diff --git a/.circleci/config.yml b/.circleci/config.yml index a1670216ece..b0307f51c3c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -197,29 +197,6 @@ jobs: command: | npm run lint:gql - test-app: - <<: *defaults - steps: - - checkout - - restore_cache: - name: Restoring Meteor cache - key: reaction-v2-meteor - - run: - name: Link Restored Meteor - command: sudo ln -s ~/.meteor/meteor /usr/local/bin/meteor - - restore_cache: - # Fall back to less specific caches - keys: - - reaction-v2-node-modules-{{ checksum "package.json" }}-{{ checksum "package-lock.json" }} - - reaction-v2-node-modules-{{ .Branch }} - - reaction-v2-node-modules-master - - run: - name: Load App Plugins - command: node --experimental-modules ./.reaction/scripts/build.mjs - - run: - name: Run Meteor Integration Tests - command: .circleci/tests.sh - test-unit: <<: *defaults steps: @@ -298,9 +275,6 @@ workflows: jobs: - build - dockerfile-lint - - test-app: - requires: - - build - test-unit: requires: - build @@ -322,7 +296,6 @@ workflows: - deploy-docs: requires: - test-unit - - test-app - docker-build filters: branches: diff --git a/.circleci/tests.sh b/.circleci/tests.sh deleted file mode 100755 index 1edd84ecb0a..00000000000 --- a/.circleci/tests.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash - -# Allow reaction tests to potentially fail the first time because -# tests sometimes fail due to a SIGKILL during Meteor package npm install. -# Since the install doesn't need to happen on second run, the error is -# often avoided and the false positive doesn't fail the CircleCI build. -# -# This will update npm deps which takes a while - -set +e - -npm run test:app - -if [ $? -eq 0 ]; then - echo "Reaction tests have passed!" -else - echo "Reaction tests failed. Trying one more time..." - set -e - npm run test:app -fi diff --git a/.meteor/packages b/.meteor/packages index bfc78964d57..c143863c9bc 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -58,11 +58,4 @@ percolate:migrations gadicc:blaze-react-component orionsoft:graphql-compiler -# Testing packages -dburles:factory -meteortesting:mocha -practicalmeteor:chai -practicalmeteor:sinon -johanbrook:publication-collector - # Custom Packages diff --git a/.meteor/versions b/.meteor/versions index 80791f31ddc..8471f35cae1 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -28,8 +28,6 @@ caching-compiler@1.2.1 caching-html-compiler@1.1.3 callback-hook@1.1.0 check@1.3.1 -coffeescript@1.0.17 -dburles:factory@1.1.0 ddp@1.4.0 ddp-client@2.3.3 ddp-common@1.4.0 @@ -58,22 +56,17 @@ htmljs@1.0.11 http@1.4.1 id-map@1.1.0 inter-process-messaging@0.1.0 -johanbrook:publication-collector@1.1.0 jquery@1.11.11 juliancwirko:postcss@1.3.0 launch-screen@1.1.1 less@2.8.0 livedata@1.0.18 -lmieulet:meteor-coverage@1.1.4 localstorage@1.2.0 logging@1.1.20 mdg:validated-method@1.2.0 meteor@1.9.2 meteor-base@1.4.0 -meteorhacks:picker@1.0.3 meteorhacks:subs-manager@1.6.4 -meteortesting:browser-tests@0.2.0 -meteortesting:mocha@0.6.0 minifier-css@1.4.1 minifier-js@2.4.0 minimongo@1.4.5 @@ -98,9 +91,6 @@ ongoworks:security@2.1.0 ordered-dict@1.1.0 orionsoft:graphql-compiler@0.0.4 percolate:migrations@0.9.8 -practicalmeteor:chai@2.1.0_1 -practicalmeteor:mocha-core@1.0.1 -practicalmeteor:sinon@1.14.1_2 promise@0.11.2 raix:eventemitter@0.1.3 random@1.1.0 diff --git a/.reaction/graphql-linter/rules/arguments_have_descriptions.js b/.reaction/graphql-linter/rules/arguments_have_descriptions.js new file mode 100644 index 00000000000..16685466504 --- /dev/null +++ b/.reaction/graphql-linter/rules/arguments_have_descriptions.js @@ -0,0 +1,20 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.ArgumentsHaveDescriptions = ArgumentsHaveDescriptions; + +var _validation_error = require("graphql-schema-linter/lib/validation_error"); + +function ArgumentsHaveDescriptions(context) { + return { + FieldDefinition: function FieldDefinition(node) { + for (const arg of node.arguments || []) { + if (!arg.description || typeof arg.description.value !== "string" || arg.description.value.length === 0) { + context.reportError(new _validation_error.ValidationError("arguments-have-descriptions", "Every argument must have a description", [arg])); + } + } + } + }; +} diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e6c75b813d..bd854797aba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,50 @@ +# v2.4.0 + +Reaction v2.4.0 adds minor features and performance enhancements, fixes bugs and contains no breaking changes since v2.3.0. + +This release is being coordinated with [Reaction Platform](https://github.com/reactioncommerce/reaction-platform) and is designed to work with `v2.4.0` of [Reaction Hydra](https://github.com/reactioncommerce/reaction-hydra) and [Example Storefront](https://github.com/reactioncommerce/example-storefront). + +## Notable changes + +### Translations have been moved out of Meteor + +i18n translations have been moved outside of the Meteor context. This provides a standard route, `/locales/resources.json`, where all translations live, and allows for real-time updates to translations without needing to flush the cache. + +### Meteor app-tests have + +As part of our move away from Meteor, all Meteor app-tests have been removed. This speeds up both local testing, and testing on CI. + +## Feature + +- feat: Translations without Meteor ([#5514](http://github.com/reactioncommerce/reaction/pull/5514)) + +## Fixes + +- fix: restore Add/Remove menu item in products page ([#5564](http://github.com/reactioncommerce/reaction/pull/5564)) +- fix: use catalyst button for mediauploader ([#5563](http://github.com/reactioncommerce/reaction/pull/5563)) +- fix: restore loadTranslations fn ([#5546](http://github.com/reactioncommerce/reaction/pull/5546)) + +## Refactors + +- refactor: remove Reaction.Email ([#5559](http://github.com/reactioncommerce/reaction/pull/5559)) +- refactor: remove all code releated to inviting a shop owner ([#5553](http://github.com/reactioncommerce/reaction/pull/5553)) +- refactor: Fix proptype warning with ReactSortableTree ([#5552](http://github.com/reactioncommerce/reaction/pull/5552)) +- refactor: remove `catalog/publish/products` meteor method, use `publi#5541hProductsToCatalog` GQL Mutation instead ([#](http:#5541//github.com/reactioncommerce/reaction/pull/)) + +## Tests + +- tests: Faster Jest integration tests ([#5549](http://github.com/reactioncommerce/reaction/pull/5549)) + +## Docs + +- docs: Fix test command in README.md ([#5565](http://github.com/reactioncommerce/reaction/pull/5565)) +- docs: Add missing GraphQL argument descriptions ([#5547](http://github.com/reactioncommerce/reaction/pull/5547)) + +## Chores + +- chore: remove meteor app-tests ([#5560](http://github.com/reactioncommerce/reaction/pull/5560)) +- chore: fix various prop type validation errors ([#5550](http://github.com/reactioncommerce/reaction/pull/5550)) + # v2.3.0 Reaction v2.3.0 adds minor features and performance enhancements, fixes bugs and contains no breaking changes since v2.2.1. diff --git a/README.md b/README.md index b0008b28844..3bb1f9a5a9f 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ We love your pull requests! Check our our [`Good First Issue`](https://github.co ### Pull Request guidelines Pull requests should pass all automated tests, style, and security checks. -Your code should pass all [acceptance tests and unit tests](https://docs.reactioncommerce.com/reaction-docs/master/testing-reaction). Run `docker-compose run --rm reaction reaction test` to run the test suites locally. If you're adding functionality to Reaction, you should add tests for the added functionality +Your code should pass all [acceptance tests and unit tests](https://docs.reactioncommerce.com/reaction-docs/master/testing-reaction). Run `docker-compose run --rm reaction npm run test` to run the test suites in containers. If you're adding functionality to Reaction, you should add tests for the added functionality. We require that all code contributed to Reaction follows [Reaction's ESLint rules](https://github.com/reactioncommerce/reaction-eslint-config). You can run `docker-compose run --rm reaction npm run lint` to run ESLint against your code locally. diff --git a/client/modules/core/main.js b/client/modules/core/main.js index a3c2af3edd5..41c9199e078 100644 --- a/client/modules/core/main.js +++ b/client/modules/core/main.js @@ -9,7 +9,6 @@ import { ReactiveDict } from "meteor/reactive-dict"; import { Roles } from "meteor/alanning:roles"; import Logger from "/client/modules/logger"; import { Countries } from "/client/collections"; -import { localeDep } from "/client/modules/i18n"; import { Packages, Shops } from "/lib/collections"; import { Router } from "/client/modules/router"; import { DomainsMixin } from "./domains"; @@ -59,13 +58,6 @@ export default { */ marketplace: { _ready: false }, - /** - * @summary Current locale - * @memberof Core/Client - * @type {ReactiveVar} - */ - Locale: new ReactiveVar({}), - /** * @summary Initialization code * @memberof Core/Client @@ -73,22 +65,8 @@ export default { * @returns {Tracker} tracker */ init() { - Tracker.autorun(() => { - // marketplaceSettings come over on the PrimaryShopPackages subscription - if (this.Subscriptions.PrimaryShopPackages.ready()) { - if (!this.marketplace._ready) { - const marketplacePkgSettings = this.getMarketplaceSettings(); - if (marketplacePkgSettings && marketplacePkgSettings.public) { - this.marketplace._ready = true; - this.marketplace = marketplacePkgSettings.public; - this.marketplace.enabled = true; - } - } - } - }); - // Listen for the primary shop subscription and set accordingly - Tracker.autorun(() => { + return Tracker.autorun(() => { let shop; if (this.Subscriptions.PrimaryShop.ready()) { // There should only ever be one "primary" shop @@ -99,84 +77,22 @@ export default { if (shop) { this._primaryShopId.set(shop._id); - // We'll initialize locale and currency for the primary shop unless - // marketplace settings exist and merchantLocale is set to true - if (this.marketplace.merchantLocale !== true) { - // initialize local client Countries collection - if (!Countries.findOne()) { - createCountryCollection(shop.locales.countries); - } + // We'll initialize locale and currency for the primary shop - const locale = this.Locale.get() || {}; - - // fix for https://github.com/reactioncommerce/reaction/issues/248 - // we need to keep an eye for rates changes - if (typeof locale.locale === "object" && - typeof locale.currency === "object" && - typeof locale.locale.currency === "string") { - const localeCurrency = locale.locale.currency.split(",")[0]; - if (typeof shop.currencies[localeCurrency] === "object") { - if (typeof shop.currencies[localeCurrency].rate === "number") { - locale.currency.rate = shop.currencies[localeCurrency].rate; - localeDep.changed(); - } - } - } - // we are looking for a shopCurrency changes here - if (typeof locale.shopCurrency === "object") { - locale.shopCurrency = shop.currencies[shop.currency]; - localeDep.changed(); - } + // initialize local client Countries collection + if (!Countries.findOne()) { + createCountryCollection(shop.locales.countries); } - } - } - }); - // Listen for active shop change - return Tracker.autorun(() => { // eslint-disable-line consistent-return - if (this.Subscriptions.MerchantShops.ready()) { - // if we don't have an active shopId, try to retrieve it from the userPreferences object - // and set the shop from the storedShopId - if (!this.shopId) { - const shop = this.getCurrentShop(); - - if (shop) { - // Only set shopId if it hasn't been set yet - if (!this.shopId) { - this.shopId = shop._id; - this.shopName = shop.name; - } + // if we don't have an active shopId, try to retrieve it from the userPreferences object + // and set the shop from the storedShopId + if (!this.shopId) { + const currentShop = this.getCurrentShop(); - // We only use the active shop to setup locale if marketplace settings - // are enabled and merchantLocale is set to true - if (this.marketplace.merchantLocale === true) { - // initialize local client Countries collection - if (!Countries.findOne()) { - createCountryCollection(shop.locales.countries); - } - - const locale = this.Locale.get() || {}; - - // fix for https://github.com/reactioncommerce/reaction/issues/248 - // we need to keep an eye for rates changes - if (typeof locale.locale === "object" && - typeof locale.currency === "object" && - typeof locale.locale.currency === "string") { - const localeCurrency = locale.locale.currency.split(",")[0]; - if (typeof shop.currencies[localeCurrency] === "object") { - if (typeof shop.currencies[localeCurrency].rate === "number") { - locale.currency.rate = shop.currencies[localeCurrency].rate; - localeDep.changed(); - } - } - } - // we are looking for a shopCurrency changes here - if (typeof locale.shopCurrency === "object") { - locale.shopCurrency = shop.currencies[shop.currency]; - localeDep.changed(); - } + if (currentShop) { + this.shopId = currentShop._id; + this.shopName = currentShop.name; } - return this; } } } @@ -246,23 +162,6 @@ export default { return true; } - // global roles check - // TODO: Review this commented out code - /* - - const sellerShopPermissions = Roles.getGroupsForUser(userId, "admin"); - // we're looking for seller permissions. - if (sellerShopPermissions) { - // loop through shops roles and check permissions - for (const key in sellerShopPermissions) { - if (key) { - const shop = sellerShopPermissions[key]; - if (Roles.userIsInRole(userId, permissions, shop)) { - return true; - } - } - } - }*/ // no specific permissions found returning false return false; } @@ -473,20 +372,6 @@ export default { return settings.settings || {}; }, - /** - * @name getPrimaryShopCurrency - * @method - * @memberof Core/Client - * @returns {String} primary shop currency abbreviation - */ - getPrimaryShopCurrency() { - const shop = Shops.findOne({ - _id: this.getPrimaryShopId() - }); - - return (shop && shop.currency) || "USD"; - }, - /** * @name getCurrentShop * @summary Get the proper current shop based on various checks. This mirrors the logic in diff --git a/client/modules/core/subscriptions.js b/client/modules/core/subscriptions.js index a53d724fb4b..f2c5473e827 100644 --- a/client/modules/core/subscriptions.js +++ b/client/modules/core/subscriptions.js @@ -23,9 +23,6 @@ Tracker.autorun(() => { // Primary shop subscription Subscriptions.PrimaryShop = Subscriptions.Manager.subscribe("PrimaryShop"); -// Additional shop subscriptions -Subscriptions.MerchantShops = Subscriptions.Manager.subscribe("MerchantShops"); - // This Packages subscription is used for the Active shop's packages Subscriptions.Packages = Subscriptions.Manager.subscribe("Packages"); diff --git a/client/modules/i18n/currency.js b/client/modules/i18n/currency.js index 62d36bf92b1..67037078d41 100644 --- a/client/modules/i18n/currency.js +++ b/client/modules/i18n/currency.js @@ -1,20 +1,16 @@ import { formatMoney } from "accounting-js"; import { Reaction } from "/client/api"; import { Shops, Accounts } from "/lib/collections"; -import { currencyDep } from "./main"; +import CurrencyDefinitions from "/imports/utils/CurrencyDefinitions"; /** * @name findCurrency - * @summary Private function for returning user currency - * @private - * @param {Object} defaultCurrency The default currency - * @param {Boolean} useDefaultShopCurrency - flag for displaying shop's currency in Admin view of PDP + * @summary Return user currency * @returns {Object} user currency or shop currency if none is found */ -export function findCurrency(defaultCurrency, useDefaultShopCurrency) { - const shop = Shops.findOne(Reaction.getPrimaryShopId(), { +export function findCurrency() { + const shop = Shops.findOne({ _id: Reaction.getPrimaryShopId() }, { fields: { - currencies: 1, currency: 1 } }); @@ -23,21 +19,14 @@ export function findCurrency(defaultCurrency, useDefaultShopCurrency) { const user = Accounts.findOne({ _id: Reaction.getUserId() }); - const profileCurrency = user && user.profile && user.profile.currency; - if (typeof shop === "object" && shop.currencies && profileCurrency) { - let userCurrency = {}; - if (shop.currencies[profileCurrency]) { - if (useDefaultShopCurrency) { - userCurrency = shop.currencies[shop.currency]; - userCurrency.exchangeRate = 1; - } else { - userCurrency = shop.currencies[profileCurrency]; - userCurrency.exchangeRate = shop.currencies[profileCurrency].rate; - } - } - return userCurrency; - } - return shop.currencies[shopCurrency]; + const profileCurrencyCode = user && user.profile && user.profile.currency; + let currency = CurrencyDefinitions[profileCurrencyCode || shopCurrency]; + if (!currency) throw new Error(`Currency definition not found for ${profileCurrencyCode || shopCurrency}`); + + // Clone before mutating + currency = Object.assign({}, currency, { exchangeRate: currency.rate || 1 }); + + return currency; } /** @@ -50,20 +39,11 @@ export function findCurrency(defaultCurrency, useDefaultShopCurrency) { * @returns {String} returns locale formatted and exchange rate converted values */ export function formatPriceString(formatPrice) { - currencyDep.depend(); - const locale = Reaction.Locale.get(); - - if (typeof locale !== "object" || typeof locale.currency !== "object") { - // locale not yet loaded, so we don"t need to return anything. - return false; - } - if (typeof formatPrice !== "string" && typeof formatPrice !== "number") { return false; } - // get user currency instead of locale currency - const userCurrency = findCurrency(locale.currency, true); + const currency = findCurrency(); const currentPrice = formatPrice.toString(); const prices = currentPrice.indexOf(" - ") >= 0 ? @@ -73,7 +53,7 @@ export function formatPriceString(formatPrice) { const price1 = prices[0].replace(/,/g, ""); const price2 = prices[1].replace(/,/g, ""); - return getDisplayPrice(Number(price1), Number(price2), userCurrency); + return getDisplayPrice(Number(price1), Number(price2), currency); } /** diff --git a/client/modules/i18n/helpers.js b/client/modules/i18n/helpers.js index 2d0f920467a..0981f08a620 100644 --- a/client/modules/i18n/helpers.js +++ b/client/modules/i18n/helpers.js @@ -1,9 +1,7 @@ import { Template } from "meteor/templating"; -import { check, Match } from "meteor/check"; -import { Reaction, Logger, i18next } from "/client/api"; -import { Shops, Accounts } from "/lib/collections"; -import { localeDep, i18nextDep } from "./main"; -import { formatPriceString } from "./currency"; +import { check } from "meteor/check"; +import { findCurrency, Logger, i18next } from "/client/api"; +import { i18nextDep } from "./main"; /** * @name i18n @@ -38,31 +36,7 @@ Template.registerHelper("i18n", (i18nKey, i18nMessage) => { * @returns {String} return current locale currency symbol */ Template.registerHelper("currencySymbol", () => { - const locale = Reaction.Locale.get(); - const user = Accounts.findOne({ - _id: Reaction.getUserId() - }); - const profileCurrency = user.profile && user.profile.currency; - if (profileCurrency) { - const shop = Shops.findOne(); - if (Match.test(shop, Object) && shop.currencies) { - return shop.currencies[profileCurrency].symbol; - } - } - return locale.currency.symbol; -}); + const currency = findCurrency(null, true); -/** - * @name formatPrice - * @memberof BlazeTemplateHelpers - * @method - * @summary Return shop /locale specific formatted price. Also accepts a range formatted with " - " - * @example {{formatPrice displayPrice}} - * @param {String} currentPrice - currentPrice or "xx.xx - xx.xx" formatted String - * @param {Boolean} useDefaultShopCurrency - flag for displaying shop's currency in Admin view of PDP - * @returns {String} returns locale formatted and exchange rate converted values - */ -Template.registerHelper("formatPrice", (formatPrice, useDefaultShopCurrency) => { - localeDep.depend(); - return formatPriceString(formatPrice, useDefaultShopCurrency); + return (currency && currency.symbol) || "$"; }); diff --git a/client/modules/i18n/index.js b/client/modules/i18n/index.js index 95101e053c2..10a52c29cce 100644 --- a/client/modules/i18n/index.js +++ b/client/modules/i18n/index.js @@ -1,10 +1,7 @@ -import i18next, { getBrowserLanguage, i18nextDep, localeDep, currencyDep } from "./main"; +import i18next, { i18nextDep } from "./main"; export * from "./currency"; export { i18next, - getBrowserLanguage, - i18nextDep, - localeDep, - currencyDep + i18nextDep }; diff --git a/client/modules/i18n/main.js b/client/modules/i18n/main.js index 18700a584cb..d2905f77019 100644 --- a/client/modules/i18n/main.js +++ b/client/modules/i18n/main.js @@ -1,9 +1,7 @@ import i18next from "i18next"; import { values } from "lodash"; import SimpleSchema from "simpl-schema"; -import { Meteor } from "meteor/meteor"; import { Tracker } from "meteor/tracker"; -import { Logger, Reaction } from "/client/api"; /** * @file **Internationalization** @@ -11,25 +9,6 @@ import { Logger, Reaction } from "/client/api"; * @namespace i18n */ -/** - * @name getBrowserLanguage - * @method - * @memberof i18n - * @summary Detects device default language - * @returns {String} language code - */ -export function getBrowserLanguage() { - if (typeof navigator.languages !== "undefined") { - if (navigator.languages[0].indexOf("-") >= 0) { - return navigator.languages[0].split("-")[0]; - } else if (navigator.languages[0].indexOf("_") >= 0) { - return navigator.languages[0].split("_")[0]; - } - return navigator.languages[0]; - } - return navigator.language || navigator.browserLanguage; -} - /** * @name getLabelsFor * @method @@ -80,41 +59,5 @@ export function getValidationErrorMessages() { // set language and autorun on change of language // initialize i18n and load data resources for the current language and fallback "EN" export const i18nextDep = new Tracker.Dependency(); -export const localeDep = new Tracker.Dependency(); -export const currencyDep = new Tracker.Dependency(); - -Meteor.startup(() => { - Tracker.autorun((trackerInstance) => { - let merchantShopsReadyOrSkipped = false; - - // Choose shopSubscription based on marketplace settings - if (Reaction.marketplaceEnabled && Reaction.merchantLanguage) { - merchantShopsReadyOrSkipped = Reaction.Subscriptions.MerchantShops.ready(); - } else { - merchantShopsReadyOrSkipped = true; - } - - // setting local and active packageNamespaces - // packageNamespaces are used to determine i18n namespace - if (Reaction.Subscriptions.PrimaryShop.ready() && merchantShopsReadyOrSkipped) { - // use i18n detected language to getLocale info and set it client side - Meteor.call("shop/getLocale", (error, result) => { - if (error || !result) { - Logger.error(error, "Unable to get shop locale"); - return; - } - - const locale = result; - locale.language = getBrowserLanguage(); - - Reaction.Locale.set(locale); - localeDep.changed(); - - // Stop the tracker - trackerInstance.stop(); - }); - } - }); -}); export default i18next; diff --git a/client/modules/i18n/startup.js b/client/modules/i18n/startup.js index 991a515d3db..23d5d00b473 100644 --- a/client/modules/i18n/startup.js +++ b/client/modules/i18n/startup.js @@ -1,210 +1,118 @@ import i18nextBrowserLanguageDetector from "i18next-browser-languagedetector"; -import i18nextLocalStorageCache from "i18next-localstorage-cache"; import i18nextSprintfPostProcessor from "i18next-sprintf-postprocessor"; +import i18nextFetch from "i18next-fetch-backend"; +import i18nextMultiLoadBackendAdapter from "i18next-multiload-backend-adapter"; import i18nextJquery from "jquery-i18next"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; import { $ } from "meteor/jquery"; import { Tracker } from "meteor/tracker"; -import { ReactiveVar } from "meteor/reactive-var"; -import SimpleSchema from "simpl-schema"; import { Reaction } from "/client/api"; -import { Shops, Translations } from "/lib/collections"; +import Logger from "/client/modules/logger"; +import { Shops } from "/lib/collections"; import Schemas from "@reactioncommerce/schemas"; -import i18next, { getLabelsFor, getValidationErrorMessages, i18nextDep, currencyDep } from "./main"; -import { mergeDeep } from "/lib/api"; +import i18next, { getLabelsFor, getValidationErrorMessages, i18nextDep } from "./main"; + +const configuredI18next = i18next + // https://github.com/i18next/i18next-browser-languageDetector + // Sets initial language to load based on `lng` query string + // with various fallbacks. + .use(i18nextBrowserLanguageDetector) + // https://github.com/i18next/i18next-sprintf-postProcessor + // key: 'Hello %(users[0].name)s, %(users[1].name)s and %(users[2].name)s', + // i18next.t('key2', { postProcess: 'sprintf', sprintf: { users: [{name: 'Dolly'}, {name: 'Molly'}, {name: 'Polly'}] } }); + // --> 'Hello Dolly, Molly and Polly' + .use(i18nextSprintfPostProcessor) + // https://github.com/perrin4869/i18next-fetch-backend + // This uses `fetch` to load resources from the backend based on `backend` + // config object below. + .use(i18nextMultiLoadBackendAdapter); /** - * Every schema that feature an expireMonth and an expireYear - * field will be validated against the dateBeforeNow rule. + * @summary Async function to initialize i18next after we have a fallback + * (shop) language. + * @param {String} fallbackLng Language code to use if i18nextBrowserLanguageDetector fails + * @return {undefined} */ -// eslint-disable-next-line consistent-return -SimpleSchema.addValidator(function () { - let expireMonth; - let expireYear; - let sibling; - if (this.key === "expireMonth") { - sibling = "expireYear"; - expireMonth = this.value; - expireYear = this.field(sibling).value; - } - if (this.key === "expireYear") { - sibling = "expireMonth"; - expireMonth = this.field(sibling).value; - expireYear = this.value; - } - if (expireYear && expireMonth) { - const now = new Date(); - const expire = new Date(expireYear, expireMonth); - if (now > expire) { - return "dateBeforeNow"; - } - - // Remove error message from the other field as well. - const validationErrors = this.validationContext && this.validationContext._validationErrors; - const deps = this.validationContext && this.validationContext._deps; - if (validationErrors) { - const index = validationErrors.findIndex((error) => error.name === sibling && error.type === "dateBeforeNow"); - if (index !== -1) { - validationErrors.splice(index, 1); - if (deps) deps[sibling].changed(); - } - } +async function initializeI18n(fallbackLng) { + // Reaction does not have a predefined list of namespaces. Any API plugin can + // add any namespaces. So we must first get the list of namespaces from the API. + const namespaceResponse = await fetch("/locales/namespaces.json"); + const allTranslationNamespaces = await namespaceResponse.json(); + + try { + await configuredI18next.init({ + backend: { + backend: i18nextFetch, + backendOption: { + allowMultiLoading: true, + loadPath: "/locales/resources.json?lng={{lng}}&ns={{ns}}" + } + }, + debug: false, + detection: { + // We primarily set language according to `navigator.language`, + // which is supported in all modern browsers and can be changed + // in the browser settings. This is the same list that browsers + // send in the `Accept-Language` header. + // + // For ease of testing translations, we also support `lng` + // query string to override the browser setting. + order: ["querystring", "navigator"] + }, + ns: allTranslationNamespaces, + defaultNS: "core", // reaction "core" is the default namespace + fallbackNS: allTranslationNamespaces, + fallbackLng + }); + } catch (error) { + // We want to log when this happens, but we want to also continue + // as long as `i18next.language` has been successfully detected + // so that other language-dependent things work properly. + Logger.error(error); + if (!i18next.language) return; } - return null; -}); + // i18next.language will now be set to the language detected + // by i18nextBrowserLanguageDetector, or to fallbackLng. -/** - * Error messages that are used for all SimpleSchema instances - * ATM, validation errors are not translated in Reaction in general. - */ -SimpleSchema.setDefaultMessages({ - messages: { - en: { - dateBeforeNow: "Dates in the past are not allowed." + // Loop through registered Schemas to change labels and messages + for (const schemaName in Schemas) { + if ({}.hasOwnProperty.call(Schemas, schemaName)) { + const schemaInstance = Schemas[schemaName]; + schemaInstance.labels(getLabelsFor(schemaInstance, schemaName)); + schemaInstance.messageBox.messages({ + [i18next.language]: getValidationErrorMessages() + }); + schemaInstance.messageBox.setLanguage(i18next.language); } } -}); -// setup options for i18nextBrowserLanguageDetector -// note: this isn't fully operational yet -// language is set by user currently -// progress toward detecting language -// should focus around i18nextBrowserLanguageDetector -// -const options = { - // order and from where user language should be detected - order: ["querystring", "cookie", "localStorage", "navigator", "htmlTag"], - // keys or params to lookup language from - lookupQuerystring: "lng", - lookupCookie: "i18next", - lookupLocalStorage: "i18nextLng", - - // cache user language on - caches: ["localStorage", "cookie"], - // optional htmlTag with lang attribute, the default is: - htmlTag: document.documentElement -}; + // apply language direction to html + if (i18next.dir() === "rtl") { + $("html").addClass("rtl"); + } else { + $("html").removeClass("rtl"); + } -const userProfileLanguage = new ReactiveVar(null); + // Causes all Blaze templates and the React TranslationProvider + // to update to show new translations. + i18nextDep.changed(); +} Meteor.startup(() => { - // We need to ensure fine-grained reactivity on only the profile.lang because - // user.profile changed frequently and causes excessive reruns - Tracker.autorun(() => { - const userId = Reaction.getUserId(); - const user = userId && Meteor.users.findOne(userId, { fields: { profile: 1 } }); - userProfileLanguage.set((user && user.profile && user.profile.lang) || null); - }); - // use tracker autorun to detect language changes - // this only runs on initial page loaded - // and when user.profile.lang updates - Tracker.autorun(() => { - if (!Reaction.Subscriptions.PrimaryShop.ready() || - !Reaction.Subscriptions.MerchantShops.ready()) return; + // Autorun only long enough to be sure we have a shop ID + Tracker.autorun((computation) => { + const shopId = Reaction.getPrimaryShopId(); + if (!shopId) return; // will reactively rerun after there is a shop ID - // Depend on user.profile.language reactively - const userLanguage = userProfileLanguage.get(); + computation.stop(); - // Choose shop to get language from - let shopId; - if (Reaction.marketplaceEnabled && Reaction.merchantLanguage) { - shopId = Reaction.getShopId(); - } else { - shopId = Reaction.getPrimaryShopId(); - } - // By specifying "fields", we limit reruns to only when that field changes - const shop = Shops.findOne({ _id: shopId }, { fields: { language: 1 }, reactive: false }); + const shop = Shops.findOne({ _id: shopId }); const shopLanguage = (shop && shop.language) || null; - // Use fallbacks to determine the final language - const language = userLanguage || shopLanguage || "en"; - - // - // subscribe to user + shop Translations - // - // eslint-disable-next-line consistent-return - return Meteor.subscribe("Translations", language, () => { - // - // reduce and merge translations - // into i18next resource format - // - const packageNamespaces = []; - let resources = {}; - Translations.find({}).forEach((translation) => { - resources = mergeDeep(resources, { - [translation.i18n]: translation.translation - }); - packageNamespaces.push(translation.ns); - }); - - // - // initialize i18next - // - i18next - .use(i18nextBrowserLanguageDetector) - .use(i18nextLocalStorageCache) - .use(i18nextSprintfPostProcessor) - .init({ - detection: options, - debug: false, - ns: packageNamespaces, // translation namespace for every package - defaultNS: "core", // reaction "core" is the default namespace - fallbackNS: packageNamespaces, - lng: language, - fallbackLng: shopLanguage, - resources - }, () => { - // Loop through registered Schemas to change labels and messages - for (const schemaName in Schemas) { - if ({}.hasOwnProperty.call(Schemas, schemaName)) { - const schemaInstance = Schemas[schemaName]; - schemaInstance.labels(getLabelsFor(schemaInstance, schemaName)); - schemaInstance.messageBox.messages({ - [language]: getValidationErrorMessages() - }); - schemaInstance.messageBox.setLanguage(language); - } - } - - i18nextDep.changed(); - - // global first time init event finds and replaces - // data-i18n attributes in html/template source. - $("[data-i18n]").localize(); - - // apply language direction to html - if (i18next.dir(language) === "rtl") { - return $("html").addClass("rtl"); - } - return $("html").removeClass("rtl"); - }); - - return null; - }); - }); - - // Detect user currency changes. - // These two autoruns work together to ensure currencyDep is only considered - // to be changed when it should be. - // XXX currencyDep is not used by the main app. Maybe can get rid of this - // if no add-on packages use it? - const userCurrency = new ReactiveVar(); - Tracker.autorun(() => { - // We are using the reactive var only to be sure that currencyDep.changed() - // is called only when the value is actually changed from the previous value. - const currency = userCurrency.get(); - if (currency) currencyDep.changed(); - }); - Tracker.autorun(() => { - const user = Meteor.user(); - if (Reaction.Subscriptions.PrimaryShop.ready() && - Reaction.Subscriptions.MerchantShops.ready() && - user) { - userCurrency.set((user.profile && user.profile.currency) || undefined); - } + initializeI18n(shopLanguage || "en"); }); // @@ -215,7 +123,7 @@ Meteor.startup(() => { i18nName: "i18n", // --> appends $.i18n = i18next handleName: "localize", // --> appends $(selector).localize(opts); selectorAttr: "data-i18n", // selector for translating elements - targetAttr: "data-i18n-target", // element attribute to grab target element to translate (if diffrent then itself) + targetAttr: "data-i18n-target", // element attribute to grab target element to translate (if different then itself) parseDefaultValueFromContent: true // parses default values from content ele.val or ele.text }); diff --git a/imports/client/ui/components/Button/Button.js b/imports/client/ui/components/Button/Button.js index c6ec71bfb76..e4b7670116a 100644 --- a/imports/client/ui/components/Button/Button.js +++ b/imports/client/ui/components/Button/Button.js @@ -6,7 +6,7 @@ import MuiButton from "@material-ui/core/Button"; const styles = (theme) => ({ buttonProgress: { - marginLeft: theme.spacing.unit + marginLeft: theme.spacing(1) }, containedPrimary: { "color": theme.palette.primary.contrastText, @@ -85,7 +85,6 @@ Button.defaultProps = { disableRipple: false, fullWidth: false, href: null, - mini: false, size: "medium", variant: "text" }; diff --git a/imports/client/ui/components/DetailDrawerButton/DetailDrawerButton.js b/imports/client/ui/components/DetailDrawerButton/DetailDrawerButton.js index 9d0951b1420..d38dab11f13 100644 --- a/imports/client/ui/components/DetailDrawerButton/DetailDrawerButton.js +++ b/imports/client/ui/components/DetailDrawerButton/DetailDrawerButton.js @@ -26,7 +26,7 @@ function DetailDrawerButton(props) { DetailDrawerButton.propTypes = { children: PropTypes.node, - component: PropTypes.func + component: PropTypes.object }; DetailDrawerButton.defaultProps = { diff --git a/imports/client/ui/components/Sidebar/Sidebar.js b/imports/client/ui/components/Sidebar/Sidebar.js index 173ffa42c45..056fb2ea745 100644 --- a/imports/client/ui/components/Sidebar/Sidebar.js +++ b/imports/client/ui/components/Sidebar/Sidebar.js @@ -195,7 +195,7 @@ function Sidebar(props) { disableTypography className={classes.listItemText} > - + diff --git a/imports/collections/schemas/index.js b/imports/collections/schemas/index.js index 3bdc33e46d3..58d1b3e3297 100644 --- a/imports/collections/schemas/index.js +++ b/imports/collections/schemas/index.js @@ -36,5 +36,4 @@ export * from "./groups"; export * from "./social"; export * from "./tags"; export * from "./templates"; -export * from "./translations"; export * from "./workflow"; diff --git a/imports/collections/schemas/translations.js b/imports/collections/schemas/translations.js deleted file mode 100644 index 4595adf464b..00000000000 --- a/imports/collections/schemas/translations.js +++ /dev/null @@ -1,36 +0,0 @@ -import SimpleSchema from "simpl-schema"; -import { registerSchema } from "@reactioncommerce/schemas"; -import { shopIdAutoValue } from "./helpers"; - -/** - * @name Translation - * @memberof Schemas - * @type {SimpleSchema} - * @todo Mostly just a blackbox for now. Someday we'll validate the entire schema - * @property {String} shopId, Translation ShopId - * @property {String} language, language - * @property {String} i18n, translation - * @property {String} ns, namespace - * @property {Object} translation, blackbox - */ -export const Translation = new SimpleSchema({ - shopId: { - type: String, - autoValue: shopIdAutoValue, - label: "Translation ShopId" - }, - language: { - type: String - }, - i18n: String, - ns: { - type: String, - label: "Namespace" - }, - translation: { - type: Object, - blackbox: true - } -}); - -registerSchema("Translation", Translation); diff --git a/imports/meteor-app-tests/absoluteUrl.app-test.js b/imports/meteor-app-tests/absoluteUrl.app-test.js deleted file mode 100644 index b25f9286bf2..00000000000 --- a/imports/meteor-app-tests/absoluteUrl.app-test.js +++ /dev/null @@ -1,98 +0,0 @@ -import { DDP } from "meteor/ddp-client"; - -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; - -import { composeUrl } from "/lib/core/url-common"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; - -/** - * @returns {String} A random string - */ -function randomString() { - return Math.random().toString(36); -} - -describe("AbsoluteUrlMixin", () => { - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - }); - - afterEach(() => { - sandbox.restore(); - }); - - describe("#absoluteUrl", () => { - let path; - let connectionHost; - let rootUrl; - let meteorRootUrl; - - beforeEach(() => { - // commonly used test vars - path = randomString(); - connectionHost = `${randomString()}.reactioncommerce.com`; - rootUrl = `https://${randomString()}.reactioncommerce.com`; - - // mocking Meteor - meteorRootUrl = composeUrl.defaultOptions.rootUrl; - // this is a round-about way of mocking $ROOT_URL - composeUrl.defaultOptions.rootUrl = rootUrl; - }); - - afterEach(() => { - // restore Meteor - composeUrl.defaultOptions.rootUrl = meteorRootUrl; - }); - - describe("outside of a connection", () => { - it("defaults to $ROOT_URL", () => { - expect(Reaction.absoluteUrl()).to.include(rootUrl); - }); - }); - - describe("within a connection", () => { - beforeEach(() => { - // for reference: https://github.com/meteor/meteor/blob/ed98a07125cd072552482ca2244239f034857814/packages/ddp-server/livedata_server.js#L279-L295 - sinon.stub(DDP._CurrentMethodInvocation, "get").returns({ - connection: { httpHeaders: { host: connectionHost } } - }); - }); - - afterEach(() => { - DDP._CurrentMethodInvocation.get.restore(); - }); - - it("uses the current connection's host", () => { - expect(Reaction.absoluteUrl()).to.include(connectionHost); - }); - - it("uses $ROOT_URL's protocol/scheme", () => { - // this would he http:// if $ROOT_URL had not used https:// - expect(Reaction.absoluteUrl()).to.startsWith("https://"); - }); - }); - - it("accepts options the same way composeUrl does", () => { - const options = { - secure: true, - replaceLocalhost: true, - rootUrl: "http://127.0.0.1" - }; - - const reactionVersion = Reaction.absoluteUrl(path, options); - const meteorVersion = composeUrl(path, options); - - expect(reactionVersion).to.equal(meteorVersion); - }); - }); -}); diff --git a/imports/meteor-app-tests/accounts-validation.app-test.js b/imports/meteor-app-tests/accounts-validation.app-test.js deleted file mode 100644 index 7e10595adfb..00000000000 --- a/imports/meteor-app-tests/accounts-validation.app-test.js +++ /dev/null @@ -1,120 +0,0 @@ -/* eslint prefer-arrow-callback:0 */ -import { Meteor } from "meteor/meteor"; -import { expect } from "meteor/practicalmeteor:chai"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; - -// These are client-side only function (???) so they cannot be test from here -describe("Account Registration Validation ", function () { - before(function (done) { - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - describe("username validation ", function () { - it("should not allow a invalid username of length 3", function (done) { - const username = "tn"; - Meteor.call("accounts/validation/username", username, function (error, result) { - expect(error).to.be.undefined; - expect(result).to.be.an("object"); - return done(); - }); - }); - - it("should allow a username of valid length", function (done) { - const username = "tenten"; - Meteor.call("accounts/validation/username", username, function (error, result) { - expect(error).to.be.undefined; - expect(result).to.be.true; - return done(); - }); - }); - }); - - describe("email address validation ", function () { - it("should not allow an invalid email address", function (done) { - this.timeout(4000); - const email = "emailwebsite.com"; - Meteor.call("accounts/validation/email", email, false, function (error, result) { - expect(result).to.be.an("object"); - return done(); - }); - }); - - it("should allow a valid email address", function (done) { - const email = "email@website.com"; - Meteor.call("accounts/validation/email", email, false, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - - it("should allow a valid, supplied, optional email address", function (done) { - const email = "email@website.com"; - Meteor.call("accounts/validation/email", email, true, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - - it("should not allow an invalid, supplied, optional email address", function (done) { - const email = "emailwebsite.com"; - Meteor.call("accounts/validation/email", email, true, function (error, result) { - expect(result).to.be.an("object"); - return done(); - }); - }); - }); - - describe("password validation", function () { - it("should not allow a password under 6 characters in length", function (done) { - const password = "abc12"; - Meteor.call("accounts/validation/password", password, undefined, function (error, result) { - expect(result).to.be.an("array"); - const errMessage = result[0]; - expect(errMessage).to.be.an("object"); - expect(errMessage.reason).to.contain("at least 6 characters"); - return done(); - }); - }); - - it("should allow a password of exactly 6 characters in length", function (done) { - const password = "abc123"; - Meteor.call("accounts/validation/password", password, undefined, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - - it("should allow a password of 6 characters or more in length", function (done) { - const password = "abc1234"; - Meteor.call("accounts/validation/password", password, undefined, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - - it("should allow a password of 6 characters or more in length with only uppercase characters", function (done) { - const password = "ABC1234"; - Meteor.call("accounts/validation/password", password, undefined, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - - it("should allow a password of 6 characters or more in length uppercase and lower characters", function (done) { - const password = "abcABC1234"; - Meteor.call("accounts/validation/password", password, undefined, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - it("should allow a password of 6 characters or more in length uppercase, lower, and symbol characters", function (done) { - const password = "abcABC1234@#$%^"; - Meteor.call("accounts/validation/password", password, undefined, function (error, result) { - expect(result).to.be.true; - return done(); - }); - }); - }); -}); diff --git a/imports/meteor-app-tests/accounts.app-test.js b/imports/meteor-app-tests/accounts.app-test.js deleted file mode 100644 index 5725339a95d..00000000000 --- a/imports/meteor-app-tests/accounts.app-test.js +++ /dev/null @@ -1,65 +0,0 @@ -/* eslint-disable require-jsdoc */ -/* eslint dot-notation: 0 */ -/* eslint prefer-arrow-callback:0 */ -import { Meteor } from "meteor/meteor"; -import { Factory } from "meteor/dburles:factory"; -import { check, Match } from "meteor/check"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { Accounts, Packages, Orders, Products, Shops, Cart } from "/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import { getShop } from "/imports/plugins/core/core/server/fixtures/shops"; -import Fixtures from "/imports/plugins/core/core/server/fixtures"; - -describe("Account Meteor method ", function () { - let shopId; - let fakeUser; - const originals = {}; - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - Fixtures(); - done(); - }); - }); - - after(() => { - Packages.remove({}); - Cart.remove({}); - Accounts.remove({}); - Orders.remove({}); - Products.remove({}); - Shops.remove({}); - if (sandbox) { - sandbox.restore(); - } - }); - - beforeEach(function () { - shopId = getShop()._id; - sandbox = sinon.sandbox.create(); - - fakeUser = Factory.create("user"); - const userId = fakeUser._id; - // set the _id... some code requires that Account#_id === Account#userId - sandbox.stub(Meteor, "user", () => fakeUser); - sandbox.stub(Meteor.users, "findOne", () => fakeUser); - sandbox.stub(Reaction, "getUserId", () => userId); - sandbox.stub(Reaction, "getShopId", () => shopId); - - Object.keys(originals).forEach((method) => spyOnMethod(method, userId)); - }); - - afterEach(function () { - sandbox.restore(); - }); - - function spyOnMethod(method, id) { - return sandbox.stub(Meteor.server.method_handlers, `cart/${method}`, function (...args) { - check(args, [Match.Any]); // to prevent audit_arguments from complaining - this.userId = id; // having to do this makes me think that we should be using Meteor.userId() instead of this.userId in our Meteor methods - return originals[method].apply(this, args); - }); - } -}); diff --git a/imports/meteor-app-tests/core.app-test.js b/imports/meteor-app-tests/core.app-test.js deleted file mode 100644 index 920aa784198..00000000000 --- a/imports/meteor-app-tests/core.app-test.js +++ /dev/null @@ -1,161 +0,0 @@ -import { Meteor } from "meteor/meteor"; - -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { Shops } from "/lib/collections"; - -import Logger from "@reactioncommerce/logger"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ConnectionDataStore from "/imports/plugins/core/core/server/util/connectionDataStore"; - -/** - * @returns {String} A random string - */ -function randomString() { - return Math.random().toString(36); -} - -describe("Server/API/Core", () => { - let sandbox; - let shop; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - shop = { _id: randomString() }; - }); - - afterEach(() => { - sandbox.restore(); - shop = undefined; - }); - - describe("#getPrimaryShop", () => { - it("returns the shop tagged as primary", () => { - sandbox.stub(Shops, "findOne") - .withArgs({ shopType: "primary" }) - .returns(shop); - - expect(Reaction.getPrimaryShop()).to.be.equal(shop); - }); - }); - - describe("#getShopId", () => { - afterEach(() => { - Reaction.resetShopId(); - }); - - it("returns the cached value if applicable", () => { - sandbox.stub(ConnectionDataStore, "get") - .withArgs("shopId") - .returns(shop._id); - - expect(Reaction.getShopId()).to.equal(shop._id); - }); - - it("fetches a user's preferred shop", () => { - const userId = randomString(); - - sandbox.stub(Meteor, "userId").returns(userId); - - const fnGetUserShopId = - sandbox.stub(Reaction, "getUserShopId").withArgs(userId).returns(shop._id); - - expect(Reaction.getShopId()).to.equal(shop._id); - expect(fnGetUserShopId.called).to.be.true; - }); - - it("gets the shop by domain", () => { - const fnGetShopIdByDomain = - sandbox.stub(Reaction, "getShopIdByDomain").returns(shop._id); - - sandbox.stub(Meteor, "userId").returns(null); - - expect(Reaction.getShopId()).to.equal(shop._id); - expect(fnGetShopIdByDomain.called).to.be.true; - }); - - it("defaults to the Primary Shop", () => { - const primaryShopId = randomString(); - const fnGetPrimaryShopId = - sandbox.stub(Reaction, "getPrimaryShopId").returns(primaryShopId); - const fnLogger = - sandbox.stub(Logger, "warn").withArgs(sinon.match(/No shop matching/)); - sandbox.stub(Meteor, "userId").returns(null); - sandbox.stub(Reaction, "getShopIdByDomain").returns(null); - - expect(Reaction.getShopId()).to.equal(primaryShopId); - expect(fnGetPrimaryShopId.called).to.be.true; - expect(fnLogger.called).to.be.true; - }); - - it("caches the shopId for subsequent calls", () => { - const fnSetCachedData = sandbox.stub(ConnectionDataStore, "set").withArgs("shopId", shop._id); - - sandbox.stub(Meteor, "userId").returns(null); - sandbox.stub(Reaction, "getShopIdByDomain").returns(shop._id); - - Reaction.getShopId(); - - expect(fnSetCachedData.called).to.be.true; - }); - }); - - describe("#resetShopId", () => { - it("clears shopId from cache", () => { - const fnCacheClear = - sandbox.spy(ConnectionDataStore, "clear").withArgs("shopId"); - - Reaction.resetShopId(); - - expect(fnCacheClear.called).to.be.true; - }); - }); - - describe("#getShopIdByDomain", () => { - it("gets the shop with the domain attribute which includes the current domain", () => { - const domain = `${randomString()}.reactioncommerce.com`; - const shopsCursor = { - fetch: () => [shop] - }; - - sandbox.stub(Reaction, "getDomain").returns(domain); - - sandbox.stub(Shops, "find") - .withArgs({ domains: domain }, sinon.match.any) - .returns(shopsCursor); - - expect(Reaction.getShopIdByDomain()).to.equal(shop._id); - }); - }); - - describe("#isShopPrimary", () => { - let primaryShopId; - - beforeEach(() => { - primaryShopId = randomString(); - }); - - it("is true when the current shop is the Primary Shop", () => { - sandbox.stub(Reaction, "getShopId", () => primaryShopId); - sandbox.stub(Reaction, "getPrimaryShopId", () => primaryShopId); - - expect(Reaction.isShopPrimary()).to.be.true; - }); - - it("is false when the current shop is a Merchant Shop", () => { - const shopId = `xxx${primaryShopId}xxx`; - - sandbox.stub(Reaction, "getShopId", () => shopId); - sandbox.stub(Reaction, "getPrimaryShopId", () => primaryShopId); - - expect(Reaction.isShopPrimary()).to.be.false; - }); - }); -}); diff --git a/imports/meteor-app-tests/generate-sitemaps.app-test.js b/imports/meteor-app-tests/generate-sitemaps.app-test.js deleted file mode 100644 index 21aabe6314c..00000000000 --- a/imports/meteor-app-tests/generate-sitemaps.app-test.js +++ /dev/null @@ -1,132 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import { expect } from "meteor/practicalmeteor:chai"; -import { Factory } from "meteor/dburles:factory"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import { Products, Shops, Tags } from "/lib/collections"; -import { Sitemaps } from "/imports/plugins/included/sitemap-generator/lib/collections/sitemaps"; -import generateSitemaps from "/imports/plugins/included/sitemap-generator/server/lib/generate-sitemaps"; - -describe("generateSitemaps", () => { - let sandbox; - let primaryShop; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - beforeEach(function () { - this.timeout(30000); - sandbox = sinon.sandbox.create(); - primaryShop = Factory.create("shop"); - sandbox.stub(Reaction, "getPrimaryShopId", () => primaryShop._id); - }); - - afterEach(() => { - const { _id: shopId } = primaryShop; - Shops.remove({ _id: shopId }); - Sitemaps.remove({ shopId }); - Products.remove({ shopId }); - Tags.remove({ shopId }); - sandbox.restore(); - }); - - it("should throw not-found error if invalid shopId is passed", () => { - expect(() => generateSitemaps({ shopIds: ["FAKE_SHOP_ID"] })).to.throw(Meteor.Error, /not-found/); - }); - - it("should generate the correct number of sitemap documents", () => { - const { _id: shopId } = primaryShop; - - // Create a visible tag and product for our primary shop - Factory.create("tag", { shopId, slug: "slug1" }); - Factory.create("product", { shopId }); - - generateSitemaps({ urlsPerSitemap: 1 }); // 1 URL per sitemap - - /** - * At this point, we should have the following sitemaps: - * sitemap.xml - * sitemap-pages-1.xml - * sitemap-products-1.xml - * sitemaps-tags-1.xml - */ - - const sitemapsCount = Sitemaps.find({ shopId }).count(); - expect(sitemapsCount).to.equal(4); - }); - - it("should create sitemaps for primary shop if no shop _id is given", () => { - const { _id: shopId } = primaryShop; - - Sitemaps.remove({}); - - Factory.create("product", { shopId }); - - generateSitemaps({ urlsPerSitemap: 1 }); // 1 URL per sitemap - - const sitemap = Sitemaps.findOne({}); - expect(sitemap).to.be.an("object"); - expect(sitemap.shopId).to.equal(shopId); - }); - - it("should not include deleted/non-visible products in sitemaps", () => { - const { _id: shopId } = primaryShop; - - const tag1 = Factory.create("tag", { shopId, slug: "slug2" }); - Factory.create("product", { shopId, hashtags: [tag1._id] }); - - // Create a deleted/non-visible tag and product - const tag2 = Factory.create("tag", { shopId, isVisible: false, isDeleted: true, slug: "slug3" }); - Factory.create("product", { shopId, hashtags: [tag2._id], isVisible: false, isDeleted: true }); - - generateSitemaps({ urlsPerSitemap: 1 }); // 1 URL per sitemap - - const sitemapsCount = Sitemaps.find({ shopId }).count(); - expect(sitemapsCount).to.equal(4); - }); - - it("should create sitemaps with the correct number of URLs per each", () => { - const { _id: shopId } = primaryShop; - const shopFields = { shopId }; - - // Create 4 visible products - for (let inc = 0; inc < 4; inc += 1) { - Factory.create("product", shopFields); - } - - // Create 4 visible tags - for (let inc = 0; inc < 4; inc += 1) { - Factory.create("tag", { ...shopFields, slug: `tag${inc}` }); - } - - generateSitemaps({ urlsPerSitemap: 2 }); // 2 URLs per sitemap - - /** - * @name expectLocTagCount - * @summary Loads a sitemap's XML by handle for current primary shop, and confirms # of tags is as expected - * @private - * @param {String} handle - Sitemaps handle - * @param {Number} count - Expected count of tags in sitemap's XML - * @returns {undefined} - */ - const expectLocTagCount = (handle, count) => { - const sitemapProducts1 = Sitemaps.findOne({ shopId, handle: "sitemap-products-1.xml" }); - expect(sitemapProducts1).to.be.an("object"); - const { xml } = sitemapProducts1; - expect(xml).to.be.a("string"); - const locTagCount = (xml.match(//g) || []).length; - expect(locTagCount).to.equal(count); - }; - - // Should be 2 product sitemaps - sitemap-products-1.xml, sitemap-products-2.xml - // Each should have 2 entries (sitemap location XML tags) - expectLocTagCount("sitemap-products-1.xml", 2); - expectLocTagCount("sitemap-products-2.xml", 2); - expectLocTagCount("sitemap-tags-1.xml", 2); - expectLocTagCount("sitemap-tags-2.xml", 2); - }); -}); diff --git a/imports/meteor-app-tests/get-sitemap-xml.app-test.js b/imports/meteor-app-tests/get-sitemap-xml.app-test.js deleted file mode 100644 index acce34aae4c..00000000000 --- a/imports/meteor-app-tests/get-sitemap-xml.app-test.js +++ /dev/null @@ -1,37 +0,0 @@ -import Random from "@reactioncommerce/random"; -import { expect } from "meteor/practicalmeteor:chai"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import { Sitemaps } from "/imports/plugins/included/sitemap-generator/lib/collections/sitemaps"; -import getSitemapXML from "/imports/plugins/included/sitemap-generator/server/lib/get-sitemap-xml"; - -describe("getSitemapXML", () => { - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - it("should return an empty string if no sitemap by handle for given shop is found", () => { - Sitemaps.remove({}); - const xml = getSitemapXML("FAKE_SHOP_ID", "FAKE_HANDLE"); - expect(xml).to.equal(""); - }); - - it("should return the correct XML for a sitemap", () => { - const shopId = Random.id(); - const handle = "sitemap.xml"; - const mockSitemap = { - shopId, - handle, - _id: Random.id(), - xml: "", // Fake XML - createdAt: new Date() - }; - - Sitemaps.insert(mockSitemap); - - const xml = getSitemapXML(shopId, handle); - expect(xml).to.equal(mockSitemap.xml); - }); -}); diff --git a/imports/meteor-app-tests/members-publications.app-test.js b/imports/meteor-app-tests/members-publications.app-test.js deleted file mode 100644 index ba230daae13..00000000000 --- a/imports/meteor-app-tests/members-publications.app-test.js +++ /dev/null @@ -1,84 +0,0 @@ -/* eslint dot-notation: 0 */ -/* eslint prefer-arrow-callback:0 */ -import _ from "lodash"; -import { Meteor } from "meteor/meteor"; -import { Factory } from "meteor/dburles:factory"; -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { Roles } from "meteor/alanning:roles"; -import { getShop } from "/imports/plugins/core/core/server/fixtures/shops"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import Fixtures from "/imports/plugins/core/core/server/fixtures"; - -const shopId = getShop()._id; - -describe("Account Publications", function () { - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - Fixtures(); - done(); - }); - }); - - beforeEach(function () { - // reset - Meteor.users.remove({}); - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("ShopMembers", function () { - it("should let an admin fetch userIds", function () { - sandbox.stub(Reaction, "getShopId", () => shopId); - sandbox.stub(Roles, "userIsInRole", () => true); - const publication = Meteor.server.publish_handlers["ShopMembers"]; - const user = Factory.create("user"); - const thisContext = { - userId: user._id - }; - const cursor = publication.apply(thisContext); - // verify - const data = cursor.fetch()[0]; - expect(data._id).to.equal(user._id); - }); - - it("should not let a regular user fetch userIds", function () { - sandbox.stub(Reaction, "getShopId", () => shopId); - sandbox.stub(Roles, "userIsInRole", () => false); - const thisContext = { - userId: "notAdminUser", - ready() { return "ready"; } - }; - const publication = Meteor.server.publish_handlers["ShopMembers"]; - const cursor = publication.apply(thisContext); - expect(cursor).to.equal("ready"); - }); - - it("should not overpublish user data to admins", function () { - sandbox.stub(Reaction, "getShopId", () => shopId); - sandbox.stub(Roles, "userIsInRole", () => true); - const user = Factory.create("user"); - Factory.create("registeredUser"); - const thisContext = { - userId: user._id, - ready() { return "ready"; } - }; - const publication = Meteor.server.publish_handlers["ShopMembers"]; - const cursor = publication.apply(thisContext); - // verify - const data = cursor.fetch(); - // we expect services will be clean object - expect(data.some((_user) => - // we expect two users. First will be without services, second with - // clean services object - typeof _user.services === "object" && - _.isEqual(_user.services, {}))).to.be.true; - }); - }); -}); diff --git a/imports/meteor-app-tests/methods.app-test.js b/imports/meteor-app-tests/methods.app-test.js deleted file mode 100644 index 26450966983..00000000000 --- a/imports/meteor-app-tests/methods.app-test.js +++ /dev/null @@ -1,98 +0,0 @@ -/* eslint-disable require-jsdoc */ -/* eslint prefer-arrow-callback:0 */ -import { Meteor } from "meteor/meteor"; -import { Roles } from "meteor/alanning:roles"; -import { Factory } from "meteor/dburles:factory"; -import { Shops, Tags } from "/lib/collections"; -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; - -describe("Server/Core", function () { - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("shop/createTag", () => { - beforeEach(() => { - Tags.remove({}); - }); - - it("should throw 403 error by non admin", () => { - sandbox.stub(Roles, "userIsInRole", () => false); - sandbox.spy(Tags, "insert"); - expect(function () { - return Meteor.call("shop/createTag", "testTag", true); - }).to.throw(ReactionError, /Access Denied/); - expect(Tags.insert).not.to.have.been.called; - }); - - it("should create new tag", (done) => { - sandbox.stub(Roles, "userIsInRole", () => true); - sandbox.spy(Tags, "insert"); - expect(Meteor.call("shop/createTag", "testTag", true)).to.be.a("string"); - expect(Tags.insert).to.have.been.called; - return done(); - }); - }); - - describe("shop/updateHeaderTags", function () { - beforeEach(function () { - Shops.remove({}); - return Tags.remove({}); - }); - - it("should throw 403 error by non admin", function (done) { - sandbox.spy(Tags, "update"); - const tag = Factory.create("tag"); - function updateTagFunc() { - return Meteor.call("shop/updateHeaderTags", tag._id); - } - expect(updateTagFunc).to.throw(ReactionError, /Access Denied/); - expect(Tags.update).not.to.have.been.called; - return done(); - }); - - it("should insert new header tag with 1 argument by admin", function (done) { - sandbox.stub(Reaction, "hasPermission", function () { - return true; - }); - const tagCount = Tags.find().count(); - Factory.create("shop"); // Create shop so that ReactionCore.getShopId() doesn't fail - Meteor.call("shop/updateHeaderTags", "new tag"); - expect(Tags.find().count()).to.equal(tagCount + 1); - const tag = Tags.find().fetch()[0]; - expect(tag.name).to.equal("new tag"); - expect(tag.slug).to.equal("new-tag"); - return done(); - }); - - it("should update existing header tag with 2 arguments by admin", function (done) { - let tag; - sandbox.stub(Reaction, "hasPermission", function () { - return true; - }); - tag = Factory.create("tag"); - Meteor.call("shop/updateHeaderTags", "updated tag", tag._id); - expect(Tags.find().count()).to.equal(1); - tag = Tags.findOne(); - expect(tag.name).to.equal("updated tag"); - expect(tag.slug).to.equal("updated-tag"); - return done(); - }); - }); -}); diff --git a/imports/meteor-app-tests/packages-update.app-test.js b/imports/meteor-app-tests/packages-update.app-test.js deleted file mode 100644 index 89db1385332..00000000000 --- a/imports/meteor-app-tests/packages-update.app-test.js +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-disable require-jsdoc */ -/* eslint prefer-arrow-callback:0 */ -import { Meteor } from "meteor/meteor"; -import { Match } from "meteor/check"; -import { Factory } from "meteor/dburles:factory"; -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { Packages } from "/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; - -describe("Update Package", function () { - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("package/update", function () { - it("should throw an 'Access Denied' error for non-admins", function () { - this.timeout(20000); - const pkgUpdateSpy = sandbox.spy(Packages, "update"); - const examplePackage = Factory.create("examplePackage"); - - function updatePackage() { - return Meteor.call("package/update", examplePackage.name, "settings", {}); - } - expect(updatePackage).to.throw(ReactionError, /Access Denied/); - expect(pkgUpdateSpy).to.not.have.been.called; - }); - - it("should throw an error when supplied with an argument of the wrong type", function () { - this.timeout(20000); - const pkgUpdateSpy = sandbox.spy(Packages, "update"); - sandbox.stub(Reaction, "getShopId", () => "randomId"); - sandbox.stub(Reaction, "hasPermission", () => true); - - function updatePackage(packageName, field, value) { - return Meteor.call("package/update", packageName, field, value); - } - expect(() => updatePackage([], "someField", { foo: "bar" })).to.throw(Match.Error, /Match error: Expected string, got object/); - expect(() => updatePackage("somePackage", [], { foo: "bar" })).to.throw(Match.Error, /Match error: Expected string, got object/); - expect(() => updatePackage("somePackage", "someField", "")) - .to.throw(Match.Error, /Match error: Failed Match.OneOf, Match.Maybe or Match.Optional validation/); - expect(pkgUpdateSpy).to.not.have.been.called; - }); - - it("should be able to update any Package", function () { - this.timeout(20000); - const packageUpdateSpy = sandbox.spy(Packages, "update"); - const oldPackage = Factory.create("examplePackage"); - - sandbox.stub(Reaction, "getShopId", () => oldPackage.shopId); - sandbox.stub(Reaction, "hasPermission", () => true); - const packageName = oldPackage.name; - const newValues = { - enabled: true, - apiUrl: "http://foo-bar.com/api/v1" - }; - Meteor.call("package/update", packageName, "settings", newValues); - expect(packageUpdateSpy).to.have.been.called; - const updatedPackage = Packages.findOne({ name: packageName }); - expect(oldPackage.settings.enabled).to.not.equal(updatedPackage.settings.enabled); - expect(oldPackage.settings.apiUrl).to.not.equal(updatedPackage.settings.apiUrl); - }); - }); -}); diff --git a/imports/meteor-app-tests/shops.app-test.js b/imports/meteor-app-tests/shops.app-test.js deleted file mode 100644 index a65e37b4fd8..00000000000 --- a/imports/meteor-app-tests/shops.app-test.js +++ /dev/null @@ -1,139 +0,0 @@ -/* eslint dot-notation: 0 */ -/* eslint prefer-arrow-callback:0 */ -import Logger from "@reactioncommerce/logger"; -import Random from "@reactioncommerce/random"; -import { Meteor } from "meteor/meteor"; -import { expect } from "meteor/practicalmeteor:chai"; -import { Factory } from "meteor/dburles:factory"; -import { sinon, stubs, spies } from "meteor/practicalmeteor:sinon"; -import Fixtures from "/imports/plugins/core/core/server/fixtures"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; -import { Shops } from "/lib/collections"; - -describe("Shop Methods", function () { - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - Fixtures(); - done(); - }); - }); - - beforeEach(function () { - return Shops.remove({}); - }); - - after(function () { - spies.restoreAll(); - stubs.restoreAll(); - }); - - it("shop factory should create a new shop", function () { - stubs.create("hasPermissionStub", Reaction, "hasPermission"); - stubs.hasPermissionStub.returns(true); - spies.create("shopInsertSpy", Shops, "insert"); - Factory.create("shop"); - expect(spies.shopInsertSpy).to.have.been.called; - }); -}); - -describe("core shop methods", function () { - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - Fixtures(); - done(); - }); - }); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("shop/createShop", function () { - let primaryShop; - let insertShopSpy; - - beforeEach(function () { - this.timeout(20000); - Shops.remove({}); - - primaryShop = Factory.create("shop"); - sandbox.stub(Reaction, "getPrimaryShop", () => primaryShop); - - insertShopSpy = sandbox.spy(Shops, "insert"); - }); - - describe("failure conditions", function () { - it("throws a 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - - expect(() => Meteor.call("shop/createShop")) - .to.throw(ReactionError, /Access Denied/); - expect(insertShopSpy).to.not.have.been.called; - }); - }); - - describe("success conditions", function () { - let userId; - let shopId; - let name; - - beforeEach(function () { - userId = Random.id(); - shopId = Random.id(); - name = Random.id(); - - Factory.create("user", { - _id: userId, - emails: [{ - address: `${userId}@example.com`, - provides: "default", - verified: true - }] - }); - Factory.create("account", { userId, shopId }); - - sandbox.stub(Reaction, "getUserId", () => userId); - sandbox.stub(Reaction, "hasPermission", () => true); - sandbox.stub(Reaction, "getPrimaryShopId", () => shopId); - - // a logging statement exists, stub it to keep the output clean - sandbox.stub(Logger, "info") - .withArgs(sinon.match(/Created shop/), sinon.match.string); - }); - - afterEach(function () { - const newShopCount = Shops.find({ name }).count(); - expect(newShopCount).to.equal(1); - }); - - it("creates a new shop for admin for userId and a partial shopObject", function () { - this.timeout(15000); - const partialShop = { name }; - - Meteor.call("shop/createShop", userId, partialShop); - }); - - it("creates a new shop for admin for userId and a partial shopObject ignoring extraneous data", function () { - this.timeout(15000); - const extraneousData = Random.id(); - const partialShop = { name, extraneousData }; - - Meteor.call("shop/createShop", userId, partialShop); - - expect(insertShopSpy) - .to.have.been.calledWith(sinon.match({ name })); - expect(insertShopSpy) - .to.not.have.been.calledWith(sinon.match({ extraneousData })); - }); - }); - }); -}); diff --git a/imports/meteor-app-tests/tags.app-test.js b/imports/meteor-app-tests/tags.app-test.js deleted file mode 100644 index 5f08825299f..00000000000 --- a/imports/meteor-app-tests/tags.app-test.js +++ /dev/null @@ -1,86 +0,0 @@ -/* eslint-disable require-jsdoc */ -import { Random } from "meteor/random"; -import { expect } from "meteor/practicalmeteor:chai"; -import { Factory } from "meteor/dburles:factory"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { PublicationCollector } from "meteor/johanbrook:publication-collector"; -import * as Collections from "/lib/collections"; -import Fixtures from "/imports/plugins/core/core/server/fixtures"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import { createActiveShop } from "/imports/plugins/core/core/server/fixtures/shops"; - -describe("Tags Publication", () => { - let sandbox; - let collector; - let primaryShop; - let shop; - let tags; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - Fixtures(); - done(); - }); - }); - - beforeEach(() => { - sandbox = sinon.sandbox.create(); - - collector = new PublicationCollector({ userId: Random.id() }); - - primaryShop = createActiveShop(); - shop = Factory.create("shop"); - - sandbox.stub(Reaction, "getPrimaryShopId", () => primaryShop._id); - sandbox.stub(Reaction, "hasPermission", () => true); - - Collections.Tags.remove({}); - - tags = [1, 2, 3].map(() => { - const tag = createTag({ shopId: primaryShop._id }); - Collections.Tags.insert(tag); - return tag; - }); - }); - - afterEach(() => { - sandbox.restore(); - }); - - it("ensures our test is set up properly", () => { - expect(primaryShop._id).to.not.equal(shop._id); - }); - - it("returns all Tags when the current shop is the Primary Shop", (done) => { - // create a tag for a Merchant Shop - const tag = createTag({ shopId: shop._id }); - Collections.Tags.insert(tag); - - const expectedTags = [...tags, tag]; - const tagIds = expectedTags.map((expectedTag) => expectedTag._id); - tagIds.sort(); - - sandbox.stub(Reaction, "getShopId", () => primaryShop._id); - - collector.collect("Tags", tagIds, (collections) => { - const collectionTags = collections.Tags; - - expect(collectionTags.map((collectionTag) => collectionTag._id).sort()) - .to.eql(tagIds); - // eslint-disable-next-line promise/no-callback-in-promise - }).then(() => done()).catch(done); - }); - - function randomString() { - return Math.random().toString(36); - } - - function createTag(tagData = {}) { - return Object.assign({ - name: randomString(), - slug: randomString(), - isTopLevel: true - }, tagData); - } -}); diff --git a/imports/meteor-app-tests/translations.app-test.js b/imports/meteor-app-tests/translations.app-test.js deleted file mode 100644 index 1427ab2e6ce..00000000000 --- a/imports/meteor-app-tests/translations.app-test.js +++ /dev/null @@ -1,53 +0,0 @@ -/* eslint prefer-arrow-callback:0 */ -import { Meteor } from "meteor/meteor"; -import { Factory } from "meteor/dburles:factory"; -import { Roles } from "meteor/alanning:roles"; -import { Translations } from "/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import Fixtures from "/imports/plugins/core/core/server/fixtures"; - -describe("i18n methods", function () { - let sandbox; - - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - Fixtures(); - done(); - }); - }); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("i18n/flushTranslations", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Roles, "userIsInRole", () => false); - const removeTranslationSpy = sandbox.spy(Translations, "remove"); - const importTranslationSpy = sandbox.spy(Reaction.Importer, "translation"); - expect(() => Meteor.call("i18n/flushTranslations")).to.throw(ReactionError, /Access Denied/); - expect(removeTranslationSpy).to.not.have.been.called; - expect(importTranslationSpy).to.not.have.been.called; - }); - - it("should remove and load translations back by admin", function () { - this.timeout(20000); - sandbox.stub(Meteor, "userId", () => "0123456789"); - sandbox.stub(Roles, "userIsInRole", () => true); - const removeTranslationSpy = sandbox.spy(Translations, "remove"); - const importTranslationSpy = sandbox.spy(Reaction.Importer, "translation"); - Factory.create("shop"); - Meteor.call("i18n/flushTranslations"); - expect(removeTranslationSpy).to.have.been.called; - expect(importTranslationSpy).to.have.been.called; - }); - }); -}); diff --git a/imports/node-app/registerPlugins.js b/imports/node-app/registerPlugins.js index 55393df8792..693dbef3614 100644 --- a/imports/node-app/registerPlugins.js +++ b/imports/node-app/registerPlugins.js @@ -2,7 +2,9 @@ import registerAccountsPlugin from "/imports/plugins/core/accounts/server/no-met import registerAddressPlugin from "/imports/plugins/core/address/server/no-meteor/register"; import registerCartPlugin from "/imports/plugins/core/cart/server/no-meteor/register"; import registerCatalogPlugin from "/imports/plugins/core/catalog/server/no-meteor/register"; +import registerCheckoutPlugin from "/imports/plugins/core/checkout/server/no-meteor/register"; import registerCorePlugin from "/imports/plugins/core/core/server/no-meteor/register"; +import registerDashboardPlugin from "/imports/plugins/core/dashboard/server/no-meteor/register"; import registerDiscountCodesPlugin from "/imports/plugins/included/discount-codes/server/no-meteor/register"; import registerDiscountsPlugin from "/imports/plugins/core/discounts/server/no-meteor/register"; import registerEmailTemplatesPlugin from "/imports/plugins/included/email-templates/server/register"; @@ -16,6 +18,8 @@ import registerNotificationsPlugin from "/imports/plugins/included/notifications import registerOrdersPlugin from "/imports/plugins/core/orders/server/no-meteor/register"; import registerPaymentsPlugin from "/imports/plugins/core/payments/server/no-meteor/register"; import registerProductPlugin from "/imports/plugins/core/product/server/no-meteor/register"; +import registerProductVariantPlugin from "/imports/plugins/included/product-variant/server/no-meteor/register"; +import registerProductAdminPlugin from "/imports/plugins/included/product-admin/server/no-meteor/register"; import registerSettingsPlugin from "/imports/plugins/core/settings/server/register"; import registerShippingPlugin from "/imports/plugins/core/shipping/server/no-meteor/register"; import registerShippingRatesPlugin from "/imports/plugins/included/shipping-rates/server/no-meteor/register"; @@ -32,6 +36,7 @@ import registerTaxesPlugin from "/imports/plugins/core/taxes/server/no-meteor/re import registerTaxesRatesPlugin from "/imports/plugins/included/taxes-rates/server/no-meteor/register"; import registerTemplatesPlugin from "/imports/plugins/core/templates/server/no-meteor/register"; import registerTestAddressValidationPlugin from "/imports/plugins/included/address-validation-test/server/register"; +import registerUIPlugin from "/imports/plugins/core/ui/server/no-meteor/register"; /** * @summary A function in which you should call `register` function for each API plugin, @@ -50,6 +55,8 @@ export default async function registerPlugins(app) { await registerSettingsPlugin(app); // REQUIRED await registerI18nPlugin(app); // REQUIRED await registerAddressPlugin(app); // REQUIRED + await registerDashboardPlugin(app); // REQUIRED + await registerUIPlugin(app); // REQUIRED await registerSystemInfoPlugin(app); // OPTIONAL /** @@ -68,8 +75,11 @@ export default async function registerPlugins(app) { * Catalog */ await registerProductPlugin(app); // REQUIRED + await registerProductVariantPlugin(app); // REQUIRED + await registerProductAdminPlugin(app); // REQUIRED await registerCatalogPlugin(app); // REQUIRED await registerTagsPlugin(app); // REQUIRED + await registerCheckoutPlugin(app); // REQUIRED /** * Pricing diff --git a/imports/plugins/core/accounts/server/index.js b/imports/plugins/core/accounts/server/index.js index 393150fda9e..02da78e3de4 100644 --- a/imports/plugins/core/accounts/server/index.js +++ b/imports/plugins/core/accounts/server/index.js @@ -1,5 +1,4 @@ import { Meteor } from "meteor/meteor"; -import "./i18n"; import "./init.js"; import methods from "./methods"; diff --git a/imports/plugins/core/accounts/server/methods/index.js b/imports/plugins/core/accounts/server/methods/index.js index 2ce18b509a1..52e7b5226f7 100644 --- a/imports/plugins/core/accounts/server/methods/index.js +++ b/imports/plugins/core/accounts/server/methods/index.js @@ -2,7 +2,6 @@ import addUserPermissions from "./addUserPermissions"; import createFallbackLoginToken from "./createFallbackLoginToken"; import getUserId from "./getUserId"; import groupMethods from "./group"; -import inviteShopOwner from "./inviteShopOwner"; import removeEmailAddress from "./removeEmailAddress"; import removeUserPermissions from "./removeUserPermissions"; import sendResetPasswordEmail from "./sendResetPasswordEmail"; @@ -29,7 +28,6 @@ import verifyAccount from "./verifyAccount"; export default { "accounts/addUserPermissions": addUserPermissions, "accounts/createFallbackLoginToken": createFallbackLoginToken, - "accounts/inviteShopOwner": inviteShopOwner, "accounts/removeEmailAddress": removeEmailAddress, "accounts/removeUserPermissions": removeUserPermissions, "accounts/sendResetPasswordEmail": sendResetPasswordEmail, diff --git a/imports/plugins/core/accounts/server/methods/inviteShopOwner.js b/imports/plugins/core/accounts/server/methods/inviteShopOwner.js deleted file mode 100644 index 51427efdead..00000000000 --- a/imports/plugins/core/accounts/server/methods/inviteShopOwner.js +++ /dev/null @@ -1,80 +0,0 @@ -import Random from "@reactioncommerce/random"; -import { Meteor } from "meteor/meteor"; -import { Accounts as MeteorAccounts } from "meteor/accounts-base"; -import { check, Match } from "meteor/check"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import getGraphQLContextInMeteorMethod from "/imports/plugins/core/graphql/server/getGraphQLContextInMeteorMethod"; -import ReactionError from "@reactioncommerce/reaction-error"; -import getCurrentUserName from "../no-meteor/util/getCurrentUserName"; -import getDataForEmail from "../no-meteor/util/getDataForEmail"; - -/** - * @name accounts/inviteShopOwner - * @summary Invite a new user as owner of a new shop - * @memberof Accounts/Methods - * @method - * @param {Object} options - - * @param {String} options.email - email of invitee - * @param {String} options.name - name of invitee - * @param {Object} shopData - (optional) data used to create the new shop - * @returns {Boolean} returns true - */ -export default function inviteShopOwner(options, shopData) { - check(options, Object); - check(options.email, String); - check(options.name, String); - check(shopData, Match.Maybe(Object)); - const { name, email } = options; - - // given that we `export` this function, there is an expectation that it can - // be imported and used elsewhere in the code. the use of `this` in this - // method requires that the context be Meteor. Consider using a small - // function in the Meteor.method section below to pass any Meteor-defined - // data (e.g., userId) as a parameter to allow for this method to be reused. - if (!Reaction.hasPermission("admin", this.userId, Reaction.getPrimaryShopId())) { - throw new ReactionError("access-denied", "Access denied"); - } - const user = Meteor.users.findOne({ "emails.address": email }); - let userId; - if (user) { - // TODO: Verify email address - userId = user._id; - } else { - userId = MeteorAccounts.createUser({ - email, - name, - profile: { invited: true } - }); - } - - Meteor.call("shop/createShop", userId, shopData); - const primaryShop = Reaction.getPrimaryShop(); - - // Compile Email with SSR - const templateName = "accounts/inviteShopOwner"; - - const token = Random.id(); - const currentUser = Meteor.user(); - const currentUserName = getCurrentUserName(currentUser); - // uses primaryShop's data (name, address etc) in email copy sent to new merchant - const context = Promise.await(getGraphQLContextInMeteorMethod(Reaction.getUserId())); - const dataForEmail = Promise.await(getDataForEmail(context, { shop: primaryShop, currentUserName, name, token })); - - // 1) this should only be for new users, right? - // 2) this doesn't happen automatically on new user creation? - Meteor.users.update(userId, { - $set: { - "services.password.reset": { token, email, when: new Date() }, - name - } - }); - - Promise.await(context.mutations.sendEmail(context, { - data: dataForEmail, - fromShop: primaryShop, - templateName, - to: email - })); - - return true; -} diff --git a/imports/plugins/core/accounts/server/i18n/ar.json b/imports/plugins/core/accounts/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/ar.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/accounts/server/i18n/bg.json b/imports/plugins/core/accounts/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/bg.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/accounts/server/i18n/cs.json b/imports/plugins/core/accounts/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/cs.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/accounts/server/i18n/de.json b/imports/plugins/core/accounts/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/de.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/accounts/server/i18n/el.json b/imports/plugins/core/accounts/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/el.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/accounts/server/i18n/en.json b/imports/plugins/core/accounts/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/en.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/accounts/server/i18n/es.json b/imports/plugins/core/accounts/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/es.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/accounts/server/i18n/fr.json b/imports/plugins/core/accounts/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/fr.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/accounts/server/i18n/he.json b/imports/plugins/core/accounts/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/he.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/accounts/server/i18n/hr.json b/imports/plugins/core/accounts/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/hr.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/accounts/server/i18n/hu.json b/imports/plugins/core/accounts/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/hu.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/ui/server/i18n/index.js b/imports/plugins/core/accounts/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/core/ui/server/i18n/index.js rename to imports/plugins/core/accounts/server/no-meteor/i18n/index.js index 822f1bdf134..fe4f9543713 100644 --- a/imports/plugins/core/ui/server/i18n/index.js +++ b/imports/plugins/core/accounts/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; import cs from "./cs.json"; @@ -30,4 +28,31 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/accounts/server/i18n/it.json b/imports/plugins/core/accounts/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/it.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/accounts/server/i18n/my.json b/imports/plugins/core/accounts/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/my.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/accounts/server/i18n/nb.json b/imports/plugins/core/accounts/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/nb.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/accounts/server/i18n/nl.json b/imports/plugins/core/accounts/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/nl.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/accounts/server/i18n/pl.json b/imports/plugins/core/accounts/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/pl.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/accounts/server/i18n/pt.json b/imports/plugins/core/accounts/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/pt.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/accounts/server/i18n/ro.json b/imports/plugins/core/accounts/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/ro.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/accounts/server/i18n/ru.json b/imports/plugins/core/accounts/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/ru.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/accounts/server/i18n/sl.json b/imports/plugins/core/accounts/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/sl.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/accounts/server/i18n/sv.json b/imports/plugins/core/accounts/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/sv.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/accounts/server/i18n/tr.json b/imports/plugins/core/accounts/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/tr.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/accounts/server/i18n/vi.json b/imports/plugins/core/accounts/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/vi.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/accounts/server/i18n/zh.json b/imports/plugins/core/accounts/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/accounts/server/i18n/zh.json rename to imports/plugins/core/accounts/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/accounts/server/no-meteor/register.js b/imports/plugins/core/accounts/server/no-meteor/register.js index 02e09fc96e2..76c4a74ebd6 100644 --- a/imports/plugins/core/accounts/server/no-meteor/register.js +++ b/imports/plugins/core/accounts/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import mutations from "./mutations"; import queries from "./queries"; import { registerPluginHandler } from "./registration"; @@ -17,6 +18,7 @@ export default async function register(app) { label: "Accounts", name: "reaction-accounts", icon: "fa fa-users", + i18n, addRolesToGroups: [{ groups: ["guest", "customer"], roles: [ diff --git a/imports/plugins/core/accounts/server/no-meteor/schemas/account.graphql b/imports/plugins/core/accounts/server/no-meteor/schemas/account.graphql index 8d9b9d517ef..b30ea1d2f45 100644 --- a/imports/plugins/core/accounts/server/no-meteor/schemas/account.graphql +++ b/imports/plugins/core/accounts/server/no-meteor/schemas/account.graphql @@ -106,7 +106,19 @@ type Account implements Node { _id: ID! "A list of physical or mailing addresses associated with this account" - addressBook(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt): AddressConnection + addressBook( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt + ): AddressConnection "The date and time at which this account was created" createdAt: DateTime! @@ -121,7 +133,25 @@ type Account implements Node { firstName: String "A paged list of the permission groups in which this account is listed" - groups(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: GroupSortByField = createdAt): GroupConnection + groups( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, groups are sorted by when they were created, oldest first. Set this to sort by one of the other allowed fields" + sortBy: GroupSortByField = createdAt + ): GroupConnection "The last name of the person this account represents, if known" lastName: String @@ -249,38 +279,98 @@ extend type Shop { Returns a list of administrators for this shop, as a Relay-compatible connection. "Administrators" means all linked accounts that have the "admin" role for this shop. """ - administrators(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: AccountSortByField = createdAt): AccountConnection + administrators( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, accounts are sorted by when they were created, oldest first. Set this to sort by one of the other allowed fields" + sortBy: AccountSortByField = createdAt + ): AccountConnection } extend type Mutation { "Add a new address to the `addressBook` field for an account" - addAccountAddressBookEntry(input: AddAccountAddressBookEntryInput!): AddAccountAddressBookEntryPayload + addAccountAddressBookEntry( + "Mutation input" + input: AddAccountAddressBookEntryInput! + ): AddAccountAddressBookEntryPayload "Add an email address to an account" - addAccountEmailRecord(input: AddAccountEmailRecordInput!): AddAccountEmailRecordPayload + addAccountEmailRecord( + "Mutation input" + input: AddAccountEmailRecordInput! + ): AddAccountEmailRecordPayload "Remove an address from the `addressBook` field for an account" - removeAccountAddressBookEntry(input: RemoveAccountAddressBookEntryInput!): RemoveAccountAddressBookEntryPayload + removeAccountAddressBookEntry( + "Mutation input" + input: RemoveAccountAddressBookEntryInput! + ): RemoveAccountAddressBookEntryPayload "Remove an email address from an account" - removeAccountEmailRecord(input: RemoveAccountEmailRecordInput!): RemoveAccountEmailRecordPayload + removeAccountEmailRecord( + "Mutation input" + input: RemoveAccountEmailRecordInput! + ): RemoveAccountEmailRecordPayload "Set the preferred currency for an account" - setAccountProfileCurrency(input: SetAccountProfileCurrencyInput!): SetAccountProfileCurrencyPayload + setAccountProfileCurrency( + "Mutation input" + input: SetAccountProfileCurrencyInput! + ): SetAccountProfileCurrencyPayload "Remove an address that exists in the `addressBook` field for an account" - updateAccountAddressBookEntry(input: UpdateAccountAddressBookEntryInput!): UpdateAccountAddressBookEntryPayload + updateAccountAddressBookEntry( + "Mutation input" + input: UpdateAccountAddressBookEntryInput! + ): UpdateAccountAddressBookEntryPayload } extend type Query { "Returns the account with the provided ID" - account(id: ID!): Account + account( + "The account ID" + id: ID! + ): Account """ Returns a list of administrators for the shop with ID `shopId`, as a Relay-compatible connection. "Administrators" means all linked accounts that have the "admin" role for this shop. """ - administrators(shopId: ID!, after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: AccountSortByField = createdAt): AccountConnection + administrators( + "Return accounts that are administrators in this shop" + shopId: ID!, + + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, accounts are sorted by when they were created, oldest first. Set this to sort by one of the other allowed fields" + sortBy: AccountSortByField = createdAt + ): AccountConnection "Returns the account for the authenticated user" viewer: Account diff --git a/imports/plugins/core/accounts/server/no-meteor/schemas/group.graphql b/imports/plugins/core/accounts/server/no-meteor/schemas/group.graphql index 3c125ba8b4a..a0156756578 100644 --- a/imports/plugins/core/accounts/server/no-meteor/schemas/group.graphql +++ b/imports/plugins/core/accounts/server/no-meteor/schemas/group.graphql @@ -199,30 +199,87 @@ type RemoveGroupPayload { extend type Shop { "Returns a list of groups for this shop, as a Relay-compatible connection." - groups(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: GroupSortByField = createdAt): GroupConnection + groups( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, groups are sorted by when they were created, oldest first. Set this to sort by one of the other allowed fields" + sortBy: GroupSortByField = createdAt + ): GroupConnection } extend type Mutation { "Add an account to a group" - addAccountToGroup(input: AddAccountToGroupInput!): AddAccountToGroupPayload + addAccountToGroup( + "Mutation input" + input: AddAccountToGroupInput! + ): AddAccountToGroupPayload "Create a new permission group" - createGroup(input: CreateGroupInput!): CreateGroupPayload + createGroup( + "Mutation input" + input: CreateGroupInput! + ): CreateGroupPayload "Remove an account from a group" - removeAccountFromGroup(input: RemoveAccountFromGroupInput!): RemoveAccountFromGroupPayload @deprecated(reason: "Use `addAccountToGroup`.") + removeAccountFromGroup( + "Mutation input" + input: RemoveAccountFromGroupInput! + ): RemoveAccountFromGroupPayload @deprecated(reason: "Use `addAccountToGroup`.") "Remove an existing permission group" - removeGroup(input: RemoveGroupInput!): RemoveGroupPayload + removeGroup( + "Mutation input" + input: RemoveGroupInput! + ): RemoveGroupPayload "Update an existing permission group" - updateGroup(input: UpdateGroupInput!): UpdateGroupPayload + updateGroup( + "Mutation input" + input: UpdateGroupInput! + ): UpdateGroupPayload } extend type Query { "Returns a single group by ID." - group(id: ID!): Group + group( + "The group ID" + id: ID! + ): Group "Returns a list of groups for the shop with ID `shopId`, as a Relay-compatible connection." - groups(shopId: ID!, after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: GroupSortByField = createdAt): GroupConnection + groups( + "Return groups for this shop" + shopId: ID!, + + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, groups are sorted by when they were created, oldest first. Set this to sort by one of the other allowed fields" + sortBy: GroupSortByField = createdAt + ): GroupConnection } diff --git a/imports/plugins/core/accounts/server/no-meteor/schemas/role.graphql b/imports/plugins/core/accounts/server/no-meteor/schemas/role.graphql index 3cc185577ca..341d8ee1814 100644 --- a/imports/plugins/core/accounts/server/no-meteor/schemas/role.graphql +++ b/imports/plugins/core/accounts/server/no-meteor/schemas/role.graphql @@ -52,10 +52,49 @@ type RoleEdge implements NodeEdge { extend type Shop { "Returns a list of roles for this shop, as a Relay-compatible connection." - roles(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: RoleSortByField = name): RoleConnection + roles( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, roles are sorted alphabetically by name. Set this to sort by one of the other allowed fields" + sortBy: RoleSortByField = name + ): RoleConnection } extend type Query { "Returns a paged list of all roles associated with a shop" - roles(shopId: ID!, after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: RoleSortByField = name): RoleConnection + roles( + "Return valid roles for this shop" + shopId: ID!, + + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, roles are sorted alphabetically by name. Set this to sort by one of the other allowed fields" + sortBy: RoleSortByField = name + ): RoleConnection } diff --git a/imports/plugins/core/address/server/index.js b/imports/plugins/core/address/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/address/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/address/server/i18n/en.json b/imports/plugins/core/address/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/address/server/i18n/en.json rename to imports/plugins/core/address/server/no-meteor/i18n/en.json diff --git a/imports/plugins/included/simple-inventory/server/i18n/index.js b/imports/plugins/core/address/server/no-meteor/i18n/index.js similarity index 56% rename from imports/plugins/included/simple-inventory/server/i18n/index.js rename to imports/plugins/core/address/server/no-meteor/i18n/index.js index bce646aa335..e6a23601392 100644 --- a/imports/plugins/included/simple-inventory/server/i18n/index.js +++ b/imports/plugins/core/address/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import en from "./en.json"; // @@ -7,4 +5,6 @@ import en from "./en.json"; // imports for easier handling by // automated translation software // -loadTranslations([en]); +export default { + translations: [...en] +}; diff --git a/imports/plugins/core/address/server/no-meteor/register.js b/imports/plugins/core/address/server/no-meteor/register.js index 4a4f20ec227..8978b10f28f 100644 --- a/imports/plugins/core/address/server/no-meteor/register.js +++ b/imports/plugins/core/address/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import queries from "./queries"; import { registerPluginHandler } from "./registration"; import resolvers from "./resolvers"; @@ -12,6 +13,7 @@ export default async function register(app) { await app.registerPlugin({ label: "Address", name: "reaction-address", + i18n, functionsByType: { registerPluginHandler: [registerPluginHandler] }, diff --git a/imports/plugins/core/address/server/no-meteor/schemas/schema.graphql b/imports/plugins/core/address/server/no-meteor/schemas/schema.graphql index 31a353c2d40..b366fa4acf4 100644 --- a/imports/plugins/core/address/server/no-meteor/schemas/schema.graphql +++ b/imports/plugins/core/address/server/no-meteor/schemas/schema.graphql @@ -4,7 +4,13 @@ extend type Query { validation service is active for the shop, this will return as if the address is valid even though no check actually occurred. """ - addressValidation(address: AddressInput!, shopId: ID!): AddressValidationResults! + addressValidation( + "Address to validate" + address: AddressInput!, + + "Shop to use for determining what validation service to use" + shopId: ID! + ): AddressValidationResults! "Get a full list of all registered address validation services" addressValidationServices: [AddressValidationService]! diff --git a/imports/plugins/core/cart/server/no-meteor/schemas/cart.graphql b/imports/plugins/core/cart/server/no-meteor/schemas/cart.graphql index 2fd3a09bb57..df01ad70a9d 100644 --- a/imports/plugins/core/cart/server/no-meteor/schemas/cart.graphql +++ b/imports/plugins/core/cart/server/no-meteor/schemas/cart.graphql @@ -29,7 +29,25 @@ type Cart implements Node { expiresAt: DateTime "The items that have been added to the cart. A cart is not created until the first item is added. Items can be removed from a cart, and a cart is not deleted if all items are removed from it. Because all items may have been removed, this may be an empty array." - items(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = desc, sortBy: CartItemsSortByField = addedAt): CartItemConnection + items( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = desc, + + "By default, items are sorted by when they were added to the cart, newest first. Set this to sort by one of the other allowed fields" + sortBy: CartItemsSortByField = addedAt + ): CartItemConnection """ If you integrate with third-party systems that require you to send the same ID for order @@ -158,7 +176,25 @@ type CartItem implements Node { productSlug: String "The list of tags that have been applied to this product" - productTags(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: TagSortByField = _id): TagConnection + productTags( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, tags are sorted by ID. Set this to sort by one of the other allowed fields" + sortBy: TagSortByField = _id + ): TagConnection "The type of product, used to display cart items differently" productType: String @@ -206,13 +242,28 @@ enum CartReconciliationMode { extend type Query { "Finds a cart by the cart ID and anonymous cart token." - anonymousCartByCartId(cartId: ID!, token: String!): Cart + anonymousCartByCartId( + "The cart ID. Must be an anonymous cart (that is, one with no linked account)." + cartId: ID!, + + """ + A valid anonymous cart access token for this cart. This is returned when you create + an anonymous cart and should be stored securely in storefront client storage. + """ + token: String! + ): Cart # Access control should ensure that only authenticated users can find their own # cart. Additionally, administrative roles can find carts. # Shop ID is necessary if shops have separate carts but share the same account pool "Find a cart for a given account ID." - accountCartByAccountId(accountId: ID!, shopId: ID!): Cart + accountCartByAccountId( + "Account that owns the cart" + accountId: ID!, + + "Shop that owns the cart" + shopId: ID! + ): Cart } #################### @@ -493,20 +544,38 @@ type SetEmailOnAnonymousCartPayload { extend type Mutation { "Add item(s) to a cart" - addCartItems(input: AddCartItemsInput!): AddCartItemsPayload! + addCartItems( + "Mutation input" + input: AddCartItemsInput! + ): AddCartItemsPayload! "Create a new cart" - createCart(input: CreateCartInput!): CreateCartPayload! + createCart( + "Mutation input" + input: CreateCartInput! + ): CreateCartPayload! "Reconcile an anonymous cart with the current account cart for the same shop" - reconcileCarts(input: ReconcileCartsInput!): ReconcileCartsPayload! + reconcileCarts( + "Mutation input" + input: ReconcileCartsInput! + ): ReconcileCartsPayload! "Remove item(s) from a cart" - removeCartItems(input: RemoveCartItemsInput!): RemoveCartItemsPayload! + removeCartItems( + "Mutation input" + input: RemoveCartItemsInput! + ): RemoveCartItemsPayload! "Set the email address for an anonymous cart" - setEmailOnAnonymousCart(input: SetEmailOnAnonymousCartInput!): SetEmailOnAnonymousCartPayload! + setEmailOnAnonymousCart( + "Mutation input" + input: SetEmailOnAnonymousCartInput! + ): SetEmailOnAnonymousCartPayload! "Update cart item(s) quantity. Use absolute quantity. If updating to 0, the item will be removed." - updateCartItemsQuantity(input: UpdateCartItemsQuantityInput!): UpdateCartItemsQuantityPayload! + updateCartItemsQuantity( + "Mutation input" + input: UpdateCartItemsQuantityInput! + ): UpdateCartItemsQuantityPayload! } diff --git a/imports/plugins/core/cart/server/no-meteor/schemas/checkout.graphql b/imports/plugins/core/cart/server/no-meteor/schemas/checkout.graphql index 46c9fe05424..fc532b6d156 100644 --- a/imports/plugins/core/cart/server/no-meteor/schemas/checkout.graphql +++ b/imports/plugins/core/cart/server/no-meteor/schemas/checkout.graphql @@ -186,10 +186,16 @@ type Checkout { extend type Mutation { "Select a fulfillment option from the `availableFulfillmentOptions` list for a fulfillment group" - selectFulfillmentOptionForGroup(input: SelectFulfillmentOptionForGroupInput!): SelectFulfillmentOptionForGroupPayload! + selectFulfillmentOptionForGroup( + "Mutation input" + input: SelectFulfillmentOptionForGroupInput! + ): SelectFulfillmentOptionForGroupPayload! "Set the shipping address for all fulfillment groups" - setShippingAddressOnCart(input: SetShippingAddressOnCartInput!): SetShippingAddressOnCartPayload! + setShippingAddressOnCart( + "Mutation input" + input: SetShippingAddressOnCartInput! + ): SetShippingAddressOnCartPayload! """ Clients should call this as necessary during checkout to update the `availableFulfillmentOptions` @@ -198,5 +204,8 @@ extend type Mutation { option for each group will have its prices recalculated one last time. If the prices do not match, order creation will fail. """ - updateFulfillmentOptionsForGroup(input: UpdateFulfillmentOptionsForGroupInput!): UpdateFulfillmentOptionsForGroupPayload! + updateFulfillmentOptionsForGroup( + "Mutation input" + input: UpdateFulfillmentOptionsForGroupInput! + ): UpdateFulfillmentOptionsForGroupPayload! } diff --git a/imports/plugins/core/catalog/client/components/publishControls.js b/imports/plugins/core/catalog/client/components/publishControls.js index d0ed62fba3f..4cf42bb5bb3 100644 --- a/imports/plugins/core/catalog/client/components/publishControls.js +++ b/imports/plugins/core/catalog/client/components/publishControls.js @@ -1,11 +1,34 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; +import gql from "graphql-tag"; +import { Mutation } from "react-apollo"; import Button from "@material-ui/core/Button"; import Typography from "@material-ui/core/Typography"; import withStyles from "@material-ui/core/styles/withStyles"; import { i18next } from "/client/api"; import PrimaryAppBar from "/imports/client/ui/components/PrimaryAppBar/PrimaryAppBar"; +const publishProductsToCatalog = gql` + mutation ($productIds: [ID]!) { + publishProductsToCatalog(productIds: $productIds) { + product { + productId + title + isDeleted + supportedFulfillmentTypes + variants { + _id + title + options { + _id + title + } + } + } + } + } +`; + const styles = (theme) => ({ label: { marginRight: theme.spacing(2) @@ -36,21 +59,29 @@ class PublishControls extends Component { return null; } + renderOnCompletedAlert = () => Alerts.toast(i18next.t("admin.catalogProductPublishSuccess"), "success"); + + renderOnErrorAlert = (error) => Alerts.toast(error.message, "error"); + render() { const { documentIds, onPublishClick } = this.props; return ( {this.renderChangesNotification()} - + this.renderOnCompletedAlert()} onError={(error) => this.renderOnErrorAlert(error)}> + {(mutationFunc) => ( + + )} + ); } diff --git a/imports/plugins/core/catalog/client/containers/publishContainer.js b/imports/plugins/core/catalog/client/containers/publishContainer.js index fea57da74a1..07b60d3a838 100644 --- a/imports/plugins/core/catalog/client/containers/publishContainer.js +++ b/imports/plugins/core/catalog/client/containers/publishContainer.js @@ -1,8 +1,7 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; -import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "@reactioncommerce/reaction-components"; -import { i18next } from "/client/api"; +import getOpaqueIds from "/imports/plugins/core/core/client/util/getOpaqueIds"; import TranslationProvider from "/imports/plugins/core/ui/client/providers/translationProvider"; import PublishControls from "../components/publishControls"; @@ -10,22 +9,26 @@ import PublishControls from "../components/publishControls"; * PublishContainer is a container component connected to Meteor data source. */ class PublishContainer extends Component { - publishToCatalog(collection, documentIds) { - Meteor.call(`catalog/publish/${collection}`, documentIds, (error, result) => { - if (result) { - Alerts.toast(i18next.t("admin.catalogProductPublishSuccess", { defaultValue: "Product published to catalog" }), "success"); - } else if (error) { - Alerts.toast(error.message, "error"); + async publishToCatalog(productIds, mutation) { + // we need to encode the productIds here to pass them to GraphQL + const productIdObjects = productIds.map((productId) => ( + { namespace: "Product", id: productId } + )); + const opaqueProductIds = await getOpaqueIds(productIdObjects); + + await mutation({ + variables: { + productIds: opaqueProductIds } }); } - handlePublishClick = () => { + handlePublishClick = (mutation) => { const productIds = this.props.documents .filter((doc) => doc.type === "simple") .map((doc) => doc._id); - this.publishToCatalog("products", productIds); + this.publishToCatalog(productIds, mutation); } handlePublishActions = (event, action) => { diff --git a/imports/plugins/core/catalog/server/index.js b/imports/plugins/core/catalog/server/index.js index 31ed1d5e461..805fdaf451a 100644 --- a/imports/plugins/core/catalog/server/index.js +++ b/imports/plugins/core/catalog/server/index.js @@ -1,6 +1,4 @@ -import "./i18n"; import "./methods/catalog"; -import "./methods/publishProducts"; /** * Query functions that do not import or use any Meteor packages or globals. These can be used both diff --git a/imports/plugins/core/catalog/server/methods/catalog.app-test.js b/imports/plugins/core/catalog/server/methods/catalog.app-test.js deleted file mode 100644 index 657a5d927e8..00000000000 --- a/imports/plugins/core/catalog/server/methods/catalog.app-test.js +++ /dev/null @@ -1,531 +0,0 @@ -/* eslint dot-notation:0 */ -/* eslint no-loop-func:0 */ -/* eslint prefer-arrow-callback:0 */ -import _ from "lodash"; -import { Meteor } from "meteor/meteor"; -import { Factory } from "meteor/dburles:factory"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import { Products, Tags } from "/lib/collections"; -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { Roles } from "meteor/alanning:roles"; -import ReactionError from "@reactioncommerce/reaction-error"; -import { addProduct, addProductSingleVariant } from "/imports/plugins/core/core/server/fixtures/products"; -import { getBaseContext } from "/imports/plugins/core/graphql/server/getGraphQLContextInMeteorMethod"; -import Fixtures from "/imports/plugins/core/core/server/fixtures"; - -describe("core product methods", function () { - // we can't clean Products collection after each test from now, because we - // have functions which called from async db operations callbacks. So, if we - // clean collections each time - we could have a situation when next test - // started, but previous not yet finished his async computations. - // So, if you need to clean the collection for your test, you could try to do - // it, but this is not recommended in droves - let sandbox; - let updateStub; - let removeStub; - let insertStub; - - before(function (done) { - this.timeout(20000); - - Reaction.onAppStartupComplete(() => { - Fixtures(); - Products.remove({}); - - // We sleep until `setBaseContext` has run. I wish there were a better way to - // do this but Meteor starts app tests whenever it decides to, without waiting - // for all the startup code to run. - const handle = Meteor.setInterval(() => { - if (getBaseContext().queries) { - Meteor.clearInterval(handle); - done(); - } - }, 500); - }); - }); - - after(function () { - if (updateStub) { - updateStub.restore(); - removeStub.restore(); - insertStub.restore(); - } - }); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("products/cloneVariant", function () { - it("should throw 403 error by non admin", function () { - this.timeout(20000); - sandbox.stub(Roles, "userIsInRole", () => false); - const product = addProduct(); - const variants = Products.find({ ancestors: [product._id] }).fetch(); - expect(variants.length).to.equal(1); - - const insertProductSpy = sandbox.spy(Products, "insert"); - expect(() => Meteor.call("products/cloneVariant", product._id, variants[0]._id)).to.throw(ReactionError, /Access Denied/); - expect(insertProductSpy).to.not.have.been.called; - }); - - it("should clone variant by admin", function () { - sandbox.stub(Roles, "userIsInRole", () => true); - const product = addProduct(); - let variants = Products.find({ ancestors: [product._id] }).fetch(); - expect(variants.length).to.equal(1); - Meteor.call("products/cloneVariant", product._id, variants[0]._id); - variants = Products.find({ ancestors: [product._id] }).count(); - expect(variants).to.equal(2); - }); - - it("number of `child variants` between source and cloned `variants` should be equal", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - const variant = Products.find({ ancestors: [product._id] }).fetch(); - let optionCount = Products.find({ - ancestors: { - $in: [variant[0]._id] - } - }).count(); - expect(optionCount).to.equal(2); - - Meteor.call("products/cloneVariant", product._id, variant[0]._id); - const variants = Products.find({ ancestors: [product._id] }).fetch(); - const clonedVariant = variants.filter((filteredVariant) => filteredVariant._id !== variant[0]._id); - expect(variant[0]._id).to.not.equal(clonedVariant[0]._id); - expect(_.isEqual(variant[0].ancestors, clonedVariant[0].ancestors)).to.be.true; - // expect(variant[0].ancestors).to.equal(clonedVariant[0].ancestors); - - optionCount = Products.find({ ancestors: { $in: [clonedVariant[0]._id] } }).count(); - expect(optionCount).to.equal(2); - }); - }); - - describe("products/createVariant", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const updateProductSpy = sandbox.spy(Products, "update"); - expect(() => Meteor.call("products/createVariant", product._id)).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - }); - - it("should create top level variant", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - let variants = Products.find({ ancestors: [product._id] }).fetch(); - expect(variants.length).to.equal(1); - Meteor.call("products/createVariant", product._id); - variants = Products.find({ ancestors: [product._id] }).fetch(); - expect(variants.length).to.equal(2); - }); - - it("should create option variant", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let options; - const product = addProduct(); - const variant = Products.find({ ancestors: [product._id] }).fetch()[0]; - options = Products.find({ - ancestors: { $in: [variant._id] } - }).fetch(); - expect(options.length).to.equal(2); - - Meteor.call("products/createVariant", variant._id); - options = Products.find({ - ancestors: { $in: [variant._id] } - }).fetch(); - expect(options.length).to.equal(3); - }); - }); - - describe("products/deleteVariant", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const variant = Products.findOne({ ancestors: [product._id] }); - const removeProductSpy = sandbox.spy(Products, "remove"); - expect(() => Meteor.call("products/deleteVariant", variant._id)).to.throw(ReactionError, /Access Denied/); - expect(removeProductSpy).to.not.have.been.called; - }); - - it("should mark top-level variant as deleted", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - let variant = Products.findOne({ ancestors: [product._id] }); - expect(variant.isDeleted).to.equal(false); - Meteor.call("products/deleteVariant", variant._id); - variant = Products.findOne(variant._id); - expect(variant.isDeleted).to.equal(true); - }); - - it("should mark all child variants (options) as deleted if top-level variant deleted", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - const variant = Products.find({ ancestors: [product._id] }).fetch()[0]; - const variants = Products.find({ - ancestors: { - $in: [variant._id] - } - }).fetch(); - expect(variants.length).to.equal(2); - Meteor.call("products/deleteVariant", variant._id); - }); - }); - - describe("products/cloneProduct", function () { - // At the moment we do not have any mechanisms that track the product - // cloning hierarchy, so the only way to track that will be cleaning - // collection on before each test. - beforeEach(function () { - return Products.remove({}); - }); - - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const insertProductSpy = sandbox.spy(Products, "insert"); - expect(() => Meteor.call("products/cloneProduct", {})).to.throw(ReactionError, /Access Denied/); - expect(insertProductSpy).to.not.have.been.called; - }); - - it("should clone product", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - expect(Products.find({ type: "simple" }).count()).to.equal(1); - Meteor.call("products/cloneProduct", product); - expect(Products.find({ type: "simple" }).count()).to.equal(2); - const productCloned = Products.find({ - _id: { - $ne: product._id - }, - type: "simple" - }).fetch()[0]; - expect(productCloned.title).to.equal(`${product.title}-copy`); - expect(productCloned.handle).to.equal(`${product.handle}-copy`); - expect(productCloned.pageTitle).to.equal(product.pageTitle); - expect(productCloned.description).to.equal(product.description); - }); - - it("product should be cloned with all variants and child variants with equal data, but not the same `_id`s", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - const variants = Products.find({ ancestors: { $in: [product._id] } }).fetch(); - expect(variants.length).to.equal(3); - Meteor.call("products/cloneProduct", product); - const clone = Products.find({ - _id: { - $ne: product._id - }, - type: "simple" - }).fetch()[0]; - const cloneVariants = Products.find({ - ancestors: { $in: [clone._id] } - }).fetch(); - expect(cloneVariants.length).to.equal(3); - for (let inc = 0; inc < variants.length; inc += 1) { - expect(cloneVariants.some((clonedVariant) => clonedVariant.title === variants[inc].title)).to.be.ok; - } - }); - - it("product group cloning should create the same number of new products", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - const product2 = addProduct(); - Meteor.call("products/cloneProduct", [product, product2]); - const clones = Products.find({ - _id: { - $nin: [product._id, product2._id] - }, - type: "simple" - }).fetch(); - expect(clones.length).to.equal(2); - }); - - it("product group cloning should create the same number of cloned variants", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - const product2 = addProduct(); - const variants = Products.find({ - ancestors: { $in: [product._id, product2._id] } - }).count(); - Meteor.call("products/cloneProduct", [product, product2]); - const clones = Products.find({ - _id: { - $nin: [product._id, product2._id] - }, - type: "simple" - }).fetch(); - expect(clones.length).to.equal(2); - const clonedVariants = Products.find({ - ancestors: { $in: [clones[0]._id, clones[1]._id] } - }).count(); - expect(clonedVariants).to.equal(variants); - }); - }); - - describe("createProduct", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const insertProductSpy = sandbox.spy(Products, "insert"); - expect(() => Meteor.call("products/createProduct")).to.throw(ReactionError, /Access Denied/); - expect(insertProductSpy).to.not.have.been.called; - }); - - it("should create new product", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - Meteor.call("products/createProduct", (error, result) => { - if (result) { - expect(Products.find({ _id: result }).count()).to.equal(1); - } - }); - }); - - it("should create variant with new product", function (done) { - sandbox.stub(Reaction, "hasPermission", () => true); - Meteor.call("products/createProduct", (error, result) => { - if (error || !result) { - done(error || new Error("no result")); - return; - } - // this test successfully finds product variant only by such way - Meteor.defer(() => { - expect(Products.find({ ancestors: [result] }).count()).to.equal(1); - done(); - }); - }); - }); - }); - - describe("deleteProduct", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const removeProductSpy = sandbox.spy(Products, "remove"); - expect(() => Meteor.call("products/archiveProduct", product._id)).to.throw(ReactionError, /Access Denied/); - expect(removeProductSpy).to.not.have.been.called; - }); - - it("should mark product as deleted by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - Meteor.call("products/archiveProduct", product._id); - product = Products.findOne(product._id); - expect(product.isDeleted).to.equal(true); - }); - }); - - describe("updateProductField", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const updateProductSpy = sandbox.spy(Products, "update"); - expect(() => Meteor.call( - "products/updateProductField", - product._id, "title", "Updated Title" - )).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - }); - - it("should update product field by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - Meteor.call("products/updateProductField", product._id, "title", "Updated Title"); - product = Products.findOne(product._id); - expect(product.title).to.equal("Updated Title"); - }); - - it("should update variant fields", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const product = addProduct(); - let variant = Products.findOne({ ancestors: [product._id] }); - Meteor.call("products/updateProductField", variant._id, "title", "Updated Title"); - variant = Products.findOne(variant._id); - expect(variant.title).to.equal("Updated Title"); - }); - }); - - describe("updateProductTags", function () { - beforeEach(function () { - return Tags.remove({}); - }); - - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const updateProductSpy = sandbox.spy(Products, "update"); - const insertTagsSpy = sandbox.spy(Tags, "insert"); - expect(() => Meteor.call("products/updateProductTags", product._id, "productTag", null)).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - expect(insertTagsSpy).to.not.have.been.called; - }); - - it("should create new tag when passed tag name and null ID by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - const tagName = "Product Tag"; - expect(Tags.findOne({ name: tagName })).to.be.undefined; - Meteor.call("products/updateProductTags", product._id, tagName, null); - const tag = Tags.findOne({ name: tagName }); - expect(tag.slug).to.equal(Reaction.getSlug(tagName)); - product = Products.findOne(product._id); - expect(product.hashtags).to.contain(tag._id); - }); - - it("should add existing tag when passed existing tag and tag._id by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - const tag = Factory.create("tag"); - expect(Tags.find().count()).to.equal(1); - expect(product.hashtags).to.not.contain(tag._id); - Meteor.call("products/updateProductTags", product._id, tag.name, tag._id); - expect(Tags.find().count()).to.equal(1); - product = Products.findOne(product._id); - expect(product.hashtags).to.contain(tag._id); - }); - }); - - describe("removeProductTag", function () { - beforeEach(function () { - return Tags.remove({}); - }); - - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const tag = Factory.create("tag"); - const updateProductSpy = sandbox.spy(Products, "update"); - const removeTagsSpy = sandbox.spy(Tags, "remove"); - expect(() => Meteor.call("products/removeProductTag", product._id, tag._id)).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - expect(removeTagsSpy).to.not.have.been.called; - }); - - it("should remove product tag by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - const tag = Factory.create("tag"); - - // Update product tags and publish so the original product will have the tags - Meteor.call("products/updateProductTags", product._id, tag.name, tag._id); - product = Products.findOne(product._id); - expect(product.hashtags).to.contain(tag._id); - expect(Tags.find().count()).to.equal(1); - - // Remove the tag from the published product and ensure it succeed. - Meteor.call("products/removeProductTag", product._id, tag._id); - product = Products.findOne(product._id); - expect(product.hashtags).to.not.contain(tag._id); - }); - }); - - describe("setHandle", () => { - beforeEach(() => Tags.remove({})); - - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const productUpdateSpy = sandbox.spy(Products, "update"); - expect(() => Meteor.call("products/setHandle", product._id)).to.throw(ReactionError, /Access Denied/); - expect(productUpdateSpy).to.not.have.been.called; - }); - - it("should set handle for product by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - Meteor.call("products/updateProductField", product._id, "title", "new product name"); - Meteor.call("products/setHandle", product._id); - product = Products.findOne(product._id); - expect(product.handle).to.equal("new-product-name"); - }); - }); - - describe("setHandleTag", function () { - beforeEach(function () { - return Tags.remove({}); - }); - - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const tag = Factory.create("tag"); - const updateProductSpy = sandbox.spy(Products, "update"); - expect(function () { - return Meteor.call("products/setHandleTag", product._id, tag._id); - }).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - }); - - it("should set handle tag for product by admin", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - const tag = Factory.create("tag"); - Meteor.call("products/setHandleTag", product._id, tag._id); - product = Products.findOne(product._id); - expect(product.handle).to.equal(tag.slug); - }); - }); - - describe("updateMetaFields position", () => { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const product2 = addProduct(); - const updateProductSpy = sandbox.spy(Products, "update"); - expect(() => Meteor.call("products/updateVariantsPosition", [ - product._id, product2._id], product.shopId)).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - }); - - it("should update variants' position", function () { - sandbox.stub(Reaction, "hasPermission", () => true); - const { variant: variant1 } = addProductSingleVariant(); - const { variant: variant2 } = addProductSingleVariant(); - const { variant: variant3 } = addProductSingleVariant(); - - expect(variant1.index).to.be.undefined; - expect(variant2.index).to.be.undefined; - expect(variant3.index).to.be.undefined; - - Meteor.call("products/updateVariantsPosition", [ - variant2._id, variant3._id, variant1._id - ], variant1.shopId); - const modifiedVariant1 = Products.findOne(variant1._id); - const modifiedVariant2 = Products.findOne(variant2._id); - const modifiedVariant3 = Products.findOne(variant3._id); - expect(modifiedVariant1.index).to.be.equal(2); - expect(modifiedVariant2.index).to.be.equal(0); - expect(modifiedVariant3.index).to.be.equal(1); - }); - }); - - describe("updateMetaFields", function () { - it("should throw 403 error by non admin", function () { - sandbox.stub(Reaction, "hasPermission", () => false); - const product = addProduct(); - const updateProductSpy = sandbox.spy(Products, "update"); - expect(() => Meteor.call("products/updateMetaFields", product._id, { - key: "Material", - value: "Spandex" - })).to.throw(ReactionError, /Access Denied/); - expect(updateProductSpy).to.not.have.been.called; - }); - - it("should add meta fields by admin", function (done) { - sandbox.stub(Reaction, "hasPermission", () => true); - let product = addProduct(); - Meteor.call("products/updateMetaFields", product._id, { - key: "Material", - value: "Spandex" - }); - product = Products.findOne(product._id); - expect(product.metafields.length).to.be.equal(1); - - return done(); - }); - }); -}); diff --git a/imports/plugins/core/catalog/server/methods/publishProducts.js b/imports/plugins/core/catalog/server/methods/publishProducts.js deleted file mode 100644 index 99394c913d4..00000000000 --- a/imports/plugins/core/catalog/server/methods/publishProducts.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import { check } from "meteor/check"; -import getGraphQLContextInMeteorMethod from "/imports/plugins/core/graphql/server/getGraphQLContextInMeteorMethod"; -import publishProductsMutation from "../no-meteor/mutations/publishProducts"; - -Meteor.methods({ - "catalog/publish/products"(productIds) { - check(productIds, [String]); - const context = Promise.await(getGraphQLContextInMeteorMethod(this.userId)); - return publishProductsMutation(context, productIds); - } -}); diff --git a/imports/plugins/core/catalog/server/i18n/ar.json b/imports/plugins/core/catalog/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/ar.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/catalog/server/i18n/bg.json b/imports/plugins/core/catalog/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/bg.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/catalog/server/i18n/cs.json b/imports/plugins/core/catalog/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/cs.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/catalog/server/i18n/de.json b/imports/plugins/core/catalog/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/de.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/catalog/server/i18n/el.json b/imports/plugins/core/catalog/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/el.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/catalog/server/i18n/en.json b/imports/plugins/core/catalog/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/en.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/catalog/server/i18n/es.json b/imports/plugins/core/catalog/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/es.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/catalog/server/i18n/fr.json b/imports/plugins/core/catalog/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/fr.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/catalog/server/i18n/he.json b/imports/plugins/core/catalog/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/he.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/catalog/server/i18n/hr.json b/imports/plugins/core/catalog/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/hr.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/catalog/server/i18n/hu.json b/imports/plugins/core/catalog/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/hu.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/checkout/server/i18n/index.js b/imports/plugins/core/catalog/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/core/checkout/server/i18n/index.js rename to imports/plugins/core/catalog/server/no-meteor/i18n/index.js index 2d1a40cefec..9deb0a6b6e7 100644 --- a/imports/plugins/core/checkout/server/i18n/index.js +++ b/imports/plugins/core/catalog/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; import de from "./de.json"; @@ -28,4 +26,29 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/catalog/server/i18n/it.json b/imports/plugins/core/catalog/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/it.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/catalog/server/i18n/my.json b/imports/plugins/core/catalog/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/my.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/catalog/server/i18n/nb.json b/imports/plugins/core/catalog/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/nb.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/catalog/server/i18n/nl.json b/imports/plugins/core/catalog/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/nl.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/catalog/server/i18n/pl.json b/imports/plugins/core/catalog/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/pl.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/catalog/server/i18n/pt.json b/imports/plugins/core/catalog/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/pt.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/catalog/server/i18n/ro.json b/imports/plugins/core/catalog/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/ro.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/catalog/server/i18n/ru.json b/imports/plugins/core/catalog/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/ru.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/catalog/server/i18n/sl.json b/imports/plugins/core/catalog/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/sl.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/catalog/server/i18n/sv.json b/imports/plugins/core/catalog/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/sv.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/catalog/server/i18n/tr.json b/imports/plugins/core/catalog/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/tr.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/catalog/server/i18n/vi.json b/imports/plugins/core/catalog/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/vi.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/catalog/server/i18n/zh.json b/imports/plugins/core/catalog/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/catalog/server/i18n/zh.json rename to imports/plugins/core/catalog/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/catalog/server/no-meteor/register.js b/imports/plugins/core/catalog/server/no-meteor/register.js index be05b931728..b245aaafc15 100644 --- a/imports/plugins/core/catalog/server/no-meteor/register.js +++ b/imports/plugins/core/catalog/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import mutations from "./mutations"; import queries from "./queries"; import resolvers from "./resolvers"; @@ -14,6 +15,7 @@ export default async function register(app) { label: "Catalog", name: "reaction-catalog", icon: "fa fa-book", + i18n, collections: { Catalog: { name: "Catalog", diff --git a/imports/plugins/core/catalog/server/no-meteor/schemas/schema.graphql b/imports/plugins/core/catalog/server/no-meteor/schemas/schema.graphql index 321e5f3aec0..d3901f4d53b 100644 --- a/imports/plugins/core/catalog/server/no-meteor/schemas/schema.graphql +++ b/imports/plugins/core/catalog/server/no-meteor/schemas/schema.graphql @@ -163,7 +163,25 @@ type CatalogProduct implements CatalogProductOrVariant & Node { tagIds: [ID] "The list of tags that have been applied to this product" - tags(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: TagSortByField = _id): TagConnection + tags( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, tags are sorted by ID. Set this to sort by one of the other allowed fields" + sortBy: TagSortByField = _id + ): TagConnection "Product title" title: String @@ -389,21 +407,26 @@ extend type Query { "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." after: ConnectionCursor, + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." before: ConnectionCursor, + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." first: ConnectionLimitInt, + "Return at most this many results. This parameter may be used with the `before` parameter." last: ConnectionLimitInt, + "Return only results that come after the Nth result. This parameter may be used with the `first` parameter." offset: Int, + "Return results sorted in this order" sortOrder: SortOrder = desc, "Provide a Currency code if sortBy is minPrice" sortByPriceCurrencyCode: String - "By default, items are sorted by newest products. Set this to sort by one of the other allowed fields" + "By default, items are sorted by when they were last updated, most recently updated first. Set this to sort by one of the other allowed fields" sortBy: CatalogItemSortByField = updatedAt ): CatalogItemConnection diff --git a/imports/plugins/core/checkout/register.js b/imports/plugins/core/checkout/register.js new file mode 100644 index 00000000000..add1f847771 --- /dev/null +++ b/imports/plugins/core/checkout/register.js @@ -0,0 +1,11 @@ +/** + * This file is necessary for backwards compatibility while we refactor + * the API to remove Meteor. The no-meteor `register.js` file will + * eventually become the main entry point of the plugin, but for now + * our Meteor tooling loads this file, so we include this here as a + * temporary bridge. + */ +import Reaction from "/imports/plugins/core/core/server/Reaction"; +import register from "./server/no-meteor/register"; + +Reaction.whenAppInstanceReady(register); diff --git a/imports/plugins/core/checkout/server/index.js b/imports/plugins/core/checkout/server/index.js index ffcc5c170b7..09b8411d29a 100644 --- a/imports/plugins/core/checkout/server/index.js +++ b/imports/plugins/core/checkout/server/index.js @@ -1,2 +1 @@ import "./methods/workflow"; -import "./i18n"; diff --git a/imports/plugins/core/checkout/server/i18n/ar.json b/imports/plugins/core/checkout/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/ar.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/checkout/server/i18n/bg.json b/imports/plugins/core/checkout/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/bg.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/checkout/server/i18n/cs.json b/imports/plugins/core/checkout/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/cs.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/checkout/server/i18n/de.json b/imports/plugins/core/checkout/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/de.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/checkout/server/i18n/el.json b/imports/plugins/core/checkout/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/el.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/checkout/server/i18n/en.json b/imports/plugins/core/checkout/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/en.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/checkout/server/i18n/es.json b/imports/plugins/core/checkout/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/es.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/checkout/server/i18n/fr.json b/imports/plugins/core/checkout/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/fr.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/checkout/server/i18n/he.json b/imports/plugins/core/checkout/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/he.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/checkout/server/i18n/hr.json b/imports/plugins/core/checkout/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/hr.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/checkout/server/i18n/hu.json b/imports/plugins/core/checkout/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/hu.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/dashboard/server/i18n/index.js b/imports/plugins/core/checkout/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/core/dashboard/server/i18n/index.js rename to imports/plugins/core/checkout/server/no-meteor/i18n/index.js index 2d1a40cefec..9deb0a6b6e7 100644 --- a/imports/plugins/core/dashboard/server/i18n/index.js +++ b/imports/plugins/core/checkout/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; import de from "./de.json"; @@ -28,4 +26,29 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/checkout/server/i18n/it.json b/imports/plugins/core/checkout/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/it.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/checkout/server/i18n/my.json b/imports/plugins/core/checkout/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/my.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/checkout/server/i18n/nb.json b/imports/plugins/core/checkout/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/nb.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/checkout/server/i18n/nl.json b/imports/plugins/core/checkout/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/nl.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/checkout/server/i18n/pl.json b/imports/plugins/core/checkout/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/pl.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/checkout/server/i18n/pt.json b/imports/plugins/core/checkout/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/pt.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/checkout/server/i18n/ro.json b/imports/plugins/core/checkout/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/ro.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/checkout/server/i18n/ru.json b/imports/plugins/core/checkout/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/ru.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/checkout/server/i18n/sl.json b/imports/plugins/core/checkout/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/sl.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/checkout/server/i18n/sv.json b/imports/plugins/core/checkout/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/sv.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/checkout/server/i18n/tr.json b/imports/plugins/core/checkout/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/tr.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/checkout/server/i18n/vi.json b/imports/plugins/core/checkout/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/vi.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/checkout/server/i18n/zh.json b/imports/plugins/core/checkout/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/checkout/server/i18n/zh.json rename to imports/plugins/core/checkout/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/checkout/server/no-meteor/register.js b/imports/plugins/core/checkout/server/no-meteor/register.js new file mode 100644 index 00000000000..961634c85ee --- /dev/null +++ b/imports/plugins/core/checkout/server/no-meteor/register.js @@ -0,0 +1,14 @@ +import i18n from "./i18n"; + +/** + * @summary Import and call this function to add this plugin to your API. + * @param {ReactionNodeApp} app The ReactionNodeApp instance + * @returns {undefined} + */ +export default async function register(app) { + await app.registerPlugin({ + label: "Checkout", + name: "reaction-checkout", + i18n + }); +} diff --git a/imports/plugins/core/components/lib/hoc.js b/imports/plugins/core/components/lib/hoc.js index ca27a41f1a5..8bc9a78a529 100644 --- a/imports/plugins/core/components/lib/hoc.js +++ b/imports/plugins/core/components/lib/hoc.js @@ -6,10 +6,11 @@ import { Accounts } from "/lib/collections"; import { lifecycle } from "recompose"; import { composeWithTracker } from "./composer"; +let i18next; let Reaction; if (Meteor.isClient) { - ({ Reaction } = require("/client/api")); + ({ i18next, Reaction } = require("/client/api")); } else { Reaction = require("/imports/plugins/core/core/server/Reaction").default; } @@ -43,7 +44,7 @@ export function withMoment(component) { componentDidMount() { import("moment") .then(({ default: moment }) => { - moment.locale(Reaction.Locale.get().language); + moment.locale(i18next.language); this.setState({ moment }); return null; }) diff --git a/imports/plugins/core/core/server/Reaction/core.js b/imports/plugins/core/core/server/Reaction/core.js index a47a4433720..9a539d80637 100644 --- a/imports/plugins/core/core/server/Reaction/core.js +++ b/imports/plugins/core/core/server/Reaction/core.js @@ -308,23 +308,6 @@ export default { return settings.settings || {}; }, - /** - * @name getPrimaryShopCurrency - * @method - * @memberof Core - * @summary Get primary shop currency string - * @returns {String} Get shop currency or "USD" - */ - getPrimaryShopCurrency() { - const primaryShop = this.getPrimaryShop(); - - if (primaryShop && primaryShop.currency) { - return primaryShop.currency; - } - - return "USD"; - }, - /** * @summary **DEPRECATED** This method has been deprecated in favor of using getShopId * and getPrimaryShopId. To be removed. diff --git a/imports/plugins/core/core/server/Reaction/importer.js b/imports/plugins/core/core/server/Reaction/importer.js index 8b3f13650c3..f3b8a152e87 100644 --- a/imports/plugins/core/core/server/Reaction/importer.js +++ b/imports/plugins/core/core/server/Reaction/importer.js @@ -300,21 +300,6 @@ Importer.template = function (templateInfo, shopId) { return this.object(Collections.Templates, key, templateInfo); }; -/** - * @name translation - * @method - * @memberof Importer - * @summary Store a translation in the import buffer. - * @param {Object} key A key to look up the translation - * @param {Object} translation The translation data to be updated - * @param {String} shopId The package data to be updated - * @returns {Object} updated translation buffer - */ -Importer.translation = function (key, translation, shopId) { - const modifiedKey = Object.assign(key, { ns: translation.ns }); - return this.object(Collections.Translations, modifiedKey, { ...translation, shopId }); -}; - /** * @name shop * @method @@ -472,7 +457,6 @@ Importer.process = function (json, keys, callback, cbArgs) { } }; -Importer.indication("i18n", Collections.Translations, 0.2); Importer.indication("hashtags", Collections.Products, 0.5); Importer.indication("barcode", Collections.Products, 0.5); Importer.indication("price", Collections.Products, 0.5); diff --git a/imports/plugins/core/core/server/Reaction/index.js b/imports/plugins/core/core/server/Reaction/index.js index 526936b6397..0b872ad3403 100644 --- a/imports/plugins/core/core/server/Reaction/index.js +++ b/imports/plugins/core/core/server/Reaction/index.js @@ -1,5 +1,4 @@ import Log from "@reactioncommerce/logger"; -import getGraphQLContextInMeteorMethod from "/imports/plugins/core/graphql/server/getGraphQLContextInMeteorMethod"; import Core from "./core"; import { Fixture, Importer } from "./importer"; import getSlug from "./getSlug"; @@ -12,26 +11,6 @@ export default { ...Core, ...accountUtils, Collections, - - /** - * @deprecated Reaction.Email should no longer be used - */ - Email: { - /** - * @summary Backwards compatible email sending function - * @deprecated Call `context.mutations.sendEmail` directly instead - * @param {Object} options See `sendEmail` - * @returns {undefined} - */ - send(options) { - const context = Promise.await(getGraphQLContextInMeteorMethod(accountUtils.getUserId())); - - if (!options.fromShopId) options.fromShopId = Core.getShopId(); - - return Promise.await(context.mutations.sendEmail(context, options)); - } - }, - Fixture, getSlug, Importer, diff --git a/imports/plugins/core/core/server/fixtures/accounts.js b/imports/plugins/core/core/server/fixtures/accounts.js deleted file mode 100755 index 96cef50686d..00000000000 --- a/imports/plugins/core/core/server/fixtures/accounts.js +++ /dev/null @@ -1,109 +0,0 @@ -/* eslint-disable require-jsdoc */ -/* eslint-disable node/no-unsupported-features/es-syntax */ -import faker from "faker"; -import _ from "lodash"; -import { Factory } from "meteor/dburles:factory"; -import { Accounts } from "/lib/collections"; -import { getUser } from "./users"; -import { getShop } from "./shops"; - -/** - * @method getAccount - * @memberof Fixtures - * @returns {Object} Existing account or Factory account - */ -export function getAccount() { - const existingAccount = Accounts.findOne(); - return existingAccount || Factory.create("account"); -} - -/** - * @method getAddress - * @memberof Fixtures - * @param {Object} [options={}] Address options, optional - * @param {String} [options._id] - id of CartItem - * @param {String} [options.fullName] fullName - * @param {String} [options.address1] address1 - * @param {String} [options.address2] address2 - * @param {String} [options.city] city - * @param {String} [options.company] company - * @param {String} [options.phone] phone - * @param {String} [options.region] region - * @param {String} [options.postal] postal - * @param {String} [options.country] country - * @param {Boolean} [options.isCommercial] isCommercial - * @param {Boolean} [options.isShippingDefault] isShippingDefault - * @param {Boolean} [options.isBillingDefault] isBillingDefault - * @param {Array} [options.metafields] metafields - * @returns {Object} Address object - */ -export function getAddress(options = {}) { - const defaults = { - fullName: options.fullName || faker.name.findName(), - address1: options.address1 || faker.address.streetAddress(), - address2: options.address2 || faker.address.secondaryAddress(), - city: options.city || faker.address.city(), - company: faker.company.companyName(), - phone: faker.phone.phoneNumber(), - region: options.region || faker.address.stateAbbr(), - postal: options.postal || faker.address.zipCode(), - country: options.country || faker.address.countryCode(), - isCommercial: options.isCommercial || faker.random.boolean(), - isShippingDefault: options.isShippingDefault || faker.random.boolean(), - isBillingDefault: options.isBillingDefault || faker.random.boolean(), - metafields: [] - }; - return _.defaults(options, defaults); -} - -/** - * @name account - * @memberof Fixtures - * @summary Factory for Account - * @example Factory.create("account", { _id: "12345678", shopId }); - * @property {String} shopID - `getShop()._id` - * @property {String} userId id - `Factory.get("user")` - * @property {Array} emails `[{ - address: faker.internet.email(), - verified: faker.random.boolean() - }]` - * @property {Boolean} acceptsMarketing - `true` - * @property {String} state - `"new"` - * @property {Note} note - `faker.lorem.sentences()` - * @property {Object} profile - `{ - addressBook: [ - getAddress() - ] - }` - * @property {Array} metafields - '[]' - * @property {Date} createdAt - `new Date()` - * @property {Date} updatedAt - `new Date()` - * @returns {undefined} - */ -export function createAccountFactory() { - // there are many places in code which require that an Account's _id be equal - // to the User's _id (and therefore equal to userId) - Factory.define("account", Accounts, { - shopId: getShop()._id, - userId: getUser()._id, - emails: [{ - address: faker.internet.email(), - verified: faker.random.boolean() - }], - acceptsMarketing: true, - state: "new", - note: faker.lorem.sentences(), - profile: { - addressBook: [ - getAddress() - ] - }, - metafields: [], - createdAt: new Date(), - updatedAt: new Date() - }); -} - -export default function () { - createAccountFactory(); -} diff --git a/imports/plugins/core/core/server/fixtures/cart.js b/imports/plugins/core/core/server/fixtures/cart.js deleted file mode 100755 index 2d5a3aedeeb..00000000000 --- a/imports/plugins/core/core/server/fixtures/cart.js +++ /dev/null @@ -1,262 +0,0 @@ -/* eslint-disable require-jsdoc */ -import faker from "faker"; -import _ from "lodash"; -import Random from "@reactioncommerce/random"; -import { Factory } from "meteor/dburles:factory"; -import getGraphQLContextInMeteorMethod from "/imports/plugins/core/graphql/server/getGraphQLContextInMeteorMethod"; -import publishProductToCatalog from "/imports/plugins/core/catalog/server/no-meteor/utils/publishProductToCatalog"; -import { Cart, Products } from "/lib/collections"; -import { getShop } from "./shops"; -import { getAddress } from "./accounts"; -import { addProduct } from "./products"; - -/** - * @method getCartItem - * @memberof Fixtures - * @param {Object} [options] - Options object (optional) - * @param {String} [options._id] - id of CartItem - * @param {String} [options.productId] - _id of product that item came from - * @param {String} [options.shopId] - _id of shop that item came from - * @param {number} [options.quantity] - quantity of item in CartItem - * @param {Object} [options.variants] - _single_ variant object. ¯\_(ツ)_/¯ why called variants - * - * @returns {Object} - randomly generated cartItem/orderItem data object - */ -export function getCartItem(options = {}) { - const product = addProduct(); - const context = Promise.await(getGraphQLContextInMeteorMethod(null)); - Promise.await(publishProductToCatalog(product, context)); - const variant = Products.findOne({ ancestors: [product._id] }); - const childVariants = Products.find({ - ancestors: [ - product._id, variant._id - ] - }).fetch(); - const selectedOption = Random.choice(childVariants); - const quantity = 1; - const price = _.random(1, 100); - const defaults = { - _id: Random.id(), - addedAt: new Date(), - createdAt: new Date(), - isTaxable: false, - optionTitle: selectedOption.optionTitle, - price: { - amount: price, - currencyCode: "USD" - }, - priceWhenAdded: { - amount: price, - currencyCode: "USD" - }, - productId: product._id, - productSlug: product.handle, - productType: product.type, - quantity, - shopId: options.shopId || getShop()._id, - subtotal: { - amount: price * quantity, - currencyCode: "USD" - }, - title: product.title, - updatedAt: new Date(), - variantId: selectedOption._id, - variantTitle: selectedOption.title - }; - return _.defaults(options, defaults); -} - -/** - * @method getSingleCartItem - * @memberof Fixtures - * @param {Object} [options] - Options object (optional) - * @param {String} [options._id] - id of CartItem - * @param {String} [options.productId] - _id of product that item came from - * @param {String} [options.shopId] - _id of shop that item came from - * @returns {Object} - randomly generated cartItem/orderItem data object with only one cart item - */ -function getSingleCartItem(options = {}) { - const cartItem = getCartItem(options); - const quantity = options.cartQuantity || 1; - cartItem.quantity = quantity; - return cartItem; -} - -/** - * @method createCart - * @memberof Fixtures - * @param {String} productId ID of Product - * @param {String} variantId ID of Product Variant - * @returns {Object} Inserted cart object - */ -export function createCart(productId, variantId) { - const product = Products.findOne(productId); - const variant = Products.findOne(variantId); - const user = Factory.create("user"); - const account = Factory.create("account", { userId: user._id }); - const quantity = 1; - const cartItem = { - _id: Random.id(), - addedAt: new Date(), - createdAt: new Date(), - isTaxable: false, - optionTitle: variant.optionTitle, - price: { - amount: variant.price, - currencyCode: "USD" - }, - priceWhenAdded: { - amount: variant.price, - currencyCode: "USD" - }, - productId: product._id, - productSlug: product.handle, - productType: product.type, - quantity, - shopId: getShop()._id, - subtotal: { - amount: variant.price * quantity, - currencyCode: "USD" - }, - title: product.title, - updatedAt: new Date(), - variantId: variant._id, - variantTitle: variant.title - }; - - const cart = { - shopId: getShop()._id, - accountId: account._id, - email: faker.internet.email(), - items: [cartItem], - currencyCode: "USD", - shipping: [ - { - _id: Random.id(), - shopId: getShop()._id, - address: getAddress() - } - ], - createdAt: faker.date.past(), - updatedAt: new Date() - }; - const newCartId = Cart.insert(cart); - const insertedCart = Cart.findOne({ _id: newCartId }); - return insertedCart; -} - -/** - * @description exports cart fixtures - * @returns {undefined} undefined - */ -export default function () { - /** - * @name Cart - * @memberof Fixtures - * @summary Define cart Factory - * @example const cart = Factory.create("cartMultiItems"); - * @property {string} shopId id - `getShop().id` - * @property {string} accountId id - `Factory.get("account")` - * @property {string} email - `faker.internet.email()` - * @property {Array} items - `[getCartItem(), getCartItem()]` - * @property {Array} shipping - `[ - { - _id: Random.id(), - shopId: getShop()._id, - address: addressForOrder - } - ]` - * @property {Date} createdAt - `faker.date.past()` - * @property {Date} updatedAt - `new Date()` - * @description Types of Cart Factories: - * - `cart`: A cart with a user and two items - * - `cartToOrder`: A cart with shipping, billing info and at the Checkout workflow state - * - `anonymousCart`: An empty cart with an anonymous user - * - `cartOne`: A cart with one item - * - `cartTwo`: A cart with one item with quantity 2 - * - `cartMultiItems`: A cart with two items, 1 each - * - `cartMultiShop`: A cart with two items, from different shops - * - `cartNoItems`: A cart with a user and no items - */ - const cartNoItems = { - shopId: getShop()._id, - accountId: Factory.get("account", { userId: Factory.get("user") }), - currencyCode: "USD", - email: faker.internet.email(), - items: [], - shipping: [], - workflow: { - status: "new", - workflow: [] - }, - createdAt: faker.date.past(), - updatedAt: new Date() - }; - - const cart = { - shopId: getShop()._id, - accountId: Factory.get("account"), - currencyCode: "USD", - email: faker.internet.email(), - items: [ - getCartItem(), - getCartItem() - ], - shipping: [], - workflow: { - status: "new", - workflow: [] - }, - createdAt: faker.date.past(), - updatedAt: new Date() - }; - - const cartOne = { - items: [ - getSingleCartItem() - ] - }; - - const cartTwo = { - items: [ - getSingleCartItem({ cartQuantity: 2 }) - ] - }; - - const cartMultiItems = { - items: [getSingleCartItem(), getSingleCartItem()] - }; - - const cartMultiShopItems = { - items: [getSingleCartItem(), getSingleCartItem({ shopId: Random.id() })] - }; - - const addressForOrder = getAddress(); - const cartToOrder = { - shopId: getShop()._id, - shipping: [ - { - _id: Random.id(), - shopId: getShop()._id, - address: addressForOrder, - payment: { - _id: Random.id(), - shopId: getShop()._id, - address: addressForOrder - } - } - ] - }; - - const anonymousCart = { - accountId: Factory.get("account", { userId: Factory.get("anonymous") }) - }; - - Factory.define("cart", Cart, Object.assign({}, cart)); - Factory.define("anonymousCart", Cart, Object.assign({}, cart, anonymousCart)); - Factory.define("cartOne", Cart, Object.assign({}, cart, cartToOrder, cartOne)); - Factory.define("cartTwo", Cart, Object.assign({}, cart, cartToOrder, cartTwo)); - Factory.define("cartMultiItems", Cart, Object.assign({}, cart, cartToOrder, cartMultiItems)); - Factory.define("cartMultiShop", Cart, Object.assign({}, cart, cartToOrder, cartMultiShopItems)); - Factory.define("cartNoItems", Cart, Object.assign({}, cart, cartToOrder, cartNoItems)); -} diff --git a/imports/plugins/core/core/server/fixtures/groups.js b/imports/plugins/core/core/server/fixtures/groups.js deleted file mode 100755 index c5dc95937e0..00000000000 --- a/imports/plugins/core/core/server/fixtures/groups.js +++ /dev/null @@ -1,20 +0,0 @@ -import { Factory } from "meteor/dburles:factory"; -import { Groups } from "/lib/collections"; -import { getShop } from "./shops"; - -/** - * @summary define group factory - * @returns {undefined} - */ -export default function () { - const group = { - name: "default", - slug: "default", - permissions: ["test"], - shopId: getShop()._id, - createdAt: new Date(), - updatedAt: new Date() - }; - - Factory.define("group", Groups, group); -} diff --git a/imports/plugins/core/core/server/fixtures/index.js b/imports/plugins/core/core/server/fixtures/index.js deleted file mode 100644 index 00bf29c022f..00000000000 --- a/imports/plugins/core/core/server/fixtures/index.js +++ /dev/null @@ -1,30 +0,0 @@ -import accounts from "./accounts"; -import cart from "./cart"; -import orders from "./orders"; -import products from "./products"; -import { examplePaymentMethod, examplePackage } from "./packages"; -import shops from "./shops"; -import users from "./users"; -import groups from "./groups"; - -/** - * @file Fixtures and Factories for testing - Use these factories to test shops, users, example payment methods, example packages, orders, products, accounts, carts and user groups. - * See the [meteor-factory](https://github.com/versolearning/meteor-factory/) documentation to learn how to define, extend and create your own factories. - * - * @namespace Fixtures -*/ - -/** - * @returns {undefined} - */ -export default function fixtures() { - shops(); - users(); - examplePaymentMethod(); - examplePackage(); - accounts(); - products(); - cart(); - orders(); - groups(); -} diff --git a/imports/plugins/core/core/server/fixtures/orders.js b/imports/plugins/core/core/server/fixtures/orders.js deleted file mode 100755 index 91ccb9edea1..00000000000 --- a/imports/plugins/core/core/server/fixtures/orders.js +++ /dev/null @@ -1,262 +0,0 @@ -/* eslint-disable node/no-unsupported-features/es-syntax */ -import faker from "faker"; -import _ from "lodash"; -import Random from "@reactioncommerce/random"; -import { Factory } from "meteor/dburles:factory"; -import { Orders, Products } from "/lib/collections"; -import { getShop } from "./shops"; -import { getAccount, getAddress } from "./accounts"; -import { addProduct } from "./products"; - -/** - * @method randomProcessor - * @memberof Fixtures - * @summary Return a random payment processor string, either: `"Stripe"` `"Braintree"` - * @returns {String} Name of payment processor - */ -export function randomProcessor() { - return _.sample(["Stripe", "Braintree"]); -} - -const itemIdOne = Random.id(); -const itemIdTwo = Random.id(); - -/** - * @method randomStatus - * @memberof Fixtures - * @summary Return a random payment status, from: `"created", "approved", "failed", "canceled", "expired", "pending", "voided", "settled"` - * @returns {String} Payment status string - */ -export function randomStatus() { - return _.sample([ - "created", - "approved", - "failed", - "canceled", - "expired", - "pending", - "voided", - "settled" - ]); -} - -/** - * @method randomMode - * @memberof Fixtures - * @summary Return a random credit card status, from: `"authorize", "capture", "refund", "void"` - * @returns {String} Payment status string - */ -export function randomMode() { - return _.sample(["authorize", "capture", "refund", "void"]); -} - -/** - * @method getAccountId - * @memberof Fixtures - * @returns {String} ID - */ -export function getAccountId() { - return getAccount()._id; -} - -/** - * @method getShopId - * @memberof Fixtures - * @returns {String} ID - */ -export function getShopId() { - return getShop()._id; -} - -/** - * @method defineOrders - * @memberof Fixtures - * @returns {undefined} - */ -export default function defineOrders() { - const shopId = getShopId(); - const accountId = getAccountId(); - - /** - * @name order - * @memberof Fixtures - * @summary Create an Order Factory - * @example order = Factory.create("order") - * @property {String} status OrderItems - `faker.lorem.sentence(3)` - * @property {Array} history OrderItems History - `[]` - * @property {Array} documents OrderItems Document - `[]` - * @property {String} cartId Order - `Random.id()` - * @property {Array} notes Order - `[]` - * @property {String} shopId Cart - `shopId` - * @property {String} shopId.accountId Cart - `accountId` - * @property {String} shopId.email Cart - `faker.internet.email()` - * @property {String} shopId.workflow Cart - Object - * @property {String} shopId.workflow.status Cart - `"new"` - * @property {String} shopId.workflow Cart - `"coreOrderWorkflow/created"` - * @property {Array} shopId.items Array of products - * @property {String} shopId.items._id Cart - Product - cart ID - * @property {String} shopId.items.title Cart - Product - `"itemOne"` - * @property {String} shopId.items.shopId Cart - Product - store ID - * @property {String} shopId.items.productId Cart - Product - product ID - * @property {Number} shopId.items.quantity Cart - Product - `1` - * @property {Object} shopId.items.variants Cart - Product - variants - * @property {Object} shopId.items.workflow Cart - Product - Object - * @property {String} shopId.items.workflow.status Cart - Product - `"new"` - * @property {String[]} supportedFulfillmentTypes - ["shipping"] - * @property {Array} shipping - Shipping - `[{}]` - * @property {String[]} shipping.itemIds - * @property {Object} shipping.payment - A payment - * @property {String} shipping.payment._id - Billing - `Random.id()` - * @property {Object} shipping.payment.address - Billing - Address object - * @property {String} shipping.payment.displayName - `"MasterCard 2346"` - * @property {String} shipping.payment.method - `"credit"` - * @property {String} shipping.payment.processor - `"Example"` - * @property {String} shipping.payment.paymentPluginName - `"example-paymentmethod"` - * @property {String} shipping.payment.mode - `"authorize"` - * @property {String} shipping.payment.status - `"created"` - * @property {Number} shipping.payment.amount - `12.4` - * @property {Object} shipping.payment.invoice - Object - * @property {Number} shipping.payment.invoice.total - `12.45` - * @property {Number} shipping.payment.invoice.subtotal - `12.45` - * @property {Number} shipping.payment.invoice.discounts - `0` - * @property {Number} shipping.payment.invoice.taxes - `0.12` - * @property {Number} shipping.payment.invoice.shipping - `4.0` - * @property {String} state - `"new"` - * @property {Date} createdAt - `new Date()` - * @property {Date} updatedAt - `new Date()` - */ - Factory.define("order", Orders, { - // Schemas.OrderItems - status: faker.lorem.sentence(3), - history: [], - documents: [], - - // Schemas.Order - cartId: Random.id(), - notes: [], - - // Schemas.Cart - shopId, - accountId, - email: faker.internet.email(), - workflow: { - status: "new", - workflow: [ - "coreOrderWorkflow/created" - ] - }, - supportedFulfillmentTypes: ["shipping"], - shipping() { - const product = addProduct({ shopId }); - const variant = Products.findOne({ ancestors: [product._id] }); - const childVariants = Products.find({ - ancestors: [ - product._id, variant._id - ] - }).fetch(); - const selectedOption = Random.choice(childVariants); - const product2 = addProduct({ shopId }); - const variant2 = Products.findOne({ ancestors: [product2._id] }); - const childVariants2 = Products.find({ - ancestors: [ - product2._id, variant2._id - ] - }).fetch(); - const selectedOption2 = Random.choice(childVariants2); - return [{ - _id: Random.id(), - address: getAddress({ isShippingDefault: true }), - type: "shipping", - invoice: { - currencyCode: "USD", - discounts: 0, - effectiveTaxRate: 0.05, - shipping: 4.00, - subtotal: 12.45, - surcharges: 0, - taxableAmount: 12.45, - taxes: 0.12, - total: 12.45 - }, - items: [{ - _id: itemIdOne, - addedAt: new Date(), - createdAt: new Date(), - updatedAt: new Date(), - price: { - amount: 1, - currencyCode: "USD" - }, - subtotal: 1, - title: "firstItem", - shopId: product.shopId, - productId: product._id, - quantity: 1, - product, - variants: selectedOption, - workflow: { - status: "new" - } - }, { - _id: itemIdTwo, - addedAt: new Date(), - createdAt: new Date(), - updatedAt: new Date(), - price: { - amount: 1, - currencyCode: "USD" - }, - subtotal: 1, - title: "secondItem", - shopId: product2.shopId, - productId: product2._id, - quantity: 1, - product: product2, - variants: selectedOption2, - workflow: { - status: "new" - } - }], - itemIds: [itemIdOne, itemIdTwo], - shipmentMethod: { - _id: Random.id(), - currencyCode: "USD", - handling: 0, - rate: 0, - name: "name", - label: "label" - }, - totalItemQuantity: 2, - shopId, - workflow: { - status: "new" - } - }]; - }, // fulfillment group Schema - payments: [ - { - _id: Random.id(), - address: getAddress({ isBillingDefault: true }), - amount: 12.45, - createdAt: new Date(), - currencyCode: "USD", - displayName: "MasterCard 2346", - method: "credit", - mode: "authorize", - name: "iou_example", - paymentPluginName: "example-paymentmethod", - processor: "Example", - shopId, - status: "created", - transactionId: "txID", - transactions: [] - } - ], - state: "new", - currencyCode: "USD", - referenceId: () => Random.id(), - totalItemQuantity: 2, - createdAt: new Date(), - updatedAt: new Date() - }); -} diff --git a/imports/plugins/core/core/server/fixtures/packages.js b/imports/plugins/core/core/server/fixtures/packages.js deleted file mode 100644 index a3e1fc394d3..00000000000 --- a/imports/plugins/core/core/server/fixtures/packages.js +++ /dev/null @@ -1,76 +0,0 @@ -import { Factory } from "meteor/dburles:factory"; -import { Packages } from "/lib/collections"; -import { getShopId } from "./shops"; - -/** - * @method getPkgData - * @memberof Fixtures - * @summary Get package data object, given a package name - * @example getPkgData("example-paymentmethod") ? getPkgData("example-paymentmethod")._id : "uiwneiwknekwewe" - * @param {String} pkgName name of package - * @returns {Object} Package object - */ -export const getPkgData = (pkgName) => { - const pkgData = Packages.findOne({ - name: pkgName - }); - return pkgData; -}; - -/** - * @name examplePaymentMethod - * @memberof Fixtures - * @summary Create a new fixture based off an example payment package method - * @example example = Factory.create("examplePaymentPackage"); - * @property {String} name - `"example-paymentmethod"` - * @property {String} icon - `"fa fa-credit-card-alt"` - * @property {String} shopId - `getShopId()` - * @property {Boolean} enabled - `true` - * @property {Object} settings - Object - * @property {Boolean} settings.mode - `false` - * @property {String} settings.apikey - `""` - * @property {Array} registry - `[]` - * @property {Object} layout - `null` - * @returns {undefined} - */ -export function examplePaymentMethod() { - const examplePaymentMethodPackage = { - name: "example-paymentmethod", - icon: "fa fa-credit-card-alt", - shopId: getShopId(), - enabled: true, - settings: { - mode: false, - apikey: "" - }, - registry: [], - layout: null - }; - - Factory.define("examplePaymentPackage", Packages, Object.assign({}, examplePaymentMethodPackage)); -} - -/** - * @name examplePackage - * @memberof Fixtures - * @summary Create a new fixture based off of the Packages collection. - * @since 1.5.5 - * @property {String} name `"example-package"` - * @property {Object} settings - * @property {Boolean} settings.enabled `false` - * @property {String} settings.apiUrl `http://example.com/api` - * @property {String} shopId `"random-shop-id"` - * @returns {undefined} - */ -export function examplePackage() { - const examplePkg = { - name: "example-package", - settings: { - enabled: false, - apiUrl: "http://example.com/api" - }, - shopId: "random-shop-101" - }; - - Factory.define("examplePackage", Packages, examplePkg); -} diff --git a/imports/plugins/core/core/server/fixtures/products.js b/imports/plugins/core/core/server/fixtures/products.js deleted file mode 100755 index c12a9429e8b..00000000000 --- a/imports/plugins/core/core/server/fixtures/products.js +++ /dev/null @@ -1,228 +0,0 @@ -import faker from "faker"; -import _ from "lodash"; -import { Factory } from "meteor/dburles:factory"; -import { Products, Tags } from "/lib/collections"; -import getSlug from "../Reaction/getSlug"; -import { getShop } from "./shops"; - -/** - * @method metaField - * @memberof Fixtures - * @param {Object} [options] - options object to override generated default values - * @param {String} [options.key] - metaField key - * @param {String} [options.value] - metaField value - * @param {String} [options.scope] - metaField scope - * @returns {Object} - randomly generated metaField - */ -export function metaField(options = {}) { - const defaults = { - key: faker.commerce.productAdjective(), - value: faker.commerce.productMaterial(), - scope: "detail" - }; - return _.defaults(options, defaults); -} - -/** - * @method productVariant - * @memberof Fixtures - * @param {Object} [options] - Options object - * @param {String} [options._id] - id - * @param {String} [options.parentId] - variant's parent's ID. Sets variant as child. - * @param {String} [options.compareAtPrice] - MSRP Price / Compare At Price - * @param {String} [options.weight] - productVariant weight - * @param {String} [options.price] - productVariant price - * @param {String} [options.title] - productVariant title - * @param {String} [options.optionTitle] - productVariant option title - * @param {String} [options.sku] - productVariant sku - * @param {Object[]} [options.metafields] - productVariant metaFields - * - * @returns {Object} - randomly generated productVariant - */ -export function productVariant(options = {}) { - const defaults = { - ancestors: [], - attributeLabel: "Variant", - compareAtPrice: _.random(0, 1000), - weight: _.random(0, 10), - isTaxable: faker.random.boolean(), - isVisible: true, - price: _.random(10, 1000), - title: faker.commerce.productName(), - optionTitle: faker.commerce.productName(), - shopId: getShop()._id, - sku: _.random(0, 6), - type: "variant", - metafields: [ - metaField(), - metaField({ - key: "facebook", - scope: "socialMessages" - }), - metaField({ - key: "twitter", - scope: "socialMessages" - }) - ] - }; - return _.defaults(options, defaults); -} - -/** - * @method addProduct - * @summary Create a product with variants - * @memberof Fixtures - * @param {Object} [options={}] [description] - * @param {String} [options._id] - id - * @param {String} [options.parentId] - variant's parent's ID. Sets variant as child. - * @param {String} [options.compareAtPrice] - MSRP Price / Compare At Price - * @param {String} [options.weight] - productVariant weight - * @param {String} [options.price] - productVariant price - * @param {String} [options.title] - productVariant title - * @param {String} [options.optionTitle] - productVariant option title - * @param {String} [options.sku] - productVariant sku - * @param {Object[]} [options.metafields] - productVariant metaFields - * @returns {Object} Product - */ -export function addProduct(options = {}) { - const product = Factory.create("product", options); - // top level variant - const variant = Factory.create("variant", Object.assign({}, productVariant(options), { ancestors: [product._id] })); - Factory.create("variant", Object.assign({}, productVariant(options), { ancestors: [product._id, variant._id] })); - Factory.create("variant", Object.assign({}, productVariant(options), { ancestors: [product._id, variant._id] })); - return product; -} - -/** - * @method addProductSingleVariant - * @summary Create a product with 1 variant - * @memberof Fixtures - * @param {Object} [options={}] Product variant options object - * @returns {Object} Product with Variant - */ -export function addProductSingleVariant() { - const product = Factory.create("product"); - // top level variant - const variant = Factory.create("variant", Object.assign({}, productVariant(), { ancestors: [product._id] })); - return { product, variant }; -} - -/** - * @method getProduct - * @summary Get a product - * @memberof Fixtures - * @param {Object} [options={}] Product variant options object - * @returns {Object} Product - */ -export function getProduct() { - const existingProduct = Products.findOne(); - return existingProduct || Factory.create("product"); -} - -/** - * @method getProducts - * @summary Get a number of products - * @memberof Fixtures - * @param {Object} [limit=2] Number of products - * @returns {Array} Array of products - */ -export function getProducts(limit = 2) { - const products = []; - const existingProducts = Products.find({}, { limit }).fetch(); - for (let inc = 0; inc < limit; inc += 1) { - const product = existingProducts[inc] || Factory.create("product"); - products.push(product); - } - return products; -} - -/** - * @returns {undefined} undefined - */ -export default function () { - /** - * @name tag - * @memberof Fixtures - * @example Factory.create("tag") - * @summary Define a Tag for Products - * @property {String} name - `"Tag"` - * @property {String} slug - `"tag"` - * @property {Number} position - `_.random(0, 100000)` - * @property {Boolean} isVisible - `true` - * @property {Boolean} isTopLevel - `true` - * @property {String} shopId - `getShop()._id` - * @property {Date} createdAt - `faker.date.past()` - * @property {Date} updatedAt - `new Date()` - */ - Factory.define("tag", Tags, { - name: "Tag", - slug: "tag", - position: _.random(0, 100000), - // relatedTagIds: [], - isVisible: true, - isTopLevel: true, - shopId: getShop()._id, - createdAt: faker.date.past(), - updatedAt: new Date() - }); - - /** - * @name Product - * @memberof Fixtures - * @example const product = Factory.create("product") - * @example Factory.create("variant", Object.assign({}, productVariant(options), { ancestors: [product._id, variant._id] })); - * @summary Define a factory for Product - * @property {Array} ancestors `[]` - * @property {String} shopId `getShop()._id` - * @property {String} title `faker.commerce.productName()` - * @property {String} pageTitle `faker.lorem.sentence()` - * @property {String} description `faker.lorem.paragraph()` - * @property {String} type `"simple"` or `"variant"` for Product Variant - * @property {String} vendor `faker.company.companyName()` - * @property {Object} price `priceRange` - * @property {String} price.range `"1.00 - 12.99"` - * @property {Number} price.min `1.00` - * @property {Number} price.max `12.9` - * @property {Array} metafields `[]` - * @property {String[]} supportedFulfillmentTypes - ["shipping"] - * @property {Array} hashtags `[]` - * @property {Boolean} isVisible `true` - * @property {Date} publishedAt `new Date()` - * @property {Date} createdAt `new Date()` - * @property {Date} updatedAt `new Date()` - */ - const base = { - ancestors: [], - shopId: () => getShop()._id - }; - - const priceRange = { - range: "1.00 - 12.99", - min: 1.00, - max: 12.99 - }; - - const productTitle = faker.commerce.productName(); - - const product = { - title: productTitle, - pageTitle: faker.lorem.sentence(), - description: faker.lorem.paragraph(), - handle: getSlug(productTitle), - type: "simple", - vendor: faker.company.companyName(), - price: priceRange, - metafields: [], - supportedFulfillmentTypes: ["shipping"], - hashtags: [], - isVisible: true, - publishedAt: new Date(), - createdAt: new Date(), - updatedAt: new Date() - }; - - Factory.define("product", Products, Object.assign({}, base, product)); - Factory.define("variant", Products, { - type: "variant" - }); -} diff --git a/imports/plugins/core/core/server/fixtures/shops.js b/imports/plugins/core/core/server/fixtures/shops.js deleted file mode 100755 index d3dd06c373c..00000000000 --- a/imports/plugins/core/core/server/fixtures/shops.js +++ /dev/null @@ -1,326 +0,0 @@ -import faker from "faker"; -import _ from "lodash"; -import Random from "@reactioncommerce/random"; -import { Factory } from "meteor/dburles:factory"; -import { Shops } from "/lib/collections"; - -/** - * @method getShop - * @memberof Fixtures - * @summary Get an existing shop or create a shop factory - * @returns {Object} Shop - */ -export function getShop() { - createShopFactory(); - const existingShop = Shops.findOne(); - return existingShop || Factory.create("shop"); -} - -/** - * @method getShopId - * @memberof Fixtures - * @summary Get the first shop found and return the shop id - * @returns {String} Shop ID - */ -export function getShopId() { - const shop = Shops.find({}).fetch()[0]; - return shop && shop._id; -} - -/** - * @method getAddress - * @memberof Fixtures - * @summary Get an address, supplying options (optional) - * @param {Object} [options={}] Address options, optional - * @param {String} [options.fullName] fullName - `faker.name.findName()` - * @param {String} [options.address1] address1 - `faker.address.streetAddress()` - * @param {String} [options.address2] address2 - `faker.address.secondaryAddress()` - * @param {String} [options.city] city - `faker.address.city()` - * @param {String} [options.company] company - `faker.company.companyName()` - * @param {String} [options.phone] phone - `faker.phone.phoneNumber()` - * @param {String} [options.region] region - `faker.address.stateAbbr()` - * @param {String} [options.postal] postal - `faker.address.zipCode()` - * @param {String} [options.country] country - `faker.address.countryCode()` - * @param {String} [options.isCommercial] isCommercial - `faker.random.boolean()` - * @param {Boolean} [options.isShippingDefault] isShippingDefault - `faker.random.boolean()` - * @param {Boolean} [options.isBillingDefault] isBillingDefault - `faker.random.boolean()` - * @param {Array} [options.metafields] metafields - `[]` - * @returns {Object} Address object - */ -export function getAddress(options = {}) { - const defaults = { - fullName: faker.name.findName(), - address1: faker.address.streetAddress(), - address2: faker.address.secondaryAddress(), - city: faker.address.city(), - company: faker.company.companyName(), - phone: faker.phone.phoneNumber(), - region: faker.address.stateAbbr(), - postal: faker.address.zipCode(), - country: faker.address.countryCode(), - isCommercial: faker.random.boolean(), - isShippingDefault: faker.random.boolean(), - isBillingDefault: faker.random.boolean(), - metafields: [] - }; - return _.defaults(options, defaults); -} - -const shop = { - name: () => faker.internet.domainName(), - description: faker.company.catchPhrase(), - keywords: faker.company.bsAdjective(), - addressBook: [getAddress()], - domains: ["localhost"], - emails: [ - { - address: faker.internet.email(), - verified: faker.random.boolean() - } - ], - currency: "USD", // could use faker.finance.currencyCode() - currencies: { - USD: { - format: "%s%v", - symbol: "$" - }, - EUR: { - format: "%v %s", - symbol: "€", - decimal: ",", - thousand: "." - } - }, - locale: "en", - locales: { - continents: { - NA: "North America" - }, - countries: { - US: { - name: "United States", - native: "United States", - phone: "1", - continent: "NA", - capital: "Washington D.C.", - currency: "USD,USN,USS", - languages: "en" - } - } - }, - baseUOL: "in", - unitsOfLength: [{ - uol: "in", - label: "Inches", - default: true - }, { - uol: "cm", - label: "Centimeters" - }, { - uol: "ft", - label: "Feet" - }], - baseUOM: "oz", - unitsOfMeasure: [{ - uom: "oz", - label: "Ounces", - default: true - }, { - uom: "lb", - label: "Pounds" - }, { - uom: "g", - label: "Grams" - }, { - uom: "kg", - label: "Kilograms" - }], - defaultParcelSize: { - weight: () => faker.random.number(), - length: () => faker.random.number(), - width: () => faker.random.number(), - height: () => faker.random.number() - }, - layout: [{ - layout: "coreLayout", - workflow: "coreLayout", - theme: "default", - enabled: true - }, { - layout: "coreLayout", - workflow: "coreCartWorkflow", - collection: "Cart", - theme: "default", - enabled: true - }, { - layout: "coreLayout", - workflow: "coreOrderWorkflow", - collection: "Orders", - theme: "default", - enabled: true - }, { - layout: "coreLayout", - workflow: "coreOrderShipmentWorkflow", - collection: "Orders", - theme: "default", - enabled: true - }], - workflow: { - status: "new" - }, - public: true, - brandAssets: [ - { - mediaId: "J8Bhq3uTtdgwZx3rz", - type: "navbarBrandImage" - } - ], - timezone: "US/Pacific", - metafields: [], - shopType: "primary", - createdAt: new Date(), - updatedAt: new Date() -}; - -const activeShop = { - workflow: { - status: "active" - }, - _id: Random.id() -}; - -/** - * @method createActiveShop - * @memberof Fixtures - * @summary Find and return an existing shop from option parameters, or create an active shop factory - * @param {Object} [options={}] Any shop properties - * @returns {Object} Shop, with active status - */ -export function createActiveShop(options = {}) { - const existingActiveShop = Shops.findOne({ "workflow.status": "active", ...options }); - - // If we found an existingActiveShop, return it - if (existingActiveShop) { - return existingActiveShop; - } - // Otherwise, we need to create a new shop from the factory - - // Setup the activeShop factory definition - createActiveShopFactory(); - - // Create a new shop from the factory with the provided options - return Factory.create("activeShop", options); -} - -/** - * @method createShopFactory - * @memberof Fixtures - * @summary Create Shop factory. Shop name should be unique for the slug to be unique. - * @property {String} name - `faker.internet.domainName()` - * @property {String} description - `faker.company.catchPhrase()` - * @property {String} keywords - `faker.company.bsAdjective()` - * @property {Array} addressBook - `[getAddress()]` - * @property {Array} domains - `["localhost"]` - * @property {Array} emails - `[]` - * @property {String} emails.address - `faker.internet.email()` - * @property {Boolean} emails.verified - `faker.random.boolean()` - * @property {String} currency - `"USD"` - Could use faker.finance.currencyCode() - * @property {Object} currencies - `{}` - * @property {Object} currencies.USD - `{}` - * @property {String} currencies.USD.format - `"%s%v"` - * @property {String} currencies.USD.symbol - `"$"` - * @property {Object} currencies.EUR - `{}` - * @property {String} currencies.EUR.format - `"%v %s"` - * @property {String} currencies.EUR.symbol - `"€"` - * @property {String} currencies.EUR.decimal - `","` - * @property {String} currencies.EUR.thousand - `"."` - * @property {String} locale - `"en"` - * @property {Object} locales - `{}` - * @property {Object} locales.continents - `{}` - * @property {String} locales.continents.NA - `"North America"` - * @property {Object} locales.countries - `{}` - * @property {Object} locales.countries.US - `{}` - * @property {String} locales.countries.name - `"United States"` - * @property {String} locales.countries.native - `"United States"` - * @property {String} locales.countries.phone - `"1"` - * @property {String} locales.countries.continent - `"NA"` - * @property {String} locales.countries.capital - `"Washington D.C."` - * @property {String} locales.countries.currency - `"USD,USN,USS"` - * @property {String} locales.countries.languages - `"en"` - * @property {String} baseUOL - `"in"` - * @property {Array} unitsOfLength - `[{}]` - * @property {String} unitsOfLength.uol - `"in"` - * @property {String} unitsOfLength.label - `"Inches"` - * @property {String} unitsOfLength.default - `true` - * @property {String} unitsOfLength.uol - `"cm"` - * @property {String} unitsOfLength.label - `"Centimeters"` - * @property {String} unitsOfLength.uol - `"ft"` - * @property {String} unitsOfLength.label - `"Feet"` - * @property {String} baseUOM - `"oz"` - * @property {Array} unitsOfMeasure - `[{}]` - * @property {String} unitsOfMeasure.uom - `"oz"` - * @property {String} unitsOfMeasure.label - `"Ounces"` - * @property {String} unitsOfMeasure.default - `true` - * @property {String} unitsOfMeasure.uom - `"lb"` - * @property {String} unitsOfMeasure.label - `"Pounds"` - * @property {String} unitsOfMeasure.uom - `"g"` - * @property {String} unitsOfMeasure.label - `"Grams"` - * @property {String} unitsOfMeasure.uom - `"kg"` - * @property {String} unitsOfMeasure.label - `"Kilograms"` - * @property {Array} layout - `[{}]` - * @property {String} layout - `"coreLayout"` - * @property {String} workflow - `"coreLayout"` - * @property {String} theme - `"default"` - * @property {Boolean} enabled - `true` - * @property {String} layout - `"coreLayout"` - * @property {String} workflow - `"coreCartWorkflow"` - * @property {String} collection - `"Cart"` - * @property {String} theme - `"default"` - * @property {Boolean} enabled - `true` - * @property {String} layout - `"coreLayout"` - * @property {String} workflow - `"coreOrderWorkflow"` - * @property {String} collection - `"Orders"` - * @property {String} theme - `"default"` - * @property {Boolean} enabled - `true` - * @property {String} layout - `"coreLayout"` - * @property {String} workflow - `"coreOrderShipmentWorkflow"` - * @property {String} collection - `"Orders"` - * @property {String} theme - `"default"` - * @property {Boolean} enabled - `true` - * @property {Object} workflow - `{}` - * @property {String} workflow.status - `"active"` - * @property {Boolean} public - `true` - * @property {Array} brandAssets - `[]` - * @property {String} mediaId - `"J8Bhq3uTtdgwZx3rz"` - * @property {String} type - `"navbarBrandImage"` - * @property {String} timezone - `"US/Pacific"` - * @property {Array} metafields - `[]` - * @property {String} shopType - `"primary"` - Not having a primary shop will cause test failures. one shop in the marketplace is required as default shop. This is used to control marketplace settings. - * @property {Date} createdAt - `new Date()` - * @property {Date} updatedAt - `new Date()` - * @returns {Object} Shop with status `"active"` - */ -export function createShopFactory() { - Factory.define("shop", Shops, shop); -} - -/** - * @name createActiveShopFactory - * @memberof Fixtures - * @summary Returns an active shop factory - * @property {Object} workflow - * @property {String} status - `"active"` - * @property {String} id - `Random.id()` - * @returns {Object} Shop with status `"active"` - */ -export function createActiveShopFactory() { - Factory.define("activeShop", Shops, Object.assign({}, shop, activeShop)); -} - -/** - * @returns {undefined} - */ -export default function () { - createShopFactory(); - createActiveShopFactory(); -} diff --git a/imports/plugins/core/core/server/fixtures/users.js b/imports/plugins/core/core/server/fixtures/users.js deleted file mode 100755 index 4eea34856b6..00000000000 --- a/imports/plugins/core/core/server/fixtures/users.js +++ /dev/null @@ -1,164 +0,0 @@ -import faker from "faker"; -import _ from "lodash"; -import Random from "@reactioncommerce/random"; -import { Meteor } from "meteor/meteor"; -import { Factory } from "meteor/dburles:factory"; -import { getShop } from "./shops"; - -/** - * @method getUser - * @memberof Fixtures - * @returns {Object} Existing user or Factory user - */ -export function getUser() { - const existingUser = Meteor.users.findOne(); - return existingUser || Factory.create("user"); -} - -/** - * @method getUsers - * @memberof Fixtures - * @param {Number} limit Default set to 2 - * @returns {Array} Array of existing users or Factory user - */ -export function getUsers(limit = 2) { - const users = []; - const existingUsers = Meteor.users.find({}, { limit }).fetch(); - for (let inc = 0; inc < limit; inc += 1) { - const user = existingUsers[inc] || Factory.create("user"); - users.push(user); - } - return users; -} - -/** - * @name user - * @memberof Fixtures - * @summary Define user Factory - * @example const user1 = Factory.create("user"); - * @description Types of User factories - * - `user` - A user - * - `registeredUser` - A user with a password, loginTokens and roles: `account/profile, guest, product, tag, index, cart/completed` - * - `anonymous` - A user without an account with rules: `guest, anonymous, product, tag, index, cart/completed` - * @property {String} username - `faker.internet.userName() + _.random(0, 1000)` - * @property {String} name - `faker.name.findName()` - * @property {Array} emails - `[{address: faker.internet.email(), verified: true}]` - * @property {Object} profile - `{ - name: this.name, - email: faker.internet.email(), - profilePictureUrl: faker.image.imageUrl() - }` - * @property {String} gender - String: `"Male", "Female", "Either"` - * @property {String} description - `faker.lorem.paragraphs(3)` - * @property {Date} startTime - `calculatedStartTime` - * @property {Date} createdAt - `new Date()` - * @property {Object} roles - `{shopId: ["guest", "anonymous", "product"]}` - */ -const user = { - username() { - return faker.internet.userName() + _.random(0, 1000); - }, - - name() { - return faker.name.findName(); - }, - - emails() { - const email = faker.internet.email(); - return [{ - address: email, - verified: true - }]; - }, - - profile() { - return { - name: this.name, - email: faker.internet.email(), - profilePictureUrl: faker.image.imageUrl() - }; - }, - - gender() { - return ["Either", "Male", "Female"][_.random(0, 2)]; - }, - - description() { - return faker.lorem.paragraphs(3); - }, - - startTime() { - const numDaysToAdd = Math.floor(Math.random() * 32); // random number of days between 0 and 31 - const numHoursToAdd = Math.floor(Math.random() * 25); // random number of hours between 0 and 24 - const secondsInDay = 24 * 60 * 60 * 1000; - const secondsInHour = 24 * 60 * 60 * 1000; - - const calculatedStartTime = Date.now() + (numDaysToAdd * secondsInDay) + (numHoursToAdd + secondsInHour); - - return new Date(calculatedStartTime); - }, - - createdAt: new Date() -}; - -/** - * @summary Users factory setup - * @returns {undefined} - */ -export default function () { - const numDaysToAdd = Math.floor(Math.random() * 32); // random number of days between 0 and 31 - const numHoursToAdd = Math.floor(Math.random() * 25); // random number of hours between 0 and 24 - const secondsInDay = 24 * 60 * 60 * 1000; - const secondsInHour = 24 * 60 * 60 * 1000; - - const timeOffset = Date.now() + (numDaysToAdd * secondsInDay) + (numHoursToAdd + secondsInHour); - - const shop = getShop(); - - const registered = { - roles: { - [shop._id]: [ - "account/profile", - "guest", - "product", - "tag", - "index", - "cart/completed" - ] - }, - services: { - password: { - bcrypt: Random.id(29) - }, - resume: { - loginTokens: [ - { - when: timeOffset - } - ] - } - } - }; - - - Factory.define("user", Meteor.users, user); - Factory.define( - "registeredUser", Meteor.users, - Object.assign({}, user, registered) - ); - - const anonymous = { - roles: { - [shop._id]: [ - "guest", - "anonymous", - "product", - "tag", - "index", - "cart/completed" - ] - } - }; - - Factory.define("anonymous", Meteor.users, Object.assign({}, user, anonymous)); -} diff --git a/imports/plugins/core/core/server/methods/shop/getLocale.js b/imports/plugins/core/core/server/methods/shop/getLocale.js deleted file mode 100644 index 9dde54cc87c..00000000000 --- a/imports/plugins/core/core/server/methods/shop/getLocale.js +++ /dev/null @@ -1,125 +0,0 @@ -import _ from "lodash"; -import Logger from "@reactioncommerce/logger"; -import { Accounts, Shops } from "/lib/collections"; -import getGraphQLContextInMeteorMethod from "/imports/plugins/core/graphql/server/getGraphQLContextInMeteorMethod"; -import { Reaction } from "/lib/api"; -import ReactionError from "@reactioncommerce/reaction-error"; -import GeoCoder from "../../util/geocoder"; - -/** - * @name shop/getLocale - * @method - * @memberof Shop/Methods - * @summary determine user's countryCode and return locale object - * determine local currency and conversion rate from shop currency - * @returns {Object} returns user location and locale - */ -export default function getLocale() { - this.unblock(); - let clientAddress; - const result = {}; - let defaultCountryCode = "US"; - let localeCurrency = "USD"; - // if called from server, ip won't be defined. - if (this.connection !== null) { - ({ clientAddress } = this.connection); - } else { - clientAddress = "127.0.0.1"; - } - - // get shop locale/currency related data - const shop = Shops.findOne(Reaction.getShopId(), { - fields: { - addressBook: 1, - allowCustomUserLocale: 1, - locales: 1, - currencies: 1, - currency: 1 - } - }); - - if (!shop) { - throw new ReactionError("not-found", "Failed to find shop data. Unable to determine locale."); - } - // configure default defaultCountryCode - // fallback to shop settings - if (shop.addressBook) { - if (shop.addressBook.length >= 1) { - if (shop.addressBook[0].country) { - defaultCountryCode = shop.addressBook[0].country; - } - } - } - - // If custom user locales are allowed, - // geocode reverse ip lookup - let geoCountryCode; - if (shop && shop.allowCustomUserLocale === true) { - const geo = new GeoCoder(); - geoCountryCode = geo.geoip(clientAddress).country_code; - } - - // countryCode either from geo or defaults - const countryCode = (geoCountryCode || defaultCountryCode).toUpperCase(); - - // get currency rates - result.currency = {}; - result.locale = shop.locales.countries[countryCode]; - - // to return default currency if rates will failed, we need to bring access - // to this data - result.shopCurrency = shop.currencies[shop.currency]; - - // check if locale has a currency defined - if (typeof result.locale === "object" && - typeof result.locale.currency === "string") { - localeCurrency = result.locale.currency.split(","); - } - - // localeCurrency is an array of allowed currencies - _.each(localeCurrency, (currency) => { - if (shop.currencies[currency]) { - result.currency = shop.currencies[currency]; - // only fetch rates if locale and shop currency are not equal - // if shop.currency = locale currency the rate is 1 - if (shop.currency !== currency) { - const settings = Reaction.getShopSettings(); - const exchangeConfig = settings.openexchangerates || {}; - - if (exchangeConfig.appId) { - if (typeof result.currency.rate === "number") { - result.currency.exchangeRate = result.currency.rate; - } else { - Logger.warn("Failed to get currency exchange rates."); - } - } - } - } - }); - - // adjust user currency - const account = Accounts.findOne({ userId: Reaction.getUserId() }); - let profileCurrency = account && account.profile && account.profile.currency; - if (account && !profileCurrency) { - [localeCurrency] = localeCurrency; - if (shop.currencies[localeCurrency] && shop.currencies[localeCurrency].enabled) { - profileCurrency = localeCurrency; - } else { - [profileCurrency] = shop.currency.split(","); - } - - const userId = Reaction.getUserId(); - const context = Promise.await(getGraphQLContextInMeteorMethod(userId)); - - Promise.await(context.mutations.setAccountProfileCurrency(context, { - profileCurrency, - userId - })); - } - - // set server side locale - Reaction.Locale = result; - - // should contain rates, locale, currency - return result; -} diff --git a/imports/plugins/core/core/server/methods/shop/index.js b/imports/plugins/core/core/server/methods/shop/index.js index 9655fd22657..06c5f3dd434 100644 --- a/imports/plugins/core/core/server/methods/shop/index.js +++ b/imports/plugins/core/core/server/methods/shop/index.js @@ -1,6 +1,5 @@ import createShop from "./createShop"; import createTag from "./createTag"; -import getLocale from "./getLocale"; import locateAddress from "./locateAddress"; import togglePackage from "./togglePackage"; import updateBrandAssets from "./updateBrandAssets"; @@ -20,7 +19,6 @@ import updateShopExternalServices from "./updateShopExternalServices"; export default { "shop/createShop": createShop, "shop/createTag": createTag, - "shop/getLocale": getLocale, "shop/locateAddress": locateAddress, "shop/togglePackage": togglePackage, "shop/updateBrandAssets": updateBrandAssets, diff --git a/imports/plugins/core/core/server/methods/shop/updateCurrencyConfiguration.js b/imports/plugins/core/core/server/methods/shop/updateCurrencyConfiguration.js index a71671e9257..92c29d27c32 100644 --- a/imports/plugins/core/core/server/methods/shop/updateCurrencyConfiguration.js +++ b/imports/plugins/core/core/server/methods/shop/updateCurrencyConfiguration.js @@ -22,12 +22,18 @@ export default function updateCurrencyConfiguration(currency, enabled) { } this.unblock(); + const shopId = Reaction.getShopId(); + const shop = Shops.findOne({ - _id: Reaction.getShopId() + _id: shopId }); const defaultCurrency = shop.currency; + if (currency === defaultCurrency && !enabled) { + throw new ReactionError("invalid-param", "Cannot disable the shop default currency"); + } + if (currency === "all") { const updateObject = {}; for (const currencyName in shop.currencies) { @@ -41,22 +47,14 @@ export default function updateCurrencyConfiguration(currency, enabled) { } return Shops.update({ - _id: Reaction.getShopId() + _id: shopId }, { $set: updateObject }); - } else if (currency === defaultCurrency) { - return Shops.update({ - _id: Reaction.getShopId() - }, { - $set: { - [`currencies.${currency}.enabled`]: true - } - }); } return Shops.update({ - _id: Reaction.getShopId() + _id: shopId }, { $set: { [`currencies.${currency}.enabled`]: enabled diff --git a/imports/plugins/core/core/server/methods/shop/updateLanguageConfiguration.js b/imports/plugins/core/core/server/methods/shop/updateLanguageConfiguration.js index 031a84ba5af..2a335a2d433 100644 --- a/imports/plugins/core/core/server/methods/shop/updateLanguageConfiguration.js +++ b/imports/plugins/core/core/server/methods/shop/updateLanguageConfiguration.js @@ -22,12 +22,16 @@ export default function updateLanguageConfiguration(language, enabled) { } this.unblock(); - const shop = Shops.findOne({ - _id: Reaction.getShopId() - }); + const shopId = Reaction.getShopId(); + + const shop = Shops.findOne({ _id: shopId }); const defaultLanguage = shop.language; + if (language === defaultLanguage && !enabled) { + throw new ReactionError("invalid-param", "Cannot disable the shop default language"); + } + if (language === "all") { const updateObject = {}; @@ -40,24 +44,16 @@ export default function updateLanguageConfiguration(language, enabled) { } }); } + return Shops.update({ - _id: Reaction.getShopId() + _id: shopId }, { $set: updateObject }); - } else if (language === defaultLanguage) { - return Shops.update({ - "_id": Reaction.getShopId(), - "languages.i18n": language - }, { - $set: { - "languages.$.enabled": true - } - }); } return Shops.update({ - "_id": Reaction.getShopId(), + "_id": shopId, "languages.i18n": language }, { $set: { diff --git a/private/data/i18n/ar.json b/imports/plugins/core/core/server/no-meteor/i18n/ar.json similarity index 100% rename from private/data/i18n/ar.json rename to imports/plugins/core/core/server/no-meteor/i18n/ar.json diff --git a/private/data/i18n/bg.json b/imports/plugins/core/core/server/no-meteor/i18n/bg.json similarity index 100% rename from private/data/i18n/bg.json rename to imports/plugins/core/core/server/no-meteor/i18n/bg.json diff --git a/private/data/i18n/cs.json b/imports/plugins/core/core/server/no-meteor/i18n/cs.json similarity index 100% rename from private/data/i18n/cs.json rename to imports/plugins/core/core/server/no-meteor/i18n/cs.json diff --git a/private/data/i18n/de.json b/imports/plugins/core/core/server/no-meteor/i18n/de.json similarity index 100% rename from private/data/i18n/de.json rename to imports/plugins/core/core/server/no-meteor/i18n/de.json diff --git a/private/data/i18n/el.json b/imports/plugins/core/core/server/no-meteor/i18n/el.json similarity index 100% rename from private/data/i18n/el.json rename to imports/plugins/core/core/server/no-meteor/i18n/el.json diff --git a/private/data/i18n/en.json b/imports/plugins/core/core/server/no-meteor/i18n/en.json similarity index 100% rename from private/data/i18n/en.json rename to imports/plugins/core/core/server/no-meteor/i18n/en.json diff --git a/private/data/i18n/es.json b/imports/plugins/core/core/server/no-meteor/i18n/es.json similarity index 100% rename from private/data/i18n/es.json rename to imports/plugins/core/core/server/no-meteor/i18n/es.json diff --git a/private/data/i18n/fr.json b/imports/plugins/core/core/server/no-meteor/i18n/fr.json similarity index 100% rename from private/data/i18n/fr.json rename to imports/plugins/core/core/server/no-meteor/i18n/fr.json diff --git a/private/data/i18n/he.json b/imports/plugins/core/core/server/no-meteor/i18n/he.json similarity index 100% rename from private/data/i18n/he.json rename to imports/plugins/core/core/server/no-meteor/i18n/he.json diff --git a/private/data/i18n/hr.json b/imports/plugins/core/core/server/no-meteor/i18n/hr.json similarity index 100% rename from private/data/i18n/hr.json rename to imports/plugins/core/core/server/no-meteor/i18n/hr.json diff --git a/private/data/i18n/hu.json b/imports/plugins/core/core/server/no-meteor/i18n/hu.json similarity index 100% rename from private/data/i18n/hu.json rename to imports/plugins/core/core/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/catalog/server/i18n/index.js b/imports/plugins/core/core/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/core/catalog/server/i18n/index.js rename to imports/plugins/core/core/server/no-meteor/i18n/index.js index 2d1a40cefec..9deb0a6b6e7 100644 --- a/imports/plugins/core/catalog/server/i18n/index.js +++ b/imports/plugins/core/core/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; import de from "./de.json"; @@ -28,4 +26,29 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/private/data/i18n/it.json b/imports/plugins/core/core/server/no-meteor/i18n/it.json similarity index 100% rename from private/data/i18n/it.json rename to imports/plugins/core/core/server/no-meteor/i18n/it.json diff --git a/private/data/i18n/my.json b/imports/plugins/core/core/server/no-meteor/i18n/my.json similarity index 100% rename from private/data/i18n/my.json rename to imports/plugins/core/core/server/no-meteor/i18n/my.json diff --git a/private/data/i18n/nb.json b/imports/plugins/core/core/server/no-meteor/i18n/nb.json similarity index 100% rename from private/data/i18n/nb.json rename to imports/plugins/core/core/server/no-meteor/i18n/nb.json diff --git a/private/data/i18n/nl.json b/imports/plugins/core/core/server/no-meteor/i18n/nl.json similarity index 100% rename from private/data/i18n/nl.json rename to imports/plugins/core/core/server/no-meteor/i18n/nl.json diff --git a/private/data/i18n/pl.json b/imports/plugins/core/core/server/no-meteor/i18n/pl.json similarity index 100% rename from private/data/i18n/pl.json rename to imports/plugins/core/core/server/no-meteor/i18n/pl.json diff --git a/private/data/i18n/pt.json b/imports/plugins/core/core/server/no-meteor/i18n/pt.json similarity index 100% rename from private/data/i18n/pt.json rename to imports/plugins/core/core/server/no-meteor/i18n/pt.json diff --git a/private/data/i18n/ro.json b/imports/plugins/core/core/server/no-meteor/i18n/ro.json similarity index 100% rename from private/data/i18n/ro.json rename to imports/plugins/core/core/server/no-meteor/i18n/ro.json diff --git a/private/data/i18n/ru.json b/imports/plugins/core/core/server/no-meteor/i18n/ru.json similarity index 100% rename from private/data/i18n/ru.json rename to imports/plugins/core/core/server/no-meteor/i18n/ru.json diff --git a/private/data/i18n/sl.json b/imports/plugins/core/core/server/no-meteor/i18n/sl.json similarity index 100% rename from private/data/i18n/sl.json rename to imports/plugins/core/core/server/no-meteor/i18n/sl.json diff --git a/private/data/i18n/sv.json b/imports/plugins/core/core/server/no-meteor/i18n/sv.json similarity index 100% rename from private/data/i18n/sv.json rename to imports/plugins/core/core/server/no-meteor/i18n/sv.json diff --git a/private/data/i18n/tr.json b/imports/plugins/core/core/server/no-meteor/i18n/tr.json similarity index 100% rename from private/data/i18n/tr.json rename to imports/plugins/core/core/server/no-meteor/i18n/tr.json diff --git a/private/data/i18n/vi.json b/imports/plugins/core/core/server/no-meteor/i18n/vi.json similarity index 100% rename from private/data/i18n/vi.json rename to imports/plugins/core/core/server/no-meteor/i18n/vi.json diff --git a/private/data/i18n/zh.json b/imports/plugins/core/core/server/no-meteor/i18n/zh.json similarity index 100% rename from private/data/i18n/zh.json rename to imports/plugins/core/core/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/core/server/no-meteor/register.js b/imports/plugins/core/core/server/no-meteor/register.js index 1395bdd7a1e..5f561295e90 100644 --- a/imports/plugins/core/core/server/no-meteor/register.js +++ b/imports/plugins/core/core/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import resolvers from "./resolvers"; import schemas from "./schemas"; import startup from "./startup"; @@ -12,6 +13,7 @@ export default async function register(app) { label: "Core", name: "core", icon: "fa fa-th", + i18n, collections: { Assets: { name: "Assets" diff --git a/imports/plugins/core/core/server/no-meteor/schemas/base.graphql b/imports/plugins/core/core/server/no-meteor/schemas/base.graphql index 6eacc4ff2ad..eab59a77429 100644 --- a/imports/plugins/core/core/server/no-meteor/schemas/base.graphql +++ b/imports/plugins/core/core/server/no-meteor/schemas/base.graphql @@ -115,7 +115,10 @@ type Rate { "Mutations have side effects, such as mutating data or triggering a task" type Mutation { "A test mutation that returns whatever string you send it" - echo(str: String): String + echo( + "Any string" + str: String + ): String } "Queries return all requested data, without any side effects" diff --git a/imports/plugins/core/core/server/no-meteor/schemas/shop.graphql b/imports/plugins/core/core/server/no-meteor/schemas/shop.graphql index d43f14c0c06..93a17ef2e6e 100644 --- a/imports/plugins/core/core/server/no-meteor/schemas/shop.graphql +++ b/imports/plugins/core/core/server/no-meteor/schemas/shop.graphql @@ -30,5 +30,8 @@ extend type Mutation { Given a person's email address and name, invite them to create an account for a certain shop, and put them in the provided permission group """ - inviteShopMember(input: InviteShopMemberInput!): InviteShopMemberPayload + inviteShopMember( + "Mutation input" + input: InviteShopMemberInput! + ): InviteShopMemberPayload } diff --git a/imports/plugins/core/core/server/no-meteor/schemas/tag.graphql b/imports/plugins/core/core/server/no-meteor/schemas/tag.graphql index 0f917032e2f..1872673a1f8 100644 --- a/imports/plugins/core/core/server/no-meteor/schemas/tag.graphql +++ b/imports/plugins/core/core/server/no-meteor/schemas/tag.graphql @@ -46,7 +46,25 @@ type Tag implements Node & Deletable { subTagIds: [ID]! "A paged list of tags that have this tag as their parent in the tag hierarchy. Currently only three levels are supported." - subTags(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: TagSortByField = position): TagConnection + subTags( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, tags are sorted by position. Set this to sort by one of the other allowed fields" + sortBy: TagSortByField = position + ): TagConnection "The date and time at which this tag was last updated" updatedAt: DateTime! @@ -131,10 +149,19 @@ extend type Query { "Set to true if you want to include tags that have isVisible set to false" shouldIncludeInvisible: Boolean = false, + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." last: ConnectionLimitInt, + + "Return results sorted in this order" sortOrder: SortOrder = asc, "By default, tags are sorted by position. Set this to sort by one of the other allowed fields" diff --git a/imports/plugins/core/core/server/publications/collections/shops.js b/imports/plugins/core/core/server/publications/collections/shops.js index 45a0f733ff2..a716c2e795d 100644 --- a/imports/plugins/core/core/server/publications/collections/shops.js +++ b/imports/plugins/core/core/server/publications/collections/shops.js @@ -1,71 +1,8 @@ import { Meteor } from "meteor/meteor"; -import { check } from "meteor/check"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; import { Shops } from "/lib/collections"; -// We should be able to publish just the enabled languages/currencies/ Meteor.publish("PrimaryShop", () => Shops.find({ shopType: "primary" }, { - fields: {}, limit: 1 })); - -Meteor.publish("MerchantShops", function (shopsOfUser = Reaction.getShopsForUser(["admin"], this.userId)) { - check(shopsOfUser, Array); - - // Check if user has permissions for those shops - if (Reaction.hasPermissionForAll(["admin"], this.userId, shopsOfUser)) { - throw new ReactionError("access-denied", "Shops requested don't belong to user"); - } - - const domain = Reaction.getDomain(); - const { enabled } = Reaction.getMarketplaceSettings(); - // Don't publish currencies, languages, or locales for merchant shops. - // We'll get that info from the primary shop. - const fields = { - languages: 0, - locales: 0, - currencies: 0 - }; - - if (Reaction.marketplaceCurrency) { - delete fields.currencies; - } - - if (Reaction.marketplaceLanguages) { - delete fields.languages; - } - - if (Reaction.marketplaceLocales) { - delete fields.locales; - } - - // If marketplace is disabled, don't return any merchant shops - if (!enabled) { - return this.ready(); - } - - - const selector = { - domains: domain, - shopType: { - $ne: "primary" - }, - $or: [ - { - _id: { - $in: shopsOfUser - } - }, - { - "workflow.status": "active" - } - ] - }; - - // Return all non-primary shops for this domain that belong to the user - // or are active - return Shops.find(selector, { fields }); -}); diff --git a/imports/plugins/core/core/server/publications/collections/translations.js b/imports/plugins/core/core/server/publications/collections/translations.js deleted file mode 100644 index e81163e1672..00000000000 --- a/imports/plugins/core/core/server/publications/collections/translations.js +++ /dev/null @@ -1,45 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import { check, Match } from "meteor/check"; -import { Shops, Translations } from "/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; - -/** -* @file Translations publication -* -* -* @module Translations -*/ - -/** - * Translations publication - * @param {String|Array} sessionLanguages - String or array of langauges. current sessionLanguage, default to 'en' - * @returns { Object } returns Translations - * @todo like to see the langages validated more with a schema - */ -Meteor.publish("Translations", (languages) => { - check(languages, Match.OneOf(String, Array)); - const shopId = Reaction.getShopId(); - const shopLanguage = Shops.findOne(shopId).language; - const sessionLanguages = []; - const langTranQuery = []; - - // set shop default - sessionLanguages.push(shopLanguage); - // lets get all these langauges - if (Array.isArray(languages)) { - sessionLanguages.concat(languages); - } else { - sessionLanguages.push(languages); - } - // add in the shop filter - for (const sessionLanguage of sessionLanguages) { - langTranQuery.push({ - i18n: sessionLanguage, - shopId: Reaction.getPrimaryShopId() - }); - } - - return Translations.find({ - $or: langTranQuery - }); -}); diff --git a/imports/plugins/core/core/server/publications/index.js b/imports/plugins/core/core/server/publications/index.js index bcff38e2a79..c00f205a191 100644 --- a/imports/plugins/core/core/server/publications/index.js +++ b/imports/plugins/core/core/server/publications/index.js @@ -13,6 +13,5 @@ import "./collections/shipping"; import "./collections/shops"; import "./collections/tags"; import "./collections/themes"; -import "./collections/translations"; import "./counts"; import "./email"; diff --git a/imports/plugins/core/core/server/startup/collection-security.js b/imports/plugins/core/core/server/startup/collection-security.js index 439338f8078..8bcae748aad 100644 --- a/imports/plugins/core/core/server/startup/collection-security.js +++ b/imports/plugins/core/core/server/startup/collection-security.js @@ -14,8 +14,7 @@ const { Shipping, Shops, Tags, - Templates, - Translations + Templates } = Collections; /** @@ -118,7 +117,7 @@ export default function () { */ Security.permit(["insert", "update", "remove"]) - .collections([Accounts, Products, Tags, Translations, Shipping, Orders, Packages, Templates, Jobs]) + .collections([Accounts, Products, Tags, Shipping, Orders, Packages, Templates, Jobs]) .ifHasRoleForActiveShop({ role: "admin" }) .ifShopIdMatches() .exceptProps(["shopId"]) diff --git a/imports/plugins/core/core/server/startup/i18n.js b/imports/plugins/core/core/server/startup/i18n.js index e9d2869d560..72298905e6d 100644 --- a/imports/plugins/core/core/server/startup/i18n.js +++ b/imports/plugins/core/core/server/startup/i18n.js @@ -1,219 +1,24 @@ -import fsModule from "fs"; -import path from "path"; -import util from "util"; -import Logger from "@reactioncommerce/logger"; -import { Assets, Translations } from "/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; - -const fs = { - readdir: util.promisify(fsModule.readdir), - readFile: util.promisify(fsModule.readFile), - realpath: util.promisify(fsModule.realpath), - stat: util.promisify(fsModule.stat) -}; - -const translationSources = []; -const rawAssetsCollection = Assets.rawCollection(); -let bulkAssetOp; - -/** - * @function directoryExists - * @param {String} dirPath directory path - * @returns {Boolean} isDirectory - */ -async function directoryExists(dirPath) { - let info; - - try { - info = await fs.stat(dirPath); - } catch (error) { - return false; - } - - return info.isDirectory(); -} - -/** - * @method loadTranslation - * @memberof i18n - * @summary Server method: Load a single translation object as an Asset - * loadTranslation should generally be used - * before startup, to ensure that Assets load. - * @param {Object} source a json i18next object - * @returns {Boolean} false if assets weren't loaded - */ -export function loadTranslation(source) { - try { - if (!bulkAssetOp) bulkAssetOp = rawAssetsCollection.initializeUnorderedBulkOp(); - const content = typeof source === "string" ? JSON.parse(source) : source; - const json = typeof source === "object" ? JSON.stringify(source) : source; - const { i18n, ns } = content[0]; - - // Keep a record of all available translations for import later at a later time if using the - // reload translations icon button from the Internationalization settings panel - translationSources.push(source); - - bulkAssetOp - .find({ type: "i18n", name: i18n, ns }) - .upsert() - .update({ $set: { content: json } }); - - Logger.debug("Translation assets bulk update prepared for ", ns); - } catch (error) { - Logger.error("Failed to prepare bulk upsert for translation assets", error); - } -} - -/** - * @method loadTranslations - * @memberof i18n - * @summary Load an array of translation objects and import using loadTranslation - * @param {Object} sources array of i18next translations - * @returns {Boolean} false if assets weren't loaded - */ -export function loadTranslations(sources) { - sources.forEach(loadTranslation); -} - -/** - * @method flushTranslationLoad - * @memberof i18n - * @summary Execute the bulk asset operation - * @returns {undefined} No return - */ -export async function flushTranslationLoad() { - if (!bulkAssetOp) return Promise.resolve(); - - try { - await bulkAssetOp.execute(); - bulkAssetOp = null; - } catch (error) { - Logger.error("Error flushing the translation asset upserts"); - } - - return Promise.resolve(); -} - /** - * @method loadCoreTranslations - * @memberof i18n - * @summary imports i18n json files from private/data/i18n into the Assets collection - * Assets collection is processed with Reaction.Import - * after all assets have been loaded. - * @async - * @returns {undefined} no return + * Deprecated. This file is here for custom plugin backward compatibility. + * Delete this when there is a 3.0.0 release. */ -export async function loadCoreTranslations() { - const meteorPath = await fs.realpath(`${process.cwd()}/../`); - const i18nFolder = `${meteorPath}/server/assets/app/data/i18n/`; - - if (await directoryExists(i18nFolder)) { - let files; - try { - files = await fs.readdir(i18nFolder); - } catch (error) { - throw new Error(`No translations found in ${i18nFolder} for import`, error); - } - - const promises = files.filter((file) => file.endsWith(".json")).map((file) => { - Logger.debug(`Importing Translations from ${file}`); - return fs.readFile(path.join(i18nFolder, file), "utf8"); - }); - - let fileContents = []; - try { - fileContents = await Promise.all(promises); - } catch (error) { - Logger.error("Failed to load translations from files", error.message); - } - - fileContents.forEach(loadTranslation); - } -} - -/** - * @method reloadAllTranslations - * @memberof i18n - * @summary Reload translations for all shops - * @returns {undefined} -*/ -export function reloadAllTranslations() { - // Clear assets for i18n - Assets.remove({ type: "i18n" }); - - // Remove translations for all shops - Translations.remove(); - - // Load translations from translation sources and prepare bulk op - loadTranslations(translationSources); - - // Load translations - importAllTranslations(); -} - -/** - * @method reloadTranslationsForShop - * @memberof i18n - * @summary Reload translations for specified shop - * @param {String} shopId - Shop Id to reset translations for - * @returns {undefined} -*/ -export function reloadTranslationsForShop(shopId) { - // Clear assets for i18n - Assets.remove({ type: "i18n" }); - - // Remove translations for the current shop - Translations.remove({ shopId }); - - // Load translations from translation sources and prepare bulk op - loadTranslations(translationSources); - - // Load translations - importAllTranslations(); -} +import Logger from "@reactioncommerce/logger"; +import { mergeResource } from "/imports/plugins/core/i18n/server/no-meteor/translations"; /** - * @method importAllTranslations - * @memberof i18n - * @summary Imports all translations into Assets collection and Translation collection - * @returns {undefined} + * @summary Load an array of translation arrays + * @deprecated Use new method of passing `i18n.translations` array to `registerPlugin` + * @param {Array} translations Array of arrays of i18next translation objects + * @return {undefined} */ -export function importAllTranslations() { - // Get count of all i18n assets - const i18nAssetCount = Assets.find({ type: "i18n" }).count(); - - // If we have no assets, then this is either a fresh start or - // the i18n assets were cleared. In either case, allow i18n translations - // to be loaded into Assets collection and subsequently into the Translation collection - if (i18nAssetCount === 0) { - // Import core translations - Promise.await(loadCoreTranslations()); - - // Flush all the bulk Assets upserts created by calls to loadTranslations - Promise.await(flushTranslationLoad()); - - Logger.debug("All translation assets updated"); - - const shopId = Reaction.getShopId(); - - // Then loop through those I18N assets and import them - if (shopId) { - // If there isn't a shop yet, and for future shops, this will be done in the "afterShopCreate" listener - Assets.find({ type: "i18n" }).forEach((translation) => { - Logger.debug(`Importing ${translation.name} translation for "${translation.ns}"`); - if (translation.content) { - Reaction.Importer.process(translation.content, ["i18n"], Reaction.Importer.translation, [shopId]); - } else { - Logger.debug(`No translation content found for ${translation.name} - ${translation.ns} asset`); - } - }); - } - - Reaction.Importer.flush(); - - Logger.debug("All translation imported into translations collection from Assets."); - } else { - bulkAssetOp = null; - Logger.debug("Cancel translation update. Translations have a already been imported."); - } +export function loadTranslations(translations) { + Logger.warn("Calling loadTranslations to load translations is deprecated. " + + "This function will be removed in the next major release. Pass an 'i18n' object " + + "with your 'registerPlugin' call instead. Look at any built-in plugin for an example."); + if (!Array.isArray(translations)) throw new Error("loadTranslations expects first argument to be an array"); + + translations.forEach((trns) => { + if (!Array.isArray(trns)) throw new Error("loadTranslations expects first argument to be an array of arrays"); + trns.forEach(mergeResource); + }); } diff --git a/imports/plugins/core/core/server/startup/index.js b/imports/plugins/core/core/server/startup/index.js index e15b891d20a..e2948d778f7 100644 --- a/imports/plugins/core/core/server/startup/index.js +++ b/imports/plugins/core/core/server/startup/index.js @@ -5,7 +5,6 @@ import register from "../no-meteor/register"; import startNodeApp from "./startNodeApp"; import "./browser-policy"; import CollectionSecurity from "./collection-security"; -import { importAllTranslations } from "./i18n"; import RateLimiters from "./rate-limits"; const { REACTION_METEOR_APP_COMMAND_START_TIME } = process.env; @@ -25,8 +24,6 @@ export default function startup() { Reaction.whenAppInstanceReady(register); - importAllTranslations(); - CollectionSecurity(); RateLimiters(); diff --git a/imports/plugins/core/core/server/util/connectionDataStore.app-test.js b/imports/plugins/core/core/server/util/connectionDataStore.app-test.js deleted file mode 100644 index c577e4ea0bd..00000000000 --- a/imports/plugins/core/core/server/util/connectionDataStore.app-test.js +++ /dev/null @@ -1,102 +0,0 @@ -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { DDP } from "meteor/ddp-client"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ConnectionDataStore from "./connectionDataStore"; - -describe("ConnectionDataStore", () => { - before(function (done) { - this.timeout(20000); - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - describe("used outside of a connection", () => { - it("sets/gets cached data", () => { - ConnectionDataStore.set("key", "val"); - - expect(ConnectionDataStore.get("key")).to.equal("val"); - }); - - it("clears cached data", () => { - ConnectionDataStore.set("key", "val"); - - expect(ConnectionDataStore.get("key")).to.equal("val"); - - ConnectionDataStore.clear("key"); - - expect(ConnectionDataStore.get("key")).to.be.undefined; - }); - }); - - describe("within the context of a connection", () => { - let mockConnection; - - beforeEach(() => { - mockConnection = {}; - - sinon.stub(DDP._CurrentMethodInvocation, "get") - .returns({ connection: mockConnection }); - - ConnectionDataStore.set("key", "val"); - }); - - afterEach(() => { - mockConnection = undefined; - - DDP._CurrentMethodInvocation.get.restore(); - }); - - it("sets/gets cached data", () => { - expect(ConnectionDataStore.get("key")).to.equal("val"); - }); - - it("stores data on the connection object", () => { - expect(mockConnection["connection-data"].key).to.equal("val"); - }); - }); - - describe("within the context of a multiple connections", () => { - let mockConnection; - let mockConnection2; - - beforeEach(() => { - mockConnection = {}; - mockConnection2 = {}; - - sinon.stub(DDP._CurrentMethodInvocation, "get") - .returns({ connection: mockConnection }); - - ConnectionDataStore.set("key", "val"); - - DDP._CurrentMethodInvocation.get.restore(); - - sinon.stub(DDP._CurrentMethodInvocation, "get") - .returns({ connection: mockConnection2 }); - - ConnectionDataStore.set("key2", "val2"); - }); - - afterEach(() => { - mockConnection = undefined; - mockConnection2 = undefined; - - DDP._CurrentMethodInvocation.get.restore(); - }); - - // we are now in the context of the second connection - it("does not access previous connection's data", () => { - expect(ConnectionDataStore.get("key")).to.be.undefined; - }); - - it("does not modify previous connection's data", () => { - expect(mockConnection["connection-data"]).not.to.have.property("key2"); - }); - - it("does modify _this_ connection's data", () => { - expect(ConnectionDataStore.get("key2")).to.equal("val2"); - expect(mockConnection2["connection-data"].key2).to.equal("val2"); - }); - }); -}); diff --git a/imports/plugins/core/dashboard/register.js b/imports/plugins/core/dashboard/register.js index 3cdce27ecf0..add1f847771 100644 --- a/imports/plugins/core/dashboard/register.js +++ b/imports/plugins/core/dashboard/register.js @@ -1,67 +1,11 @@ +/** + * This file is necessary for backwards compatibility while we refactor + * the API to remove Meteor. The no-meteor `register.js` file will + * eventually become the main entry point of the plugin, but for now + * our Meteor tooling loads this file, so we include this here as a + * temporary bridge. + */ import Reaction from "/imports/plugins/core/core/server/Reaction"; +import register from "./server/no-meteor/register"; -Reaction.registerPackage({ - label: "Dashboard", - name: "reaction-dashboard", - icon: "fa fa-th", - settings: { - name: "Dashboard" - }, - registry: [{ - provides: ["dashboard"], - workflow: "coreDashboardWorkflow", - name: "dashboardPackages", - label: "Core", - description: "Reaction core shop configuration", - icon: "fa fa-th", - priority: 0, - container: "core", - permissions: [{ - label: "Dashboard", - permission: "dashboard" - }] - }, { - route: "/dashboard", - name: "dashboard", - workflow: "coreDashboardWorkflow", - provides: ["shortcut"], - label: "Dashboard", - template: "dashboardPackages", - icon: "icon-reaction-logo", - priority: 0, - permissions: [{ - label: "Dashboard", - permission: "dashboard" - }] - }, { - route: "/dashboard/shop/settings", - template: "shopSettings", - name: "shopSettings", - label: "Shop Settings", - icon: "fa fa-th", - provides: ["settings"], - container: "dashboard" - }, { - label: "Options", - provides: ["shopSettings"], - container: "dashboard", - template: "optionsShopSettings", - showForShopTypes: ["primary"] - }], - layout: [{ - layout: "coreLayout", - workflow: "coreDashboardWorkflow", - theme: "default", - enabled: true, - structure: { - template: "dashboardPackages", - layoutHeader: "NavBar", - layoutFooter: "", - notFound: "notFound", - dashboardHeader: "dashboardHeader", - dashboardControls: "dashboardControls", - dashboardHeaderControls: "dashboardHeaderControls", - adminControlsFooter: "adminControlsFooter" - } - }] -}); +Reaction.whenAppInstanceReady(register); diff --git a/imports/plugins/core/dashboard/server/index.js b/imports/plugins/core/dashboard/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/dashboard/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/dashboard/server/i18n/ar.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/ar.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/dashboard/server/i18n/bg.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/bg.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/dashboard/server/i18n/cs.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/cs.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/dashboard/server/i18n/de.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/de.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/dashboard/server/i18n/el.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/el.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/dashboard/server/i18n/en.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/en.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/dashboard/server/i18n/es.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/es.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/dashboard/server/i18n/fr.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/fr.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/dashboard/server/i18n/he.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/he.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/dashboard/server/i18n/hr.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/hr.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/dashboard/server/i18n/hu.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/hu.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/accounts/server/i18n/index.js b/imports/plugins/core/dashboard/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/core/accounts/server/i18n/index.js rename to imports/plugins/core/dashboard/server/no-meteor/i18n/index.js index 822f1bdf134..9deb0a6b6e7 100644 --- a/imports/plugins/core/accounts/server/i18n/index.js +++ b/imports/plugins/core/dashboard/server/no-meteor/i18n/index.js @@ -1,8 +1,5 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; -import cs from "./cs.json"; import de from "./de.json"; import el from "./el.json"; import en from "./en.json"; @@ -10,7 +7,6 @@ import es from "./es.json"; import fr from "./fr.json"; import he from "./he.json"; import hr from "./hr.json"; -import hu from "./hu.json"; import it from "./it.json"; import my from "./my.json"; import nb from "./nb.json"; @@ -30,4 +26,29 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/dashboard/server/i18n/it.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/it.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/dashboard/server/i18n/my.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/my.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/dashboard/server/i18n/nb.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/nb.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/dashboard/server/i18n/nl.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/nl.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/dashboard/server/i18n/pl.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/pl.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/dashboard/server/i18n/pt.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/pt.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/dashboard/server/i18n/ro.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/ro.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/dashboard/server/i18n/ru.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/ru.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/dashboard/server/i18n/sl.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/sl.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/dashboard/server/i18n/sv.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/sv.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/dashboard/server/i18n/tr.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/tr.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/dashboard/server/i18n/vi.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/vi.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/dashboard/server/i18n/zh.json b/imports/plugins/core/dashboard/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/dashboard/server/i18n/zh.json rename to imports/plugins/core/dashboard/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/dashboard/server/no-meteor/register.js b/imports/plugins/core/dashboard/server/no-meteor/register.js new file mode 100644 index 00000000000..1edefd7c88c --- /dev/null +++ b/imports/plugins/core/dashboard/server/no-meteor/register.js @@ -0,0 +1,75 @@ +import i18n from "./i18n"; + +/** + * @summary Import and call this function to add this plugin to your API. + * @param {ReactionNodeApp} app The ReactionNodeApp instance + * @returns {undefined} + */ +export default async function register(app) { + await app.registerPlugin({ + label: "Dashboard", + name: "reaction-dashboard", + icon: "fa fa-th", + i18n, + settings: { + name: "Dashboard" + }, + registry: [{ + provides: ["dashboard"], + workflow: "coreDashboardWorkflow", + name: "dashboardPackages", + label: "Core", + description: "Reaction core shop configuration", + icon: "fa fa-th", + priority: 0, + container: "core", + permissions: [{ + label: "Dashboard", + permission: "dashboard" + }] + }, { + route: "/dashboard", + name: "dashboard", + workflow: "coreDashboardWorkflow", + provides: ["shortcut"], + label: "Dashboard", + template: "dashboardPackages", + icon: "icon-reaction-logo", + priority: 0, + permissions: [{ + label: "Dashboard", + permission: "dashboard" + }] + }, { + route: "/dashboard/shop/settings", + template: "shopSettings", + name: "shopSettings", + label: "Shop Settings", + icon: "fa fa-th", + provides: ["settings"], + container: "dashboard" + }, { + label: "Options", + provides: ["shopSettings"], + container: "dashboard", + template: "optionsShopSettings", + showForShopTypes: ["primary"] + }], + layout: [{ + layout: "coreLayout", + workflow: "coreDashboardWorkflow", + theme: "default", + enabled: true, + structure: { + template: "dashboardPackages", + layoutHeader: "NavBar", + layoutFooter: "", + notFound: "notFound", + dashboardHeader: "dashboardHeader", + dashboardControls: "dashboardControls", + dashboardHeaderControls: "dashboardHeaderControls", + adminControlsFooter: "adminControlsFooter" + } + }] + }); +} diff --git a/imports/plugins/core/discounts/server/i18n/index.js b/imports/plugins/core/discounts/server/i18n/index.js deleted file mode 100644 index 2d1a40cefec..00000000000 --- a/imports/plugins/core/discounts/server/i18n/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/discounts/server/index.js b/imports/plugins/core/discounts/server/index.js index f738cabaac7..e91d44e8d73 100644 --- a/imports/plugins/core/discounts/server/index.js +++ b/imports/plugins/core/discounts/server/index.js @@ -1,4 +1,3 @@ // assemble server api -import "./i18n"; import "./security/discounts"; import "./publications/discounts"; diff --git a/imports/plugins/core/discounts/server/i18n/ar.json b/imports/plugins/core/discounts/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/ar.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/discounts/server/i18n/bg.json b/imports/plugins/core/discounts/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/bg.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/discounts/server/i18n/cs.json b/imports/plugins/core/discounts/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/cs.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/discounts/server/i18n/de.json b/imports/plugins/core/discounts/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/de.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/discounts/server/i18n/el.json b/imports/plugins/core/discounts/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/el.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/discounts/server/i18n/en.json b/imports/plugins/core/discounts/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/en.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/discounts/server/i18n/es.json b/imports/plugins/core/discounts/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/es.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/discounts/server/i18n/fr.json b/imports/plugins/core/discounts/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/fr.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/discounts/server/i18n/he.json b/imports/plugins/core/discounts/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/he.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/discounts/server/i18n/hr.json b/imports/plugins/core/discounts/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/hr.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/discounts/server/i18n/hu.json b/imports/plugins/core/discounts/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/hu.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/discounts/server/no-meteor/i18n/index.js b/imports/plugins/core/discounts/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..9deb0a6b6e7 --- /dev/null +++ b/imports/plugins/core/discounts/server/no-meteor/i18n/index.js @@ -0,0 +1,54 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/discounts/server/i18n/it.json b/imports/plugins/core/discounts/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/it.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/discounts/server/i18n/my.json b/imports/plugins/core/discounts/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/my.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/discounts/server/i18n/nb.json b/imports/plugins/core/discounts/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/nb.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/discounts/server/i18n/nl.json b/imports/plugins/core/discounts/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/nl.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/discounts/server/i18n/pl.json b/imports/plugins/core/discounts/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/pl.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/discounts/server/i18n/pt.json b/imports/plugins/core/discounts/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/pt.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/discounts/server/i18n/ro.json b/imports/plugins/core/discounts/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/ro.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/discounts/server/i18n/ru.json b/imports/plugins/core/discounts/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/ru.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/discounts/server/i18n/sl.json b/imports/plugins/core/discounts/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/sl.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/discounts/server/i18n/sv.json b/imports/plugins/core/discounts/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/sv.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/discounts/server/i18n/tr.json b/imports/plugins/core/discounts/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/tr.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/discounts/server/i18n/vi.json b/imports/plugins/core/discounts/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/vi.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/discounts/server/i18n/zh.json b/imports/plugins/core/discounts/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/discounts/server/i18n/zh.json rename to imports/plugins/core/discounts/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/discounts/server/no-meteor/register.js b/imports/plugins/core/discounts/server/no-meteor/register.js index 509760fe0d1..dfcb22eb6aa 100644 --- a/imports/plugins/core/discounts/server/no-meteor/register.js +++ b/imports/plugins/core/discounts/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import setDiscountsOnCart from "./util/setDiscountsOnCart"; /** @@ -10,6 +11,7 @@ export default async function register(app) { label: "Discounts", name: "reaction-discounts", icon: "fa fa-gift", + i18n, collections: { Discounts: { name: "Discounts", diff --git a/imports/plugins/core/email/server/i18n/index.js b/imports/plugins/core/email/server/i18n/index.js deleted file mode 100644 index 2d1a40cefec..00000000000 --- a/imports/plugins/core/email/server/i18n/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/email/server/index.js b/imports/plugins/core/email/server/index.js index fc16e6dae02..4a5a37165ed 100644 --- a/imports/plugins/core/email/server/index.js +++ b/imports/plugins/core/email/server/index.js @@ -1,5 +1,4 @@ import { Meteor } from "meteor/meteor"; -import "./i18n"; import methods from "./methods"; Meteor.methods(methods); diff --git a/imports/plugins/core/email/server/i18n/ar.json b/imports/plugins/core/email/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/email/server/i18n/ar.json rename to imports/plugins/core/email/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/email/server/i18n/bg.json b/imports/plugins/core/email/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/email/server/i18n/bg.json rename to imports/plugins/core/email/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/email/server/i18n/cs.json b/imports/plugins/core/email/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/email/server/i18n/cs.json rename to imports/plugins/core/email/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/email/server/i18n/de.json b/imports/plugins/core/email/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/email/server/i18n/de.json rename to imports/plugins/core/email/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/email/server/i18n/el.json b/imports/plugins/core/email/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/email/server/i18n/el.json rename to imports/plugins/core/email/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/email/server/i18n/en.json b/imports/plugins/core/email/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/email/server/i18n/en.json rename to imports/plugins/core/email/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/email/server/i18n/es.json b/imports/plugins/core/email/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/email/server/i18n/es.json rename to imports/plugins/core/email/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/email/server/i18n/fr.json b/imports/plugins/core/email/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/email/server/i18n/fr.json rename to imports/plugins/core/email/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/email/server/i18n/he.json b/imports/plugins/core/email/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/email/server/i18n/he.json rename to imports/plugins/core/email/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/email/server/i18n/hr.json b/imports/plugins/core/email/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/email/server/i18n/hr.json rename to imports/plugins/core/email/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/email/server/i18n/hu.json b/imports/plugins/core/email/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/email/server/i18n/hu.json rename to imports/plugins/core/email/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/email/server/no-meteor/i18n/index.js b/imports/plugins/core/email/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..9deb0a6b6e7 --- /dev/null +++ b/imports/plugins/core/email/server/no-meteor/i18n/index.js @@ -0,0 +1,54 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/email/server/i18n/it.json b/imports/plugins/core/email/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/email/server/i18n/it.json rename to imports/plugins/core/email/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/email/server/i18n/my.json b/imports/plugins/core/email/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/email/server/i18n/my.json rename to imports/plugins/core/email/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/email/server/i18n/nb.json b/imports/plugins/core/email/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/email/server/i18n/nb.json rename to imports/plugins/core/email/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/email/server/i18n/nl.json b/imports/plugins/core/email/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/email/server/i18n/nl.json rename to imports/plugins/core/email/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/email/server/i18n/pl.json b/imports/plugins/core/email/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/email/server/i18n/pl.json rename to imports/plugins/core/email/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/email/server/i18n/pt.json b/imports/plugins/core/email/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/email/server/i18n/pt.json rename to imports/plugins/core/email/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/email/server/i18n/ro.json b/imports/plugins/core/email/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/email/server/i18n/ro.json rename to imports/plugins/core/email/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/email/server/i18n/ru.json b/imports/plugins/core/email/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/email/server/i18n/ru.json rename to imports/plugins/core/email/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/email/server/i18n/sl.json b/imports/plugins/core/email/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/email/server/i18n/sl.json rename to imports/plugins/core/email/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/email/server/i18n/sv.json b/imports/plugins/core/email/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/email/server/i18n/sv.json rename to imports/plugins/core/email/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/email/server/i18n/tr.json b/imports/plugins/core/email/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/email/server/i18n/tr.json rename to imports/plugins/core/email/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/email/server/i18n/vi.json b/imports/plugins/core/email/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/email/server/i18n/vi.json rename to imports/plugins/core/email/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/email/server/i18n/zh.json b/imports/plugins/core/email/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/email/server/i18n/zh.json rename to imports/plugins/core/email/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/email/server/no-meteor/register.js b/imports/plugins/core/email/server/no-meteor/register.js index 3f8ab7d8fa3..bac56e44ff0 100644 --- a/imports/plugins/core/email/server/no-meteor/register.js +++ b/imports/plugins/core/email/server/no-meteor/register.js @@ -1,4 +1,5 @@ import { Meteor } from "meteor/meteor"; +import i18n from "./i18n"; // This is temporary. Mutations still import jobs, which don't // work outside of a Meteor environment. @@ -19,6 +20,7 @@ export default async function register(app) { label: "Email", name: "reaction-email", icon: "fa fa-envelope-o", + i18n, collections: { Emails: { name: "Emails", diff --git a/imports/plugins/core/i18n/client/components/languageDropdown.js b/imports/plugins/core/i18n/client/components/languageDropdown.js deleted file mode 100644 index a3bfd243f10..00000000000 --- a/imports/plugins/core/i18n/client/components/languageDropdown.js +++ /dev/null @@ -1,65 +0,0 @@ -import React, { Component } from "react"; -import PropTypes from "prop-types"; -import { Components } from "@reactioncommerce/reaction-components"; - -class LanguageDropDown extends Component { - static propTypes = { - currentLanguage: PropTypes.string, - handleChange: PropTypes.func, - languages: PropTypes.array - } - - state = { - value: "" - } - - buttonElement() { - return ( - -   - - - ); - } - onChange = (event, value) => { - this.setState({ - value - }); - - this.props.handleChange(value); - } - - render() { - return ( -
- {this.props.languages.length > 1 && -
- - - - {this.props.languages.map((language) => ( - - ))} - -
- } -
- ); - } -} - -export default LanguageDropDown; diff --git a/imports/plugins/core/i18n/client/components/localizationSettings.js b/imports/plugins/core/i18n/client/components/localizationSettings.js index 30734c07cd0..5c4efc2458d 100644 --- a/imports/plugins/core/i18n/client/components/localizationSettings.js +++ b/imports/plugins/core/i18n/client/components/localizationSettings.js @@ -13,7 +13,6 @@ class LocalizationSettings extends Component { languages: PropTypes.array, onEnableAllCurrencies: PropTypes.func, onEnableAllLanguages: PropTypes.func, - onReloadTranslations: PropTypes.func, onUpdateCurrencyConfiguration: PropTypes.func, onUpdateLanguageConfiguration: PropTypes.func, onUpdateLocalization: PropTypes.func, @@ -41,33 +40,45 @@ class LocalizationSettings extends Component { } handleUpdateCurrencyConfiguration = (event, isChecked, name) => { - const currencyIndex = this.state.currencies.findIndex((currency) => currency.name === name); - this.setState((state) => { - const newStateCurrencies = state.currencies; - newStateCurrencies[currencyIndex].enabled = isChecked; + // Ensure we do not mutate the state/prop object + const newStateCurrencies = state.currencies.map((currency) => { + if (currency.name === name) return Object.assign({}, currency, { enabled: isChecked }); + return currency; + }); return { currencies: newStateCurrencies }; }, () => { // Delaying to allow animation before sending data to server // If animation is not delayed, it twitches when actual update happens setTimeout(() => { - this.props.onUpdateCurrencyConfiguration(event, isChecked, name); + this.props.onUpdateCurrencyConfiguration(event, isChecked, name, (error) => { + if (error) { + // Error has already been shown in UI but we need to revert the state change + this.setState({ currencies: this.props.currencies }); + } + }); }, 200); }); } - handleUpdateLangaugeConfiguration = (event, isChecked, name) => { - const languageIndex = this.state.languages.findIndex((language) => language.value === name); - + handleUpdateLanguageConfiguration = (event, isChecked, name) => { this.setState((state) => { - const newStateLanguages = state.languages; - newStateLanguages[languageIndex].enabled = isChecked; + // Ensure we do not mutate the state/prop object + const newStateLanguages = state.languages.map((language) => { + if (language.value === name) return Object.assign({}, language, { enabled: isChecked }); + return language; + }); return { languages: newStateLanguages }; }, () => { // Delaying to allow animation before sending data to server // If animation is not delayed, it twitches when actual update happens setTimeout(() => { - this.props.onUpdateLanguageConfiguration(event, isChecked, name); + this.props.onUpdateLanguageConfiguration(event, isChecked, name, (error) => { + if (error) { + // Error has already been shown in UI but we need to revert the state change + this.setState({ languages: this.props.languages }); + } + }); }, 200); }); } @@ -93,7 +104,7 @@ class LocalizationSettings extends Component { label={language.label} switchOn={language.enabled} switchName={language.value} - onSwitchChange={this.handleUpdateLangaugeConfiguration} + onSwitchChange={this.handleUpdateLanguageConfiguration} /> )); } @@ -128,12 +139,6 @@ class LocalizationSettings extends Component { } } - handleReloadTranslations = (event) => { - if (typeof this.props.onReloadTranslations === "function") { - this.props.onReloadTranslations(event.altKey); - } - } - renderListControls(name) { return ( @@ -150,16 +155,6 @@ class LocalizationSettings extends Component { value={name} onClick={this.handleAllOff} /> - {name === "language" && "|"} - {name === "language" && - - } ); } diff --git a/imports/plugins/core/i18n/client/containers/languageDropdown.js b/imports/plugins/core/i18n/client/containers/languageDropdown.js deleted file mode 100644 index dcd33317dec..00000000000 --- a/imports/plugins/core/i18n/client/containers/languageDropdown.js +++ /dev/null @@ -1,65 +0,0 @@ -import { compose, withProps } from "recompose"; -import { Reaction } from "/client/api"; -import { Meteor } from "meteor/meteor"; -import { Shops } from "/lib/collections"; -import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components"; -import LanguageDropdown from "../components/languageDropdown"; - -const handlers = { - handleChange(value) { - Meteor.users.update(Reaction.getUserId(), { $set: { "profile.lang": value } }); - } -}; - -const composer = (props, onData) => { - const languages = []; - let currentLanguage = ""; - - if (Reaction.Subscriptions.PrimaryShop.ready() && - Reaction.Subscriptions.MerchantShops.ready() && Meteor.user()) { - let shopId; - - // Choose shop to get language from - if (Reaction.marketplaceEnabled && Reaction.merchantLanguage) { - shopId = Reaction.getShopId(); - } else { - shopId = Reaction.getPrimaryShopId(); - } - - const shop = Shops.findOne({ - _id: shopId - }); - - if (typeof shop === "object" && shop.languages) { - for (const language of shop.languages) { - if (language.enabled === true) { - language.translation = `languages.${language.label.toLowerCase()}`; - // appending a helper to let us know this - // language is currently selected - const { profile } = Meteor.user(); - if (profile && profile.lang) { - if (profile.lang === language.i18n) { - currentLanguage = profile.lang; - } - } else if (shop.language === language.i18n) { - // we don't have a profile language - // use the shop default - currentLanguage = shop.language; - } - languages.push(language); - } - } - } - } - onData(null, { languages, currentLanguage }); -}; - -registerComponent("LanguageDropdown", LanguageDropdown, [ - composeWithTracker(composer), - withProps(handlers) -]); - -export default compose( - composeWithTracker(composer), - withProps(handlers) -)(LanguageDropdown); diff --git a/imports/plugins/core/i18n/client/containers/localizationSettings.js b/imports/plugins/core/i18n/client/containers/localizationSettings.js index 456e8c050c4..0958b04a83c 100644 --- a/imports/plugins/core/i18n/client/containers/localizationSettings.js +++ b/imports/plugins/core/i18n/client/containers/localizationSettings.js @@ -8,20 +8,36 @@ import { Shops } from "/lib/collections"; import { convertWeight, convertLength } from "/lib/api"; import LocalizationSettings from "../components/localizationSettings"; +/** + * @summary Use this as a Meteor.call callback to show a toast alert + * with the error reason/message. + * @param {Error|null} [error] Error + * @return {undefined} + */ +function methodAlertCallback(error) { + if (error) Alerts.toast(error.reason || error.message || "There was an unknown error", "error"); +} + const wrapComponent = (Comp) => ( class LocalizationSettingsContainer extends Component { static propTypes = LocalizationSettings.propTypes - handleUpdateLanguageConfiguration = (event, isChecked, name) => { + handleUpdateLanguageConfiguration = (event, isChecked, name, callback) => { const language = this.props.languages.find((lang) => lang.value === name); if (language) { - Meteor.call("shop/updateLanguageConfiguration", language.value, isChecked); + Meteor.call("shop/updateLanguageConfiguration", language.value, isChecked, (error) => { + methodAlertCallback(error); + if (callback) callback(error); + }); } } - handleUpdateCurrencyConfiguration = (event, isChecked, name) => { - Meteor.call("shop/updateCurrencyConfiguration", name, isChecked); + handleUpdateCurrencyConfiguration = (event, isChecked, name, callback) => { + Meteor.call("shop/updateCurrencyConfiguration", name, isChecked, (error) => { + methodAlertCallback(error); + if (callback) callback(error); + }); } handleSubmit = (doc) => { @@ -35,7 +51,7 @@ const wrapComponent = (Comp) => ( length: convertLength(shop.baseUOL, doc.baseUOL, shop.defaultParcelSize.length), width: convertLength(shop.baseUOL, doc.baseUOL, shop.defaultParcelSize.width) }; - Meteor.call("shop/updateDefaultParcelSize", parcelSize); + Meteor.call("shop/updateDefaultParcelSize", parcelSize, methodAlertCallback); } Shops.update({ _id: doc._id @@ -52,35 +68,11 @@ const wrapComponent = (Comp) => ( } handleEnableAllLanguages = (isEnabled) => { - Meteor.call("shop/updateLanguageConfiguration", "all", isEnabled); + Meteor.call("shop/updateLanguageConfiguration", "all", isEnabled, methodAlertCallback); } handleEnableAllCurrencies = (isEnabled) => { - Meteor.call("shop/updateCurrencyConfiguration", "all", isEnabled); - } - - handleTranslationReload = (flushAll) => { - if (flushAll === true) { - Alerts.toast(i18next.t("admin.i18nSettings.reloadAllStarted", { defaultValue: "Reloading translations for all shops." }), "info"); - - Meteor.call("i18n/flushTranslations", (error) => { - if (!error) { - Alerts.toast(i18next.t("admin.i18nSettings.reloadAllSuccess", { defaultValue: "Translations have been reloaded for all shops." }), "success"); - } else { - Alerts.toast(i18next.t("admin.i18nSettings.reloadAllFail", { defaultValue: "Translations could not be reloaded for all shops." }), "error"); - } - }); - } else { - Alerts.toast(i18next.t("admin.i18nSettings.reloadStarted", { defaultValue: "Reloading translations for the current shop." }), "info"); - - Meteor.call("i18n/flushTranslations", (error) => { - if (!error) { - Alerts.toast(i18next.t("admin.i18nSettings.reloadSuccess", { defaultValue: "Translations have been reloaded for the current shop." }), "success"); - } else { - Alerts.toast(i18next.t("admin.i18nSettings.reloadFail", { defaultValue: "Translations could not be reloaded for the current shop." }), "error"); - } - }); - } + Meteor.call("shop/updateCurrencyConfiguration", "all", isEnabled, methodAlertCallback); } render() { @@ -92,7 +84,6 @@ const wrapComponent = (Comp) => ( onUpdateCurrencyConfiguration={this.handleUpdateCurrencyConfiguration} onUpdateLanguageConfiguration={this.handleUpdateLanguageConfiguration} onUpdateLocalization={this.handleSubmit} - onReloadTranslations={this.handleTranslationReload} /> ); } diff --git a/imports/plugins/core/i18n/client/index.js b/imports/plugins/core/i18n/client/index.js index 9ab2d6e28e9..0dcb7eefdd4 100644 --- a/imports/plugins/core/i18n/client/index.js +++ b/imports/plugins/core/i18n/client/index.js @@ -5,7 +5,6 @@ import { faGlobe } from "@fortawesome/free-solid-svg-icons"; import { registerOperatorRoute } from "/imports/client/ui"; import Localization from "./containers/localizationSettings"; -export { default as LanguageDropdown } from "./containers/languageDropdown"; export { default as LocalizationSettings } from "./containers/localizationSettings"; registerOperatorRoute({ diff --git a/imports/plugins/core/i18n/server/i18n/index.js b/imports/plugins/core/i18n/server/i18n/index.js deleted file mode 100644 index 0448519dded..00000000000 --- a/imports/plugins/core/i18n/server/i18n/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -// loadTranslations([en]); -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/i18n/server/index.js b/imports/plugins/core/i18n/server/index.js deleted file mode 100644 index fc16e6dae02..00000000000 --- a/imports/plugins/core/i18n/server/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import "./i18n"; -import methods from "./methods"; - -Meteor.methods(methods); diff --git a/imports/plugins/core/i18n/server/methods/addTranslation.js b/imports/plugins/core/i18n/server/methods/addTranslation.js deleted file mode 100644 index bcc02736bfe..00000000000 --- a/imports/plugins/core/i18n/server/methods/addTranslation.js +++ /dev/null @@ -1,39 +0,0 @@ -import { check, Match } from "meteor/check"; -import ReactionError from "@reactioncommerce/reaction-error"; -import { Translations } from "/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; - -/** - * @name i18n/addTranslation - * @method - * @memberof i18n - * @example Meteor.call("i18n/addTranslation", "en", "addProductLabel", "Add product") - * @param {String | Array} lng - language - * @param {String} namespace - namespace - * @param {String} key - i18n key - * @param {String} message - i18n message - * @summary Meteor method to add translations - * @returns {String} insert result - */ -export default function addTranslation(lng, namespace, key, message) { - check(lng, Match.OneOf(String, Array)); - check(namespace, String); - check(key, String); - check(message, String); - // string or first language - let i18n = lng; - if (typeof lng === "object") { - [i18n] = lng; - } - - if (!Reaction.hasAdminAccess()) { - throw new ReactionError("access-denied", "Access Denied"); - } - const tran = ` - "i18n": "${i18n}", - "shopId": "${Reaction.getShopId()}" - `; - - const setTran = `"translation.${namespace}.${key}": "${message}"`; - Translations.update({ tran }, { setTran }); -} diff --git a/imports/plugins/core/i18n/server/methods/flushAllTranslations.js b/imports/plugins/core/i18n/server/methods/flushAllTranslations.js deleted file mode 100644 index 2e09733a050..00000000000 --- a/imports/plugins/core/i18n/server/methods/flushAllTranslations.js +++ /dev/null @@ -1,19 +0,0 @@ -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; -import { reloadAllTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -/** - * @name i18n/flushAllTranslations - * @method - * @memberof i18n - * @example Meteor.call("i18n/flushAllTranslations") - * @summary Method to remove all translations for all shops, and reload from jsonFiles - * @returns {undefined} - */ -export default function flushAllTranslations() { - if (!Reaction.hasPermission("admin", Reaction.getUserId(), Reaction.getPrimaryShopId())) { - throw new ReactionError("access-denied", "Access Denied"); - } - - reloadAllTranslations(); -} diff --git a/imports/plugins/core/i18n/server/methods/flushTranslations.js b/imports/plugins/core/i18n/server/methods/flushTranslations.js deleted file mode 100644 index 94d04048707..00000000000 --- a/imports/plugins/core/i18n/server/methods/flushTranslations.js +++ /dev/null @@ -1,20 +0,0 @@ -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; -import { reloadTranslationsForShop } from "/imports/plugins/core/core/server/startup/i18n"; - -/** - * @name i18n/flushTranslations - * @method - * @memberof i18n - * @example Meteor.call("i18n/flushTranslations") - * @summary Method to remove all translations for the current shop, and reload from jsonFiles - * @returns {undefined} - */ -export default function flushTranslations() { - if (!Reaction.hasAdminAccess()) { - throw new ReactionError("access-denied", "Access Denied"); - } - - const shopId = Reaction.getShopId(); - reloadTranslationsForShop(shopId); -} diff --git a/imports/plugins/core/i18n/server/methods/index.js b/imports/plugins/core/i18n/server/methods/index.js deleted file mode 100644 index 4ead67bdcde..00000000000 --- a/imports/plugins/core/i18n/server/methods/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import addTranslation from "./addTranslation"; -import flushAllTranslations from "./flushAllTranslations"; -import flushTranslations from "./flushTranslations"; - -export default { - "i18n/addTranslation": addTranslation, - "i18n/flushAllTranslations": flushAllTranslations, - "i18n/flushTranslations": flushTranslations -}; diff --git a/imports/plugins/core/i18n/server/i18n/ar.json b/imports/plugins/core/i18n/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/ar.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/i18n/server/i18n/bg.json b/imports/plugins/core/i18n/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/bg.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/i18n/server/i18n/cs.json b/imports/plugins/core/i18n/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/cs.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/i18n/server/i18n/de.json b/imports/plugins/core/i18n/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/de.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/i18n/server/i18n/el.json b/imports/plugins/core/i18n/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/el.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/i18n/server/i18n/en.json b/imports/plugins/core/i18n/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/en.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/i18n/server/i18n/es.json b/imports/plugins/core/i18n/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/es.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/i18n/server/i18n/fr.json b/imports/plugins/core/i18n/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/fr.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/i18n/server/i18n/he.json b/imports/plugins/core/i18n/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/he.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/i18n/server/i18n/hr.json b/imports/plugins/core/i18n/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/hr.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/i18n/server/i18n/hu.json b/imports/plugins/core/i18n/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/hu.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/i18n/server/no-meteor/i18n/index.js b/imports/plugins/core/i18n/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..9deb0a6b6e7 --- /dev/null +++ b/imports/plugins/core/i18n/server/no-meteor/i18n/index.js @@ -0,0 +1,54 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/i18n/server/i18n/it.json b/imports/plugins/core/i18n/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/it.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/i18n/server/i18n/my.json b/imports/plugins/core/i18n/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/my.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/i18n/server/i18n/nb.json b/imports/plugins/core/i18n/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/nb.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/i18n/server/i18n/nl.json b/imports/plugins/core/i18n/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/nl.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/i18n/server/i18n/pl.json b/imports/plugins/core/i18n/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/pl.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/i18n/server/i18n/pt.json b/imports/plugins/core/i18n/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/pt.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/i18n/server/i18n/ro.json b/imports/plugins/core/i18n/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/ro.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/i18n/server/i18n/ru.json b/imports/plugins/core/i18n/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/ru.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/i18n/server/i18n/sl.json b/imports/plugins/core/i18n/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/sl.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/i18n/server/i18n/sv.json b/imports/plugins/core/i18n/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/sv.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/i18n/server/i18n/tr.json b/imports/plugins/core/i18n/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/tr.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/i18n/server/i18n/vi.json b/imports/plugins/core/i18n/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/vi.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/i18n/server/i18n/zh.json b/imports/plugins/core/i18n/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/i18n/server/i18n/zh.json rename to imports/plugins/core/i18n/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/i18n/server/no-meteor/register.js b/imports/plugins/core/i18n/server/no-meteor/register.js index e3059db12ac..b706c3b71be 100644 --- a/imports/plugins/core/i18n/server/no-meteor/register.js +++ b/imports/plugins/core/i18n/server/no-meteor/register.js @@ -1,3 +1,5 @@ +import i18n from "./i18n"; +import { registerPluginHandler } from "./registration"; import startup from "./startup"; /** @@ -10,17 +12,9 @@ export default async function register(app) { label: "i18n", name: "reaction-i18n", icon: "fa fa-language", - collections: { - Translations: { - name: "Translations", - indexes: [ - // Create indexes. We set specific names for backwards compatibility - // with indexes created by the aldeed:schema-index Meteor package. - [{ shopId: 1, i18n: 1 }] - ] - } - }, + i18n, functionsByType: { + registerPluginHandler: [registerPluginHandler], startup: [startup] }, settings: { diff --git a/imports/plugins/core/i18n/server/no-meteor/registration.js b/imports/plugins/core/i18n/server/no-meteor/registration.js new file mode 100644 index 00000000000..174a41eb6c2 --- /dev/null +++ b/imports/plugins/core/i18n/server/no-meteor/registration.js @@ -0,0 +1,15 @@ +import { mergeResource } from "./translations"; + +/** + * @summary Will be called for every plugin + * @param {Object} options The options object that the plugin passed to registerPackage + * @returns {undefined} + */ +export function registerPluginHandler({ i18n, name }) { + if (i18n) { + const { translations } = i18n; + if (!Array.isArray(translations)) throw new Error(`Plugin ${name} registered i18n.translations that is not an array`); + + translations.forEach(mergeResource); + } +} diff --git a/imports/plugins/core/i18n/server/no-meteor/startup.js b/imports/plugins/core/i18n/server/no-meteor/startup.js index 5a9a68aeeb6..4ac70070662 100644 --- a/imports/plugins/core/i18n/server/no-meteor/startup.js +++ b/imports/plugins/core/i18n/server/no-meteor/startup.js @@ -1,5 +1,4 @@ -import Logger from "@reactioncommerce/logger"; -import Random from "@reactioncommerce/random"; +import { addTranslationRoutes } from "./translations"; /** * @summary Called on startup @@ -8,31 +7,7 @@ import Random from "@reactioncommerce/random"; * @returns {undefined} */ export default async function startup(context) { - const { - appEvents, - collections: { - Assets, - Translations - } - } = context; + const { app } = context; - appEvents.on("afterShopCreate", async ({ shop }) => { - const { _id: shopId } = shop; - - // Insert Translations documents for this shop - const assets = await Assets.find({ type: "i18n" }).toArray(); - const translations = assets.map((assetDoc) => { - const assetContent = JSON.parse(assetDoc.content); - - return { - _id: Random.id(), - ...assetContent[0], - shopId - }; - }); - - await Translations.insertMany(translations); - - Logger.debug(`Created translation documents for shop ${shopId}`); - }); + if (app.expressApp) addTranslationRoutes(app.expressApp); } diff --git a/imports/plugins/core/i18n/server/no-meteor/translations.js b/imports/plugins/core/i18n/server/no-meteor/translations.js new file mode 100644 index 00000000000..b35bb8a21ec --- /dev/null +++ b/imports/plugins/core/i18n/server/no-meteor/translations.js @@ -0,0 +1,70 @@ +import merge from "lodash/merge"; + +const GET_MULTI_RESOURCES_PATH = "/locales/resources.json"; +const GET_NAMESPACES_PATH = "/locales/namespaces.json"; + +// i18next browser lib always sends a language so this is only +// used if you hit the route directly. +const DEFAULT_LANGUAGE = "en"; + +// i18next browser lib always sends a namespace so this is only +// used if you hit the route directly. +const DEFAULT_NAMESPACE = "core"; + +const resources = {}; +const namespacesSet = new Set(); +let namespaces; + +/** + * @summary Call this to add translation objects. Mutates `resources` and `namespaces`. + * @param {Object} translation Object with `i18n`, `ns`, and `translation` keys + * @return {undefined} + */ +export function mergeResource(translation) { + merge(resources, { + [translation.i18n]: translation.translation + }); + + // Doing it this way to ensure each namespace is listed only once + namespacesSet.add(translation.ns); + namespaces = [...namespacesSet]; +} + +/** + * @summary Adds i18next translation routes to an Express app + * @param {Object} expressApp Express app instance + * @return {undefined} + */ +export function addTranslationRoutes(expressApp) { + expressApp.get(GET_MULTI_RESOURCES_PATH, (req, res) => { + const { lng = DEFAULT_LANGUAGE, ns = DEFAULT_NAMESPACE } = req.query; + + // Default behavior of i18next browser client is to separate multiple + // lng and ns with `+`, which becomes a space-delimited string on this end. + const requestedLanguages = lng.split(" "); + const requestedNamespaces = ns.split(" "); + + // Filter `resources` as requested before sending back. + // We always include all requested languages and namespaces + // to avoid the browser throwing load errors. But if the language + // or namespace was not registered by any plugin, then the + // translations will be just an empty {}. + const filteredResources = {}; + for (const language of requestedLanguages) { + filteredResources[language] = {}; + const lngObj = resources[language] || {}; + for (const namespace of requestedNamespaces) { + filteredResources[language][namespace] = lngObj[namespace] || {}; + } + } + + res.json(filteredResources); + }); + + // Because Reaction's namespace list is fluid -- any plugin can add any namespace + // it wants -- we provide a route where the browser code can get the full list + // on page load. + expressApp.get(GET_NAMESPACES_PATH, (req, res) => { + res.json(namespaces); + }); +} diff --git a/imports/plugins/core/inventory/server/index.js b/imports/plugins/core/inventory/server/index.js index e44f66295e1..848f1abfaf2 100644 --- a/imports/plugins/core/inventory/server/index.js +++ b/imports/plugins/core/inventory/server/index.js @@ -1,2 +1 @@ -import "./i18n"; import "../lib/extendCoreSchemas"; diff --git a/imports/plugins/core/inventory/server/i18n/en.json b/imports/plugins/core/inventory/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/inventory/server/i18n/en.json rename to imports/plugins/core/inventory/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/address/server/i18n/index.js b/imports/plugins/core/inventory/server/no-meteor/i18n/index.js similarity index 56% rename from imports/plugins/core/address/server/i18n/index.js rename to imports/plugins/core/inventory/server/no-meteor/i18n/index.js index bce646aa335..e6a23601392 100644 --- a/imports/plugins/core/address/server/i18n/index.js +++ b/imports/plugins/core/inventory/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import en from "./en.json"; // @@ -7,4 +5,6 @@ import en from "./en.json"; // imports for easier handling by // automated translation software // -loadTranslations([en]); +export default { + translations: [...en] +}; diff --git a/imports/plugins/core/inventory/server/no-meteor/register.js b/imports/plugins/core/inventory/server/no-meteor/register.js index a04d4030e3a..27de44bc54c 100644 --- a/imports/plugins/core/inventory/server/no-meteor/register.js +++ b/imports/plugins/core/inventory/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import queries from "./queries"; import schemas from "./schemas"; import publishProductToCatalog from "./utils/publishProductToCatalog"; @@ -15,6 +16,7 @@ export default async function register(app) { await app.registerPlugin({ label: "Inventory", name: "reaction-inventory", + i18n, functionsByType: { publishProductToCatalog: [publishProductToCatalog], startup: [startup], diff --git a/imports/plugins/core/layout/client/templates/theme/theme.js b/imports/plugins/core/layout/client/templates/theme/theme.js index ed6d57670a5..024d29aebfb 100644 --- a/imports/plugins/core/layout/client/templates/theme/theme.js +++ b/imports/plugins/core/layout/client/templates/theme/theme.js @@ -45,15 +45,8 @@ Router.Hooks.onEnter(addBodyClasses); Meteor.startup(() => { Tracker.autorun(() => { - if (Reaction.Subscriptions.PrimaryShop.ready() && Reaction.Subscriptions.MerchantShops.ready()) { - let shopId; - - // Choose shop to get theme from - if (Reaction.marketplaceEnabled && Reaction.merchantTheme) { - shopId = Reaction.getShopId(); - } else { - shopId = Reaction.getPrimaryShopId(); - } + if (Reaction.Subscriptions.PrimaryShop.ready()) { + const shopId = Reaction.getShopId(); const shop = Shops.findOne({ _id: shopId diff --git a/imports/plugins/core/layout/server/i18n/ar.json b/imports/plugins/core/layout/server/i18n/ar.json deleted file mode 100644 index d2bbd0600dc..00000000000 --- a/imports/plugins/core/layout/server/i18n/ar.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "ar", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "تصميم", - "layoutTitle": "تصميم", - "layoutDescription": "المرافق تخطيط" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/bg.json b/imports/plugins/core/layout/server/i18n/bg.json deleted file mode 100644 index e0813abaa4d..00000000000 --- a/imports/plugins/core/layout/server/i18n/bg.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "bg", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "оформление", - "layoutTitle": "оформление", - "layoutDescription": "Разпределение комунални услуги" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/cs.json b/imports/plugins/core/layout/server/i18n/cs.json deleted file mode 100644 index 96db30e2948..00000000000 --- a/imports/plugins/core/layout/server/i18n/cs.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "cs", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "dispozice", - "layoutTitle": "dispozice", - "layoutDescription": "rozvržení pomůcky" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/de.json b/imports/plugins/core/layout/server/i18n/de.json deleted file mode 100644 index 45086999f70..00000000000 --- a/imports/plugins/core/layout/server/i18n/de.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "de", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Layout", - "layoutTitle": "Layout", - "layoutDescription": "Layout-Dienstprogramme" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/el.json b/imports/plugins/core/layout/server/i18n/el.json deleted file mode 100644 index 8c30389c81f..00000000000 --- a/imports/plugins/core/layout/server/i18n/el.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "el", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Διάταξη", - "layoutTitle": "Διάταξη", - "layoutDescription": "διάταξη κοινής ωφελείας" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/en.json b/imports/plugins/core/layout/server/i18n/en.json deleted file mode 100644 index 740ded3a989..00000000000 --- a/imports/plugins/core/layout/server/i18n/en.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Layout", - "layoutTitle": "Layout", - "layoutDescription": "Layout utilities" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/es.json b/imports/plugins/core/layout/server/i18n/es.json deleted file mode 100644 index 3a84c6d0572..00000000000 --- a/imports/plugins/core/layout/server/i18n/es.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "es", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Diseño", - "layoutTitle": "Diseño", - "layoutDescription": "utilidades de diseño" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/fr.json b/imports/plugins/core/layout/server/i18n/fr.json deleted file mode 100644 index bdb0a5839f8..00000000000 --- a/imports/plugins/core/layout/server/i18n/fr.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "fr", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Disposition", - "layoutTitle": "Disposition", - "layoutDescription": "utilitaires de mise en page" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/he.json b/imports/plugins/core/layout/server/i18n/he.json deleted file mode 100644 index b904c578d7d..00000000000 --- a/imports/plugins/core/layout/server/i18n/he.json +++ /dev/null @@ -1,5 +0,0 @@ -[{ - "i18n": "he", - "ns": "reaction-layout", - "translation": { } -}] diff --git a/imports/plugins/core/layout/server/i18n/hr.json b/imports/plugins/core/layout/server/i18n/hr.json deleted file mode 100644 index 09e7800d31d..00000000000 --- a/imports/plugins/core/layout/server/i18n/hr.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "hr", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "raspored", - "layoutTitle": "raspored", - "layoutDescription": "izgled komunalije" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/hu.json b/imports/plugins/core/layout/server/i18n/hu.json deleted file mode 100644 index a7d2210baaf..00000000000 --- a/imports/plugins/core/layout/server/i18n/hu.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "hu", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Elrendezés", - "layoutTitle": "Elrendezés", - "layoutDescription": "Layout segédprogramok" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/index.js b/imports/plugins/core/layout/server/i18n/index.js deleted file mode 100644 index 2d1a40cefec..00000000000 --- a/imports/plugins/core/layout/server/i18n/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/layout/server/i18n/it.json b/imports/plugins/core/layout/server/i18n/it.json deleted file mode 100644 index bf612610ec7..00000000000 --- a/imports/plugins/core/layout/server/i18n/it.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "it", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "disposizione", - "layoutTitle": "disposizione", - "layoutDescription": "utilità di layout" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/my.json b/imports/plugins/core/layout/server/i18n/my.json deleted file mode 100644 index a8fed1fa457..00000000000 --- a/imports/plugins/core/layout/server/i18n/my.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "my", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "စီမန်ကိန်း", - "layoutTitle": "စီမန်ကိန်း", - "layoutDescription": "layout utilities" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/nb.json b/imports/plugins/core/layout/server/i18n/nb.json deleted file mode 100644 index df26164de15..00000000000 --- a/imports/plugins/core/layout/server/i18n/nb.json +++ /dev/null @@ -1,5 +0,0 @@ -[{ - "i18n": "nb", - "ns": "reaction-layout", - "translation": { } -}] diff --git a/imports/plugins/core/layout/server/i18n/nl.json b/imports/plugins/core/layout/server/i18n/nl.json deleted file mode 100644 index 812e48390e1..00000000000 --- a/imports/plugins/core/layout/server/i18n/nl.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "nl", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Lay-out", - "layoutTitle": "Lay-out", - "layoutDescription": "Layout utilities" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/pl.json b/imports/plugins/core/layout/server/i18n/pl.json deleted file mode 100644 index a4c6ebb362c..00000000000 --- a/imports/plugins/core/layout/server/i18n/pl.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "pl", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Układ", - "layoutTitle": "Układ", - "layoutDescription": "Układ narzędzia" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/pt.json b/imports/plugins/core/layout/server/i18n/pt.json deleted file mode 100644 index ad64aceb9f7..00000000000 --- a/imports/plugins/core/layout/server/i18n/pt.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "pt", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Traçado", - "layoutTitle": "Traçado", - "layoutDescription": "utilitários de layout" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/ro.json b/imports/plugins/core/layout/server/i18n/ro.json deleted file mode 100644 index 3151ced4492..00000000000 --- a/imports/plugins/core/layout/server/i18n/ro.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "ro", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Layout", - "layoutTitle": "Layout", - "layoutDescription": "utilitati aranjare" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/ru.json b/imports/plugins/core/layout/server/i18n/ru.json deleted file mode 100644 index 98d4c2a8e22..00000000000 --- a/imports/plugins/core/layout/server/i18n/ru.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "ru", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "раскладка", - "layoutTitle": "раскладка", - "layoutDescription": "Макет утилиты" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/sl.json b/imports/plugins/core/layout/server/i18n/sl.json deleted file mode 100644 index 2627feff9ee..00000000000 --- a/imports/plugins/core/layout/server/i18n/sl.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "sl", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "postavitev", - "layoutTitle": "postavitev", - "layoutDescription": "postavitev pripomočki" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/sv.json b/imports/plugins/core/layout/server/i18n/sv.json deleted file mode 100644 index c40c811ec00..00000000000 --- a/imports/plugins/core/layout/server/i18n/sv.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "sv", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Layout", - "layoutTitle": "Layout", - "layoutDescription": "layout verktyg" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/tr.json b/imports/plugins/core/layout/server/i18n/tr.json deleted file mode 100644 index 441184f2be1..00000000000 --- a/imports/plugins/core/layout/server/i18n/tr.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "tr", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "düzen", - "layoutTitle": "düzen", - "layoutDescription": "Düzen yarar" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/vi.json b/imports/plugins/core/layout/server/i18n/vi.json deleted file mode 100644 index 7add32d0558..00000000000 --- a/imports/plugins/core/layout/server/i18n/vi.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "vi", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "Bố trí", - "layoutTitle": "Bố trí", - "layoutDescription": "tiện ích layout" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/i18n/zh.json b/imports/plugins/core/layout/server/i18n/zh.json deleted file mode 100644 index e5aca8aaf68..00000000000 --- a/imports/plugins/core/layout/server/i18n/zh.json +++ /dev/null @@ -1,15 +0,0 @@ -[{ - "i18n": "zh", - "ns": "reaction-layout", - "translation": { - "reaction-layout": { - "admin": { - "dashboard": { - "layoutLabel": "设计", - "layoutTitle": "设计", - "layoutDescription": "布局公用事业" - } - } - } - } -}] diff --git a/imports/plugins/core/layout/server/index.js b/imports/plugins/core/layout/server/index.js index 455c7687378..e11789101c2 100644 --- a/imports/plugins/core/layout/server/index.js +++ b/imports/plugins/core/layout/server/index.js @@ -1,2 +1 @@ import "./publications/templates"; -import "./i18n"; diff --git a/imports/plugins/core/navigation/client/components/SortableNodeContentRenderer.js b/imports/plugins/core/navigation/client/components/SortableNodeContentRenderer.js index 43095176046..917269a86b0 100644 --- a/imports/plugins/core/navigation/client/components/SortableNodeContentRenderer.js +++ b/imports/plugins/core/navigation/client/components/SortableNodeContentRenderer.js @@ -1,16 +1,18 @@ // Based on theme: https://github.com/frontend-collective/react-sortable-tree-theme-file-explorer -import React, { Component } from "react"; +import React from "react"; import PropTypes from "prop-types"; import classNames from "classnames"; -import { withStyles } from "@material-ui/core/styles"; -import Card from "@material-ui/core/Card"; -import IconButton from "@material-ui/core/IconButton"; -import Typography from "@material-ui/core/Typography"; +import { + Card, + IconButton, + Typography, + makeStyles +} from "@material-ui/core"; import ChevronRightIcon from "mdi-material-ui/ChevronRight"; import DragIcon from "mdi-material-ui/Drag"; import FileOutlineIcon from "mdi-material-ui/FileOutline"; -const styles = (theme) => ({ +const useStyles = makeStyles((theme) => ({ badge: { backgroundColor: theme.palette.colors.black05, color: theme.palette.colors.black65, @@ -70,7 +72,7 @@ const styles = (theme) => ({ subtitleIcon: { marginRight: 4 } -}); +})); /** * Check if node is a descendant @@ -86,226 +88,229 @@ function isDescendant(older, younger) { ); } -class SortableNodeContentRenderer extends Component { - static propTypes = { - buttons: PropTypes.arrayOf(PropTypes.node), - canDrag: PropTypes.bool, - canDrop: PropTypes.bool, - className: PropTypes.string, - classes: PropTypes.object, - connectDragPreview: PropTypes.func.isRequired, - connectDragSource: PropTypes.func.isRequired, - didDrop: PropTypes.bool.isRequired, // eslint-disable-line react/boolean-prop-naming - draggedNode: PropTypes.shape({}), - icons: PropTypes.arrayOf(PropTypes.node), - isDragging: PropTypes.bool.isRequired, - isOver: PropTypes.bool.isRequired, - isSearchFocus: PropTypes.bool, - isSearchMatch: PropTypes.bool, - listIndex: PropTypes.number.isRequired, - lowerSiblingCounts: PropTypes.arrayOf(PropTypes.number).isRequired, - node: PropTypes.shape({}).isRequired, - parentNode: PropTypes.shape({}), // Needed for dndManager - path: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])).isRequired, - rowDirection: PropTypes.string.isRequired, - scaffoldBlockPxWidth: PropTypes.number.isRequired, - style: PropTypes.shape({}), - subtitle: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), - swapDepth: PropTypes.number, - swapFrom: PropTypes.number, - swapLength: PropTypes.number, - title: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), - toggleChildrenVisibility: PropTypes.func, - treeId: PropTypes.string.isRequired, - treeIndex: PropTypes.number.isRequired - } +/** + * SortableNodeContentRenderer + * @param {Object} props Component props + * @returns {React.Component} A react component + */ +function SortableNodeContentRenderer(props) { + const { + // ReactSortableTreeProps + scaffoldBlockPxWidth, + toggleChildrenVisibility, + connectDragPreview, + connectDragSource, + isDragging, + canDrop, + canDrag, + node, + title, + subtitle, + draggedNode, + path, + treeIndex, + isSearchMatch, + isSearchFocus, + icons, + buttons, + className, + style, + didDrop, + lowerSiblingCounts, + listIndex, + swapFrom, + swapLength, + swapDepth, + treeId, // Not needed, but preserved for other renderers + isOver, // Not needed, but preserved for other renderers + parentNode, // Needed for dndManager + rowDirection, + // Pull remaining props and apply to the root element + ...otherProps + } = props; + const classes = useStyles(); + const nodeTitle = title || node.title; + const nodeSubtitle = subtitle || node.subtitle; - static defaultProps = { - buttons: [], - canDrag: false, - canDrop: false, - className: "", - draggedNode: null, - icons: [], - isSearchFocus: false, - isSearchMatch: false, - parentNode: null, - style: {}, - swapDepth: null, - swapFrom: null, - swapLength: null, - title: null, - toggleChildrenVisibility: null - } + const isDraggedDescendant = draggedNode && isDescendant(draggedNode, node); + const isLandingPadActive = !didDrop && isDragging; - render() { - const { - classes, + // Construct the scaffold representing the structure of the tree + const scaffold = []; + lowerSiblingCounts.forEach((lowerSiblingCount, index) => { + scaffold.push(( +
+ )); - // ReactSortableTreeProps - scaffoldBlockPxWidth, - toggleChildrenVisibility, - connectDragPreview, - connectDragSource, - isDragging, - canDrop, - canDrag, - node, - title, - subtitle, - draggedNode, - path, - treeIndex, - isSearchMatch, - isSearchFocus, - icons, - buttons, - className, - style, - didDrop, - lowerSiblingCounts, - listIndex, - swapFrom, - swapLength, - swapDepth, - treeId, // Not needed, but preserved for other renderers - isOver, // Not needed, but preserved for other renderers - parentNode, // Needed for dndManager - rowDirection, - ...otherProps - } = this.props; - const nodeTitle = title || node.title; - const nodeSubtitle = subtitle || node.subtitle; + if (treeIndex !== listIndex && index === swapDepth) { + // This row has been shifted, and is at the depth of + // the line pointing to the new destination + let highlightLineClass = ""; - const isDraggedDescendant = draggedNode && isDescendant(draggedNode, node); - const isLandingPadActive = !didDrop && isDragging; + if (listIndex === swapFrom + swapLength - 1) { + // This block is on the bottom (target) line + // This block points at the target block (where the row will go when released) + highlightLineClass = classes.highlightBottomLeftCorner; + } else if (treeIndex === swapFrom) { + // This block is on the top (source) line + highlightLineClass = classes.highlightTopLeftCorner; + } else { + // This block is between the bottom and top + highlightLineClass = classes.highlightLineVertical; + } - // Construct the scaffold representing the structure of the tree - const scaffold = []; - lowerSiblingCounts.forEach((lowerSiblingCount, index) => { scaffold.push((
)); + } + }); - if (treeIndex !== listIndex && index === swapDepth) { - // This row has been shifted, and is at the depth of - // the line pointing to the new destination - let highlightLineClass = ""; - - if (listIndex === swapFrom + swapLength - 1) { - // This block is on the bottom (target) line - // This block points at the target block (where the row will go when released) - highlightLineClass = styles.highlightBottomLeftCorner; - } else if (treeIndex === swapFrom) { - // This block is on the top (source) line - highlightLineClass = styles.highlightTopLeftCorner; - } else { - // This block is between the bottom and top - highlightLineClass = styles.highlightLineVertical; - } + const nodeContent = ( +
+ - scaffold.push(( -
- )); - } - }); - - const nodeContent = ( -
- + + + + {toggleChildrenVisibility && node.children && node.children.length > 0 && ( toggleChildrenVisibility({ node, path, treeIndex })} > - + - - {toggleChildrenVisibility && node.children && node.children.length > 0 && ( - toggleChildrenVisibility({ node, path, treeIndex })} + )} + {/* Set the row preview to be used during drag and drop */} + {connectDragPreview(( +
+ {scaffold} +
- - - )} - {/* Set the row preview to be used during drag and drop */} - {connectDragPreview(( -
- {scaffold} -
-
- - {typeof nodeTitle === "function" ? nodeTitle({ node, path, treeIndex }) : nodeTitle} - {node.isVisible === false && {"Hide from storefront"}} - {node.isPrivate && {"Admin only"}} - {node.isSecondary && {"Secondary nav only"}} - - - - {typeof nodeSubtitle === "function" ? nodeSubtitle({ node, path, treeIndex }) : nodeSubtitle} - -
+
+ + {typeof nodeTitle === "function" ? nodeTitle({ node, path, treeIndex }) : nodeTitle} + {node.isVisible === false && {"Hide from storefront"}} + {node.isPrivate && {"Admin only"}} + {node.isSecondary && {"Secondary nav only"}} + + + + {typeof nodeSubtitle === "function" ? nodeSubtitle({ node, path, treeIndex }) : nodeSubtitle} + +
-
- {buttons.map((button, index) => ( -
- {button} -
- ))} -
+
+ {buttons.map((button, index) => ( +
+ {button} +
+ ))}
- ))} - +
+ ))} + -
- ); +
+ ); - return canDrag - ? connectDragSource(nodeContent, { dropEffect: "copy" }) - : nodeContent; - } + return canDrag + ? connectDragSource(nodeContent, { dropEffect: "copy" }) + : nodeContent; } -export default withStyles(styles, { name: "RuiSortableNodeContentRenderer" })(SortableNodeContentRenderer); +SortableNodeContentRenderer.propTypes = { + buttons: PropTypes.arrayOf(PropTypes.node), + canDrag: PropTypes.bool, + canDrop: PropTypes.bool, + className: PropTypes.string, + classes: PropTypes.object, + connectDragPreview: PropTypes.func.isRequired, + connectDragSource: PropTypes.func.isRequired, + didDrop: PropTypes.bool.isRequired, // eslint-disable-line react/boolean-prop-naming + draggedNode: PropTypes.shape({}), + icons: PropTypes.arrayOf(PropTypes.node), + isDragging: PropTypes.bool.isRequired, + isOver: PropTypes.bool.isRequired, + isSearchFocus: PropTypes.bool, + isSearchMatch: PropTypes.bool, + listIndex: PropTypes.number.isRequired, + lowerSiblingCounts: PropTypes.arrayOf(PropTypes.number).isRequired, + node: PropTypes.shape({}).isRequired, + parentNode: PropTypes.shape({}), // Needed for dndManager + path: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])).isRequired, + rowDirection: PropTypes.string.isRequired, + scaffoldBlockPxWidth: PropTypes.number.isRequired, + style: PropTypes.shape({}), + subtitle: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + swapDepth: PropTypes.number, + swapFrom: PropTypes.number, + swapLength: PropTypes.number, + title: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + toggleChildrenVisibility: PropTypes.func, + treeId: PropTypes.string.isRequired, + treeIndex: PropTypes.number.isRequired +}; + +SortableNodeContentRenderer.defaultProps = { + buttons: [], + canDrag: false, + canDrop: false, + className: "", + draggedNode: null, + icons: [], + isSearchFocus: false, + isSearchMatch: false, + parentNode: null, + style: {}, + swapDepth: null, + swapFrom: null, + swapLength: null, + title: null, + toggleChildrenVisibility: null +}; + +export default SortableNodeContentRenderer; diff --git a/imports/plugins/core/navigation/client/components/SortableTheme.js b/imports/plugins/core/navigation/client/components/SortableTheme.js index 47ba3743081..75dd9db445b 100644 --- a/imports/plugins/core/navigation/client/components/SortableTheme.js +++ b/imports/plugins/core/navigation/client/components/SortableTheme.js @@ -1,7 +1,7 @@ import nodeContentRenderer from "./SortableNodeContentRenderer"; import treeNodeRenderer from "./SortableTreeNodeRenderer"; -module.exports = { +export default { nodeContentRenderer, treeNodeRenderer, scaffoldBlockPxWidth: 65, diff --git a/imports/plugins/core/navigation/server/i18n/index.js b/imports/plugins/core/navigation/server/i18n/index.js deleted file mode 100644 index b9674e1cbb8..00000000000 --- a/imports/plugins/core/navigation/server/i18n/index.js +++ /dev/null @@ -1,5 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import en from "./en.json"; - -loadTranslations([en]); diff --git a/imports/plugins/core/navigation/server/index.js b/imports/plugins/core/navigation/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/navigation/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/navigation/server/i18n/en.json b/imports/plugins/core/navigation/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/navigation/server/i18n/en.json rename to imports/plugins/core/navigation/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/navigation/server/no-meteor/i18n/index.js b/imports/plugins/core/navigation/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..20b7de3735e --- /dev/null +++ b/imports/plugins/core/navigation/server/no-meteor/i18n/index.js @@ -0,0 +1,5 @@ +import en from "./en.json"; + +export default { + translations: [...en] +}; diff --git a/imports/plugins/core/navigation/server/no-meteor/register.js b/imports/plugins/core/navigation/server/no-meteor/register.js index 0a08d6863fc..d28bed4ff22 100644 --- a/imports/plugins/core/navigation/server/no-meteor/register.js +++ b/imports/plugins/core/navigation/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import mutations from "./mutations"; import queries from "./queries"; import resolvers from "./resolvers"; @@ -13,6 +14,7 @@ export default async function register(app) { await app.registerPlugin({ label: "Navigation", name: "reaction-navigation", + i18n, collections: { NavigationItems: { name: "NavigationItems" diff --git a/imports/plugins/core/navigation/server/no-meteor/schemas/schema.graphql b/imports/plugins/core/navigation/server/no-meteor/schemas/schema.graphql index bb3c17685da..ebc98f877ef 100644 --- a/imports/plugins/core/navigation/server/no-meteor/schemas/schema.graphql +++ b/imports/plugins/core/navigation/server/no-meteor/schemas/schema.graphql @@ -16,10 +16,19 @@ extend type Query { "The ID of the shop to load navigation items for" shopId: ID! + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." last: ConnectionLimitInt, + + "Return results sorted in this order" sortOrder: SortOrder = desc, "By default, items are sorted by when they were created, newest first. Set this to sort by one of the other allowed fields" @@ -168,19 +177,34 @@ type NavigationTreeItem { extend type Mutation { "Create a new navigation item" - createNavigationItem(input: CreateNavigationItemInput!): CreateNavigationItemPayload + createNavigationItem( + "Mutation input" + input: CreateNavigationItemInput! + ): CreateNavigationItemPayload "Delete a navigation item" - deleteNavigationItem(input: DeleteNavigationItemInput!): DeleteNavigationItemPayload + deleteNavigationItem( + "Mutation input" + input: DeleteNavigationItemInput! + ): DeleteNavigationItemPayload "Publish the draft structure for a navigation tree and the draft changes for all of its navigation items. Sets hasUnpublishedChanges to false on tree and its items" - publishNavigationChanges(input: PublishNavigationChangesInput!): PublishNavigationChangesPayload + publishNavigationChanges( + "Mutation input" + input: PublishNavigationChangesInput! + ): PublishNavigationChangesPayload "Update an existing navigation item's draft data. Sets hasUnpublishedChanges to true" - updateNavigationItem(input: UpdateNavigationItemInput!): UpdateNavigationItemPayload + updateNavigationItem( + "Mutation input" + input: UpdateNavigationItemInput! + ): UpdateNavigationItemPayload "Update an existing navigation tree's draft items. Sets hasUnpublishedChanges to true" - updateNavigationTree(input: UpdateNavigationTreeInput!): UpdateNavigationTreePayload + updateNavigationTree( + "Mutation input" + input: UpdateNavigationTreeInput! + ): UpdateNavigationTreePayload } "Input for the `createNavigationItem` mutation" diff --git a/imports/plugins/core/orders/client/components/OrderCardFulfillmentGroups.js b/imports/plugins/core/orders/client/components/OrderCardFulfillmentGroups.js index f90e75391df..093eaa3d529 100644 --- a/imports/plugins/core/orders/client/components/OrderCardFulfillmentGroups.js +++ b/imports/plugins/core/orders/client/components/OrderCardFulfillmentGroups.js @@ -173,7 +173,7 @@ class OrderCardFulfillmentGroups extends Component { - + {i18next.t("order.fulfillmentGroupHeader", `Fulfillment group ${currentGroupCount} of ${totalGroupsCount}`)} @@ -232,7 +232,7 @@ class OrderCardFulfillmentGroups extends Component { {i18next.t("order.trackingNumber", "Tracking number")} - + diff --git a/imports/plugins/core/orders/client/components/OrderHeader.js b/imports/plugins/core/orders/client/components/OrderHeader.js index ebff1bf85fa..9bd51a9158a 100644 --- a/imports/plugins/core/orders/client/components/OrderHeader.js +++ b/imports/plugins/core/orders/client/components/OrderHeader.js @@ -56,7 +56,7 @@ function OrderHeader(props) { - + {i18next.t("order.order", "Order")} - {referenceId} @@ -80,7 +80,7 @@ function OrderHeader(props) { - {i18next.t("order.placed", "Placed")} {orderDate} + {i18next.t("order.placed", "Placed")} {orderDate} ); diff --git a/imports/plugins/core/orders/client/components/OrderPayments.js b/imports/plugins/core/orders/client/components/OrderPayments.js index 6f410a56fcb..dc3e0075c72 100644 --- a/imports/plugins/core/orders/client/components/OrderPayments.js +++ b/imports/plugins/core/orders/client/components/OrderPayments.js @@ -125,7 +125,7 @@ function OrderPayments(props) { - + Payments diff --git a/imports/plugins/core/orders/client/components/OrderRefunds.js b/imports/plugins/core/orders/client/components/OrderRefunds.js index 31b8828d775..00761b0fccf 100644 --- a/imports/plugins/core/orders/client/components/OrderRefunds.js +++ b/imports/plugins/core/orders/client/components/OrderRefunds.js @@ -189,7 +189,7 @@ function OrderRefunds(props) { const paymentAmountAvailableForRefundDisplay = formatMoney(paymentAmountAvailableForRefund, order.currencyCode); return ( - + @@ -204,9 +204,9 @@ function OrderRefunds(props) { {i18next.t("order.availableToRefund")}: {paymentAmountAvailableForRefundDisplay} {paymentPreviousRefundTotal && paymentPreviousRefundTotal > 0 && - - {i18next.t("order.previouslyRefunded")}: {paymentPreviousRefundTotalDisplay} - + + {i18next.t("order.previouslyRefunded")}: {paymentPreviousRefundTotalDisplay} + } : diff --git a/imports/plugins/core/orders/server/i18n/index.js b/imports/plugins/core/orders/server/i18n/index.js deleted file mode 100644 index 2d1a40cefec..00000000000 --- a/imports/plugins/core/orders/server/i18n/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/orders/server/index.js b/imports/plugins/core/orders/server/index.js index dffd659cd46..5917285aded 100644 --- a/imports/plugins/core/orders/server/index.js +++ b/imports/plugins/core/orders/server/index.js @@ -1,2 +1 @@ -import "./i18n"; import "../lib/extendShopSchema"; diff --git a/imports/plugins/core/orders/server/i18n/ar.json b/imports/plugins/core/orders/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/ar.json rename to imports/plugins/core/orders/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/orders/server/i18n/bg.json b/imports/plugins/core/orders/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/bg.json rename to imports/plugins/core/orders/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/orders/server/i18n/cs.json b/imports/plugins/core/orders/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/cs.json rename to imports/plugins/core/orders/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/orders/server/i18n/de.json b/imports/plugins/core/orders/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/de.json rename to imports/plugins/core/orders/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/orders/server/i18n/el.json b/imports/plugins/core/orders/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/el.json rename to imports/plugins/core/orders/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/orders/server/i18n/en.json b/imports/plugins/core/orders/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/en.json rename to imports/plugins/core/orders/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/orders/server/i18n/es.json b/imports/plugins/core/orders/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/es.json rename to imports/plugins/core/orders/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/orders/server/i18n/fr.json b/imports/plugins/core/orders/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/fr.json rename to imports/plugins/core/orders/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/orders/server/i18n/he.json b/imports/plugins/core/orders/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/he.json rename to imports/plugins/core/orders/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/orders/server/i18n/hr.json b/imports/plugins/core/orders/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/hr.json rename to imports/plugins/core/orders/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/orders/server/i18n/hu.json b/imports/plugins/core/orders/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/hu.json rename to imports/plugins/core/orders/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/orders/server/no-meteor/i18n/index.js b/imports/plugins/core/orders/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..9deb0a6b6e7 --- /dev/null +++ b/imports/plugins/core/orders/server/no-meteor/i18n/index.js @@ -0,0 +1,54 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/orders/server/i18n/it.json b/imports/plugins/core/orders/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/it.json rename to imports/plugins/core/orders/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/orders/server/i18n/my.json b/imports/plugins/core/orders/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/my.json rename to imports/plugins/core/orders/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/orders/server/i18n/nb.json b/imports/plugins/core/orders/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/nb.json rename to imports/plugins/core/orders/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/orders/server/i18n/nl.json b/imports/plugins/core/orders/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/nl.json rename to imports/plugins/core/orders/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/orders/server/i18n/pl.json b/imports/plugins/core/orders/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/pl.json rename to imports/plugins/core/orders/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/orders/server/i18n/pt.json b/imports/plugins/core/orders/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/pt.json rename to imports/plugins/core/orders/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/orders/server/i18n/ro.json b/imports/plugins/core/orders/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/ro.json rename to imports/plugins/core/orders/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/orders/server/i18n/ru.json b/imports/plugins/core/orders/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/ru.json rename to imports/plugins/core/orders/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/orders/server/i18n/sl.json b/imports/plugins/core/orders/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/sl.json rename to imports/plugins/core/orders/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/orders/server/i18n/sv.json b/imports/plugins/core/orders/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/sv.json rename to imports/plugins/core/orders/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/orders/server/i18n/tr.json b/imports/plugins/core/orders/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/tr.json rename to imports/plugins/core/orders/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/orders/server/i18n/vi.json b/imports/plugins/core/orders/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/vi.json rename to imports/plugins/core/orders/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/orders/server/i18n/zh.json b/imports/plugins/core/orders/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/orders/server/i18n/zh.json rename to imports/plugins/core/orders/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/orders/server/no-meteor/register.js b/imports/plugins/core/orders/server/no-meteor/register.js index a44878cadfe..d75336489b4 100644 --- a/imports/plugins/core/orders/server/no-meteor/register.js +++ b/imports/plugins/core/orders/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import mutations from "./mutations"; import queries from "./queries"; import resolvers from "./resolvers"; @@ -15,6 +16,7 @@ export default async function register(app) { label: "Orders", name: "reaction-orders", icon: "fa fa-sun-o", + i18n, collections: { Orders: { name: "Orders", diff --git a/imports/plugins/core/orders/server/no-meteor/schemas/schema.graphql b/imports/plugins/core/orders/server/no-meteor/schemas/schema.graphql index c4ff6545f32..37f7ee9573e 100644 --- a/imports/plugins/core/orders/server/no-meteor/schemas/schema.graphql +++ b/imports/plugins/core/orders/server/no-meteor/schemas/schema.graphql @@ -1,10 +1,22 @@ extend type Query { "Get an order by its ID" - orderById(id: ID!, shopId: ID!, token: String): Order + orderById( + "The order ID" + id: ID!, + + "The shop that owns the order" + shopId: ID!, + + "A valid anonymous access token for this order. Required if the order is not linked with an account." + token: String + ): Order "Get all orders for a single account, optionally limited to certain shop IDs and certain orderStatus" orders( + "A filter string" filter: String + + "Limit to orders with one of these statuses" orderStatus: [String] "Provide a list of shop IDs from which you want to get orders from" @@ -28,34 +40,78 @@ extend type Query { "Return results sorted in this order" sortOrder: SortOrder = desc, - "By default, items are sorted by when they were created, newest first. Set this to sort by one of the other allowed fields" + "By default, orders are sorted by when they were created, newest first. Set this to sort by one of the other allowed fields" sortBy: OrdersSortByField = createdAt ): OrderConnection! "Get all orders for a single account, optionally limited to certain shop IDs and certain orderStatus" ordersByAccountId( - accountId: ID! - orderStatus: [String] - shopIds: [ID] + "Limit to orders placed by this account" + accountId: ID!, + + "Limit to orders with one of these statuses" + orderStatus: [String], + + "Limit to orders owned by one of these shops" + shopIds: [ID], + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." last: ConnectionLimitInt, + + "Return results sorted in this order" sortOrder: SortOrder = desc, - "By default, items are sorted by when they were created, newest first. Set this to sort by one of the other allowed fields" + "By default, orders are sorted by when they were created, newest first. Set this to sort by one of the other allowed fields" sortBy: OrdersByAccountIdSortByField = createdAt ): OrdersByAccountIdConnection! "Get an order by its reference ID (the ID shown to customers)" - orderByReferenceId(id: ID!, shopId: ID!, token: String): Order + orderByReferenceId( + "The order reference ID (the ID shown to customers)" + id: ID!, + + "The shop that owns the order" + shopId: ID!, + + "A valid anonymous access token for this order. Required if the order is not linked with an account." + token: String + ): Order "Get refunds applied to an order by order ID" - refunds(orderId: ID!, shopId: ID!, token: String): [Refund] + refunds( + "The order ID" + orderId: ID!, + + "The shop that owns the order" + shopId: ID!, + + "A valid anonymous access token for this order. Required if the order is not linked with an account." + token: String + ): [Refund] "Get refunds applied to a specific payment by payment ID" - refundsByPaymentId(orderId: ID!, paymentId: ID!, shopId: ID!, token: String): [Refund] + refundsByPaymentId( + "The order ID" + orderId: ID!, + + "The ID of one of the payments made for this order" + paymentId: ID!, + + "The shop that owns the order" + shopId: ID!, + + "A valid anonymous access token for this order. Required if the order is not linked with an account." + token: String + ): [Refund] } extend type Mutation { @@ -63,7 +119,10 @@ extend type Mutation { Use this mutation to add a new order fulfillment group to an order. It must have at least one item. Items may be provided or moved from another existing group or both. """ - addOrderFulfillmentGroup(input: AddOrderFulfillmentGroupInput!): AddOrderFulfillmentGroupPayload! + addOrderFulfillmentGroup( + "Mutation input" + input: AddOrderFulfillmentGroupInput! + ): AddOrderFulfillmentGroupPayload! """ Use this mutation to cancel one item of an order, either for the full ordered quantity @@ -74,21 +133,33 @@ extend type Mutation { be canceled. If this results in all fulfillment groups being canceled, the full order will also be canceled. """ - cancelOrderItem(input: CancelOrderItemInput!): CancelOrderItemPayload! + cancelOrderItem( + "Mutation input" + input: CancelOrderItemInput! + ): CancelOrderItemPayload! "Use this mutation to create a refund on a payment method used to make the order" - createRefund(input: CreateRefundInput!): CreateRefundPayload! + createRefund( + "Mutation input" + input: CreateRefundInput! + ): CreateRefundPayload! """ Use this mutation to move one or more items between existing order fulfillment groups. """ - moveOrderItems(input: MoveOrderItemsInput!): MoveOrderItemsPayload! + moveOrderItems( + "Mutation input" + input: MoveOrderItemsInput! + ): MoveOrderItemsPayload! """ Use this mutation to place an order, providing information necessary to pay for it. The order will be placed only if authorization is successful for all submitted payments. """ - placeOrder(input: PlaceOrderInput!): PlaceOrderPayload! + placeOrder( + "Mutation input" + input: PlaceOrderInput! + ): PlaceOrderPayload! """ Use this mutation to reduce the quantity of one item of an order and create @@ -96,17 +167,26 @@ extend type Mutation { same item status. You may want to do this if you are only able to partially fulfill the item order right now. """ - splitOrderItem(input: SplitOrderItemInput!): SplitOrderItemPayload! + splitOrderItem( + "Mutation input" + input: SplitOrderItemInput! + ): SplitOrderItemPayload! """ Use this mutation to update order details after the order has been placed. """ - updateOrder(input: UpdateOrderInput!): UpdateOrderPayload! + updateOrder( + "Mutation input" + input: UpdateOrderInput! + ): UpdateOrderPayload! """ Use this mutation to update an order fulfillment group status and tracking information. """ - updateOrderFulfillmentGroup(input: UpdateOrderFulfillmentGroupInput!): UpdateOrderFulfillmentGroupPayload! + updateOrderFulfillmentGroup( + "Mutation input" + input: UpdateOrderFulfillmentGroupInput! + ): UpdateOrderFulfillmentGroupPayload! } "Allowed values for the `OrderFulfillmentGroupItems` sortBy parameter" @@ -321,7 +401,25 @@ type OrderItem implements Node { productSlug: String "The list of tags that have been applied to this product" - productTags(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = asc, sortBy: TagSortByField = _id): TagConnection + productTags( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = asc, + + "By default, tags are sorted by ID. Set this to sort by one of the other allowed fields" + sortBy: TagSortByField = _id + ): TagConnection "The type of product, used to display cart items differently" productType: String @@ -371,10 +469,34 @@ type OrderFulfillmentGroup implements Node { data: OrderFulfillmentGroupData "The order status for display in UI" - displayStatus(language: String!): String! + displayStatus( + """ + The language in which you want the status. If no translation is available for this language, + it will be in the default language of the shop that owns the order. + """ + language: String! + ): String! "The items that are part of this fulfillment group" - items(after: ConnectionCursor, before: ConnectionCursor, first: ConnectionLimitInt, last: ConnectionLimitInt, sortOrder: SortOrder = desc, sortBy: OrderFulfillmentGroupItemsSortByField = addedAt): OrderItemConnection + items( + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." + after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." + before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." + first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." + last: ConnectionLimitInt, + + "Return results sorted in this order" + sortOrder: SortOrder = desc, + + "By default, order items are sorted by when they were added to the order, newest first. Set this to sort by one of the other allowed fields" + sortBy: OrderFulfillmentGroupItemsSortByField = addedAt + ): OrderItemConnection "The fulfillment method that was selected, with its price quote" selectedFulfillmentOption: FulfillmentOption! @@ -421,7 +543,13 @@ type Order implements Node { createdAt: DateTime! "The order status for display in UI" - displayStatus(language: String!): String! + displayStatus( + """ + The language in which you want the status. If no translation is available for this language, + it will be in the default language of the shop that owns the order. + """ + language: String! + ): String! "An email address that has been associated with the cart" email: String diff --git a/imports/plugins/core/payments/server/i18n/index.js b/imports/plugins/core/payments/server/i18n/index.js deleted file mode 100644 index 2d1a40cefec..00000000000 --- a/imports/plugins/core/payments/server/i18n/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/payments/server/index.js b/imports/plugins/core/payments/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/payments/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/payments/server/i18n/ar.json b/imports/plugins/core/payments/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/ar.json rename to imports/plugins/core/payments/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/payments/server/i18n/bg.json b/imports/plugins/core/payments/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/bg.json rename to imports/plugins/core/payments/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/payments/server/i18n/cs.json b/imports/plugins/core/payments/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/cs.json rename to imports/plugins/core/payments/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/payments/server/i18n/de.json b/imports/plugins/core/payments/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/de.json rename to imports/plugins/core/payments/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/payments/server/i18n/el.json b/imports/plugins/core/payments/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/el.json rename to imports/plugins/core/payments/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/payments/server/i18n/en.json b/imports/plugins/core/payments/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/en.json rename to imports/plugins/core/payments/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/payments/server/i18n/es.json b/imports/plugins/core/payments/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/es.json rename to imports/plugins/core/payments/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/payments/server/i18n/fr.json b/imports/plugins/core/payments/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/fr.json rename to imports/plugins/core/payments/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/payments/server/i18n/he.json b/imports/plugins/core/payments/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/he.json rename to imports/plugins/core/payments/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/payments/server/i18n/hr.json b/imports/plugins/core/payments/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/hr.json rename to imports/plugins/core/payments/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/payments/server/i18n/hu.json b/imports/plugins/core/payments/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/hu.json rename to imports/plugins/core/payments/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/payments/server/no-meteor/i18n/index.js b/imports/plugins/core/payments/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..9deb0a6b6e7 --- /dev/null +++ b/imports/plugins/core/payments/server/no-meteor/i18n/index.js @@ -0,0 +1,54 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/payments/server/i18n/it.json b/imports/plugins/core/payments/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/it.json rename to imports/plugins/core/payments/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/payments/server/i18n/my.json b/imports/plugins/core/payments/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/my.json rename to imports/plugins/core/payments/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/payments/server/i18n/nb.json b/imports/plugins/core/payments/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/nb.json rename to imports/plugins/core/payments/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/payments/server/i18n/nl.json b/imports/plugins/core/payments/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/nl.json rename to imports/plugins/core/payments/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/payments/server/i18n/pl.json b/imports/plugins/core/payments/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/pl.json rename to imports/plugins/core/payments/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/payments/server/i18n/pt.json b/imports/plugins/core/payments/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/pt.json rename to imports/plugins/core/payments/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/payments/server/i18n/ro.json b/imports/plugins/core/payments/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/ro.json rename to imports/plugins/core/payments/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/payments/server/i18n/ru.json b/imports/plugins/core/payments/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/ru.json rename to imports/plugins/core/payments/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/payments/server/i18n/sl.json b/imports/plugins/core/payments/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/sl.json rename to imports/plugins/core/payments/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/payments/server/i18n/sv.json b/imports/plugins/core/payments/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/sv.json rename to imports/plugins/core/payments/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/payments/server/i18n/tr.json b/imports/plugins/core/payments/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/tr.json rename to imports/plugins/core/payments/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/payments/server/i18n/vi.json b/imports/plugins/core/payments/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/vi.json rename to imports/plugins/core/payments/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/payments/server/i18n/zh.json b/imports/plugins/core/payments/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/payments/server/i18n/zh.json rename to imports/plugins/core/payments/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/payments/server/no-meteor/register.js b/imports/plugins/core/payments/server/no-meteor/register.js index e50ad29b7fa..3e2b730b1fa 100644 --- a/imports/plugins/core/payments/server/no-meteor/register.js +++ b/imports/plugins/core/payments/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import mutations from "./mutations"; import queries from "./queries"; import { registerPluginHandler } from "./registration"; @@ -14,6 +15,7 @@ export default async function register(app) { label: "Payments", name: "reaction-payments", icon: "fa fa-credit-card", + i18n, functionsByType: { registerPluginHandler: [registerPluginHandler] }, diff --git a/imports/plugins/core/payments/server/no-meteor/schemas/schema.graphql b/imports/plugins/core/payments/server/no-meteor/schemas/schema.graphql index 2058b196356..d5697569110 100644 --- a/imports/plugins/core/payments/server/no-meteor/schemas/schema.graphql +++ b/imports/plugins/core/payments/server/no-meteor/schemas/schema.graphql @@ -4,21 +4,36 @@ extend type Query { active/inactive, IP/region, shop, etc. To get the full list, use the `paymentMethods` query with proper authorization. """ - availablePaymentMethods(shopId: ID!): [PaymentMethod]! + availablePaymentMethods( + "ID of the shop for which the order will be placed" + shopId: ID! + ): [PaymentMethod]! "Get a full list of all payment methods" - paymentMethods(shopId: ID!): [PaymentMethod]! + paymentMethods( + "The shop to get payment methods for" + shopId: ID! + ): [PaymentMethod]! } extend type Mutation { "Approve one or more payments for an order" - approveOrderPayments(input: ApproveOrderPaymentsInput!): ApproveOrderPaymentsPayload! + approveOrderPayments( + "Mutation input" + input: ApproveOrderPaymentsInput! + ): ApproveOrderPaymentsPayload! "Capture one or more payments for an order" - captureOrderPayments(input: CaptureOrderPaymentsInput!): CaptureOrderPaymentsPayload! + captureOrderPayments( + "Mutation input" + input: CaptureOrderPaymentsInput! + ): CaptureOrderPaymentsPayload! "Enable a payment method for a shop" - enablePaymentMethodForShop(input: EnablePaymentMethodForShopInput!): EnablePaymentMethodForShopPayload! + enablePaymentMethodForShop( + "Mutation input" + input: EnablePaymentMethodForShopInput! + ): EnablePaymentMethodForShopPayload! } """ diff --git a/imports/plugins/core/router/client/startup.js b/imports/plugins/core/router/client/startup.js index 2696d354ccf..db0054810e5 100644 --- a/imports/plugins/core/router/client/startup.js +++ b/imports/plugins/core/router/client/startup.js @@ -17,21 +17,18 @@ Meteor.startup(() => { // or missing shop data throughout the app. // TODO: Revisit subscriptions manager usage and waiting for shops to exist client side before rendering. const primaryShopSub = Meteor.subscribe("PrimaryShop"); - const merchantShopSub = Meteor.subscribe("MerchantShops"); const packageSub = Meteor.subscribe("Packages"); // initialize client routing Tracker.autorun((computation) => { // All of these are reactive const primaryShopSubIsReady = primaryShopSub.ready(); - const merchantShopSubIsReady = merchantShopSub.ready(); const packageSubIsReady = packageSub.ready(); const primaryShopId = Reaction.getPrimaryShopId(); const hasShops = !!Shops.findOne(); if ( primaryShopSubIsReady && - merchantShopSubIsReady && packageSubIsReady && primaryShopId && hasShops diff --git a/imports/plugins/core/settings/server/schemas/settings.graphql b/imports/plugins/core/settings/server/schemas/settings.graphql index 8cdcd762e42..3b96bf3b479 100644 --- a/imports/plugins/core/settings/server/schemas/settings.graphql +++ b/imports/plugins/core/settings/server/schemas/settings.graphql @@ -32,7 +32,10 @@ extend type Query { Returns app settings for a specific shop. Plugins extend the ShopSettings type to support whatever settings they need. """ - shopSettings(shopId: ID!): ShopSettings! + shopSettings( + "The shop to get app settings for" + shopId: ID! + ): ShopSettings! } ## @@ -44,7 +47,10 @@ extend type Mutation { Returns app settings that are not shop specific. Plugins extend the GlobalSettings type to support whatever settings they need. """ - updateGlobalSettings(input: UpdateGlobalSettingsInput!): UpdateGlobalSettingsPayload! + updateGlobalSettings( + "Mutation input" + input: UpdateGlobalSettingsInput! + ): UpdateGlobalSettingsPayload! } "Input for the `updateGlobalSettings` mutation" @@ -84,7 +90,10 @@ extend type Mutation { Returns app settings for a specific shop. Plugins extend the ShopSettings type to support whatever settings they need. """ - updateShopSettings(input: UpdateShopSettingsInput!): UpdateShopSettingsPayload! + updateShopSettings( + "Mutation input" + input: UpdateShopSettingsInput! + ): UpdateShopSettingsPayload! } "Input for the `updateShopSettings` mutation" diff --git a/imports/plugins/core/shipping/server/i18n/index.js b/imports/plugins/core/shipping/server/i18n/index.js deleted file mode 100644 index 2d1a40cefec..00000000000 --- a/imports/plugins/core/shipping/server/i18n/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/shipping/server/index.js b/imports/plugins/core/shipping/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/shipping/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/shipping/server/i18n/ar.json b/imports/plugins/core/shipping/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/ar.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/core/shipping/server/i18n/bg.json b/imports/plugins/core/shipping/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/bg.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/core/shipping/server/i18n/cs.json b/imports/plugins/core/shipping/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/cs.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/core/shipping/server/i18n/de.json b/imports/plugins/core/shipping/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/de.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/de.json diff --git a/imports/plugins/core/shipping/server/i18n/el.json b/imports/plugins/core/shipping/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/el.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/el.json diff --git a/imports/plugins/core/shipping/server/i18n/en.json b/imports/plugins/core/shipping/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/en.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/en.json diff --git a/imports/plugins/core/shipping/server/i18n/es.json b/imports/plugins/core/shipping/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/es.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/es.json diff --git a/imports/plugins/core/shipping/server/i18n/fr.json b/imports/plugins/core/shipping/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/fr.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/core/shipping/server/i18n/he.json b/imports/plugins/core/shipping/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/he.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/shipping/server/i18n/hr.json b/imports/plugins/core/shipping/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/hr.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/core/shipping/server/i18n/hu.json b/imports/plugins/core/shipping/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/hu.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/core/shipping/server/no-meteor/i18n/index.js b/imports/plugins/core/shipping/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..9deb0a6b6e7 --- /dev/null +++ b/imports/plugins/core/shipping/server/no-meteor/i18n/index.js @@ -0,0 +1,54 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/shipping/server/i18n/it.json b/imports/plugins/core/shipping/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/it.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/it.json diff --git a/imports/plugins/core/shipping/server/i18n/my.json b/imports/plugins/core/shipping/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/my.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/my.json diff --git a/imports/plugins/core/shipping/server/i18n/nb.json b/imports/plugins/core/shipping/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/nb.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/shipping/server/i18n/nl.json b/imports/plugins/core/shipping/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/nl.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/core/shipping/server/i18n/pl.json b/imports/plugins/core/shipping/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/pl.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/core/shipping/server/i18n/pt.json b/imports/plugins/core/shipping/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/pt.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/core/shipping/server/i18n/ro.json b/imports/plugins/core/shipping/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/ro.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/core/shipping/server/i18n/ru.json b/imports/plugins/core/shipping/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/ru.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/core/shipping/server/i18n/sl.json b/imports/plugins/core/shipping/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/sl.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/core/shipping/server/i18n/sv.json b/imports/plugins/core/shipping/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/sv.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/core/shipping/server/i18n/tr.json b/imports/plugins/core/shipping/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/tr.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/core/shipping/server/i18n/vi.json b/imports/plugins/core/shipping/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/vi.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/core/shipping/server/i18n/zh.json b/imports/plugins/core/shipping/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/core/shipping/server/i18n/zh.json rename to imports/plugins/core/shipping/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/core/shipping/server/no-meteor/register.js b/imports/plugins/core/shipping/server/no-meteor/register.js index fe1c53013fc..be469e56289 100644 --- a/imports/plugins/core/shipping/server/no-meteor/register.js +++ b/imports/plugins/core/shipping/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import mutations from "./mutations"; import queries from "./queries"; import resolvers from "./resolvers"; @@ -13,6 +14,7 @@ export default async function register(app) { label: "Shipping", name: "reaction-shipping", icon: "fa fa-truck", + i18n, graphQL: { resolvers, schemas diff --git a/imports/plugins/core/shop/server/schemas/schema.graphql b/imports/plugins/core/shop/server/schemas/schema.graphql index a56f7b12f36..6a827282e98 100644 --- a/imports/plugins/core/shop/server/schemas/schema.graphql +++ b/imports/plugins/core/shop/server/schemas/schema.graphql @@ -46,7 +46,13 @@ type Shop implements Node { currency: Currency "The default navigation tree for this shop" - defaultNavigationTree(language: String!, shouldIncludeSecondary: Boolean = false): NavigationTree + defaultNavigationTree( + "Navigation tree language" + language: String!, + + "Whether to include secondary navigation items" + shouldIncludeSecondary: Boolean = false + ): NavigationTree "The ID of the shop's default navigation tree" defaultNavigationTreeId: String @@ -74,10 +80,19 @@ type Shop implements Node { "Set to true if you want soft deleted tags to be included in the response" shouldIncludeDeleted: Boolean = false, + "Return only results that come after this cursor. Use this with `first` to specify the number of results to return." after: ConnectionCursor, + + "Return only results that come before this cursor. Use this with `last` to specify the number of results to return." before: ConnectionCursor, + + "Return at most this many results. This parameter may be used with either `after` or `offset` parameters." first: ConnectionLimitInt, + + "Return at most this many results. This parameter may be used with the `before` parameter." last: ConnectionLimitInt, + + "Return results sorted in this order" sortOrder: SortOrder = asc, "By default, tags are sorted by position. Set this to sort by one of the other allowed fields" @@ -93,8 +108,14 @@ extend type Query { primaryShopId: ID "Returns a shop by ID" - shop(id: ID!): Shop + shop( + "The shop ID" + id: ID! + ): Shop "Returns a shop by slug" - shopBySlug(slug: String!): Shop + shopBySlug( + "The shop slug" + slug: String! + ): Shop } diff --git a/imports/plugins/core/shop/server/schemas/updateShop.graphql b/imports/plugins/core/shop/server/schemas/updateShop.graphql index 1d7caa77a03..73f72fe932f 100644 --- a/imports/plugins/core/shop/server/schemas/updateShop.graphql +++ b/imports/plugins/core/shop/server/schemas/updateShop.graphql @@ -48,5 +48,8 @@ type UpdateShopPayload { extend type Mutation { "Given shop data, update the Shops collection with this data" - updateShop(input: UpdateShopInput!): UpdateShopPayload! + updateShop( + "Mutation input" + input: UpdateShopInput! + ): UpdateShopPayload! } diff --git a/imports/plugins/core/system-info/server/no-meteor/schemas/schema.graphql b/imports/plugins/core/system-info/server/no-meteor/schemas/schema.graphql index b5f8a406bd5..02fa5b0daf2 100644 --- a/imports/plugins/core/system-info/server/no-meteor/schemas/schema.graphql +++ b/imports/plugins/core/system-info/server/no-meteor/schemas/schema.graphql @@ -1,7 +1,11 @@ extend type Query { "SystemInformation object" - systemInformation(shopId: ID!): SystemInformation! + systemInformation( + "Shop ID to use for shop-specific system information" + shopId: ID! + ): SystemInformation! } + "Represents Reaction Plugin" type Plugin { "Name of plugin" @@ -9,6 +13,7 @@ type Plugin { "Version of plugin" version: String } + "Represents Mongo Database information" type DatabaseInformation { "Version of database" diff --git a/imports/plugins/core/tags/client/components/TagDataTable.js b/imports/plugins/core/tags/client/components/TagDataTable.js index 9253ab9a152..023f87b378b 100644 --- a/imports/plugins/core/tags/client/components/TagDataTable.js +++ b/imports/plugins/core/tags/client/components/TagDataTable.js @@ -567,14 +567,14 @@ class TagDataTable extends Component { disabled={!hasPreviousPage} > - {i18next.t("admin.routing.tableText.previousText")} + {i18next.t("admin.tags.tableText.previousText")} diff --git a/imports/plugins/core/tags/client/components/TagForm.js b/imports/plugins/core/tags/client/components/TagForm.js index 43909025d6b..994da548906 100644 --- a/imports/plugins/core/tags/client/components/TagForm.js +++ b/imports/plugins/core/tags/client/components/TagForm.js @@ -86,9 +86,9 @@ class TagForm extends Component { } static defaultProps = { - onCancel() {}, - onCreate() {}, - onUpdate() {}, + onCancel() { }, + onCreate() { }, + onUpdate() { }, tag: {} } @@ -311,7 +311,6 @@ class TagForm extends Component { diff --git a/imports/plugins/core/tags/client/components/TagToolbar.js b/imports/plugins/core/tags/client/components/TagToolbar.js index 9d661a80d6d..8c106cf0aad 100644 --- a/imports/plugins/core/tags/client/components/TagToolbar.js +++ b/imports/plugins/core/tags/client/components/TagToolbar.js @@ -16,14 +16,13 @@ function TagToolbar(props) { {(canBeDeleted) && } -
diff --git a/imports/plugins/core/ui-navbar/client/containers/navbar.js b/imports/plugins/core/ui-navbar/client/containers/navbar.js index c1d8b1e5f3d..cc0b8ff9d38 100644 --- a/imports/plugins/core/ui-navbar/client/containers/navbar.js +++ b/imports/plugins/core/ui-navbar/client/containers/navbar.js @@ -13,9 +13,6 @@ import { Media } from "/imports/plugins/core/files/client"; * @returns {undefined} */ export function composer(props, onData) { - const shopSub = Meteor.subscribe("MerchantShops", Reaction.getShopsForUser(["admin"])); - if (!shopSub.ready()) return; - const shop = Shops.findOne({ _id: Reaction.getShopId() }); if (!shop) throw new Error(`No shop found with shop ID ${Reaction.getShopId()}`); diff --git a/imports/plugins/core/ui-navbar/server/i18n/en.json b/imports/plugins/core/ui-navbar/server/i18n/en.json deleted file mode 100644 index 331124a72d0..00000000000 --- a/imports/plugins/core/ui-navbar/server/i18n/en.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-ui-navbar", - "translation": { - "reaction-ui-navbar": { - "admin": { - "shortcut": {}, - "dashboard": {}, - "settings": {} - } - } - } -}] diff --git a/imports/plugins/core/ui-navbar/server/i18n/index.js b/imports/plugins/core/ui-navbar/server/i18n/index.js deleted file mode 100644 index 30788be39c3..00000000000 --- a/imports/plugins/core/ui-navbar/server/i18n/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -// import ar from "./ar.json"; -// import bg from "./bg.json"; -// import de from "./de.json"; -// import el from "./el.json"; -import en from "./en.json"; -// import es from "./es.json"; -// import fr from "./fr.json"; -// import he from "./he.json"; -// import hr from "./hr.json"; -// import it from "./it.json"; -// import my from "./my.json"; -// import nb from "./nb.json"; -// import nl from "./nl.json"; -// import pl from "./pl.json"; -// import pt from "./pt.json"; -// import ro from "./ro.json"; -// import ru from "./ru.json"; -// import sl from "./sl.json"; -// import sv from "./sv.json"; -// import tr from "./tr.json"; -// import vi from "./vi.json"; -// import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([en]); -// loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/ui-navbar/server/index.js b/imports/plugins/core/ui-navbar/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/ui-navbar/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/ui-tagnav/server/i18n/en.json b/imports/plugins/core/ui-tagnav/server/i18n/en.json deleted file mode 100644 index d67e51016c5..00000000000 --- a/imports/plugins/core/ui-tagnav/server/i18n/en.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-ui-tagnav", - "translation": { - "reaction-ui-tagnav": { - "admin": { - "shortcut": {}, - "dashboard": {}, - "settings": {} - } - } - } -}] diff --git a/imports/plugins/core/ui-tagnav/server/i18n/index.js b/imports/plugins/core/ui-tagnav/server/i18n/index.js deleted file mode 100644 index 30788be39c3..00000000000 --- a/imports/plugins/core/ui-tagnav/server/i18n/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -// import ar from "./ar.json"; -// import bg from "./bg.json"; -// import de from "./de.json"; -// import el from "./el.json"; -import en from "./en.json"; -// import es from "./es.json"; -// import fr from "./fr.json"; -// import he from "./he.json"; -// import hr from "./hr.json"; -// import it from "./it.json"; -// import my from "./my.json"; -// import nb from "./nb.json"; -// import nl from "./nl.json"; -// import pl from "./pl.json"; -// import pt from "./pt.json"; -// import ro from "./ro.json"; -// import ru from "./ru.json"; -// import sl from "./sl.json"; -// import sv from "./sv.json"; -// import tr from "./tr.json"; -// import vi from "./vi.json"; -// import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([en]); -// loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/ui-tagnav/server/index.js b/imports/plugins/core/ui-tagnav/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/ui-tagnav/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/ui/client/components/media/mediaItem.js b/imports/plugins/core/ui/client/components/media/mediaItem.js index 39f2530505d..e7746802841 100644 --- a/imports/plugins/core/ui/client/components/media/mediaItem.js +++ b/imports/plugins/core/ui/client/components/media/mediaItem.js @@ -72,7 +72,7 @@ class MediaItem extends Component { @@ -83,7 +83,7 @@ class MediaItem extends Component { @@ -104,7 +104,7 @@ class MediaItem extends Component { ); diff --git a/imports/plugins/core/ui/client/components/media/mediaUploader.js b/imports/plugins/core/ui/client/components/media/mediaUploader.js index eac2e47cdab..5a60ab18d89 100644 --- a/imports/plugins/core/ui/client/components/media/mediaUploader.js +++ b/imports/plugins/core/ui/client/components/media/mediaUploader.js @@ -2,7 +2,7 @@ import React, { useState } from "react"; import PropTypes from "prop-types"; import { Meteor } from "meteor/meteor"; import { useDropzone } from "react-dropzone"; -import Button from "@material-ui/core/Button"; +import Button from "@reactioncommerce/catalyst/Button"; import LinearProgress from "@material-ui/core/LinearProgress"; import { FileRecord } from "@reactioncommerce/file-collections"; import { registerComponent } from "@reactioncommerce/reaction-components"; @@ -92,7 +92,11 @@ function MediaUploader(props) { return (
- {isUploading ? : } + {isUploading ? + + : + + }
); } diff --git a/imports/plugins/core/ui/client/providers/translationProvider.js b/imports/plugins/core/ui/client/providers/translationProvider.js index 9286d9f1b4d..12196eacba1 100644 --- a/imports/plugins/core/ui/client/providers/translationProvider.js +++ b/imports/plugins/core/ui/client/providers/translationProvider.js @@ -1,8 +1,7 @@ -import { Session } from "meteor/session"; import React, { Component, Children } from "react"; // eslint-disable-line import PropTypes from "prop-types"; import { composeWithTracker } from "@reactioncommerce/reaction-components"; -import { i18nextDep } from "/client/api"; +import { i18next, i18nextDep } from "/client/api"; class TranslationProvider extends Component { getChildContext() { @@ -35,7 +34,7 @@ function composer(props, onData) { onData(null, { translations: { - language: Session.get("language") + language: i18next.language } }); } diff --git a/imports/plugins/core/ui/register.js b/imports/plugins/core/ui/register.js new file mode 100644 index 00000000000..add1f847771 --- /dev/null +++ b/imports/plugins/core/ui/register.js @@ -0,0 +1,11 @@ +/** + * This file is necessary for backwards compatibility while we refactor + * the API to remove Meteor. The no-meteor `register.js` file will + * eventually become the main entry point of the plugin, but for now + * our Meteor tooling loads this file, so we include this here as a + * temporary bridge. + */ +import Reaction from "/imports/plugins/core/core/server/Reaction"; +import register from "./server/no-meteor/register"; + +Reaction.whenAppInstanceReady(register); diff --git a/imports/plugins/core/ui/server/index.js b/imports/plugins/core/ui/server/index.js index be4987b5caf..d94fef228d3 100644 --- a/imports/plugins/core/ui/server/index.js +++ b/imports/plugins/core/ui/server/index.js @@ -1,2 +1,6 @@ -import "./i18n"; -import "./policy"; +import { BrowserPolicy } from "meteor/browser-policy-common"; + +BrowserPolicy.content.allowOriginForAll("*.facebook.com"); +BrowserPolicy.content.allowOriginForAll("connect.facebook.net"); +BrowserPolicy.content.allowOriginForAll("fonts.googleapis.com"); +BrowserPolicy.content.allowOriginForAll("fonts.gstatic.com"); diff --git a/imports/plugins/core/ui/server/i18n/ar.json b/imports/plugins/core/ui/server/no-meteor/i18n/ar.json similarity index 79% rename from imports/plugins/core/ui/server/i18n/ar.json rename to imports/plugins/core/ui/server/no-meteor/i18n/ar.json index 6002b8d569e..ffb718ea702 100644 --- a/imports/plugins/core/ui/server/i18n/ar.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/ar.json @@ -2,7 +2,7 @@ "i18n": "ar", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "المواضيع", @@ -30,6 +30,11 @@ "ofText": "من", "rowsText": "الصفوف" } + }, + "mediaGallery": { + "deleteImage": "انقر لإزالة الصورة", + "addedImage": "هذه صورة جديدة. نشر لحفظ التغييرات.", + "removedImage": "تم حذف الصورة. نشر لحفظ التغييرات." } } } diff --git a/imports/plugins/core/ui/server/i18n/bg.json b/imports/plugins/core/ui/server/no-meteor/i18n/bg.json similarity index 73% rename from imports/plugins/core/ui/server/i18n/bg.json rename to imports/plugins/core/ui/server/no-meteor/i18n/bg.json index c179b74fb5c..a4891df37ba 100644 --- a/imports/plugins/core/ui/server/i18n/bg.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/bg.json @@ -2,7 +2,7 @@ "i18n": "bg", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Теми", @@ -30,6 +30,11 @@ "ofText": "на", "rowsText": "редове" } + }, + "mediaGallery": { + "deleteImage": "Кликнете, за да премахнете изображението", + "addedImage": "Това е ново изображение. Публикуване, за да запазите промените.", + "removedImage": "Изображението бе изтрито. Публикуване, за да запазите промените." } } } diff --git a/imports/plugins/core/ui/server/i18n/cs.json b/imports/plugins/core/ui/server/no-meteor/i18n/cs.json similarity index 78% rename from imports/plugins/core/ui/server/i18n/cs.json rename to imports/plugins/core/ui/server/no-meteor/i18n/cs.json index 2ce5f5b796b..b5bd7aca788 100644 --- a/imports/plugins/core/ui/server/i18n/cs.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/cs.json @@ -2,7 +2,7 @@ "i18n": "cs", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Témata", @@ -30,6 +30,11 @@ "ofText": "z", "rowsText": "Řádky" } + }, + "mediaGallery": { + "deleteImage": "Klepnutím odeberete obrázek", + "addedImage": "Toto je nový obrázek. Publikujte, chcete-li uložit změny.", + "removedImage": "Obrázek byl smazán. Publikujte, chcete-li uložit změny." } } } diff --git a/imports/plugins/core/ui/server/i18n/de.json b/imports/plugins/core/ui/server/no-meteor/i18n/de.json similarity index 77% rename from imports/plugins/core/ui/server/i18n/de.json rename to imports/plugins/core/ui/server/no-meteor/i18n/de.json index 268e61ef159..442733632a1 100644 --- a/imports/plugins/core/ui/server/i18n/de.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/de.json @@ -2,7 +2,7 @@ "i18n": "de", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Themen", @@ -30,6 +30,11 @@ "ofText": "von", "rowsText": "Reihen" } + }, + "mediaGallery": { + "deleteImage": "Klicken Sie, um das Bild zu entfernen", + "addedImage": "Dies ist ein neues Bild. Veröffentlichen, um Änderungen zu speichern.", + "removedImage": "Bild wurde gelöscht. Veröffentlichen, um Änderungen zu speichern." } } } diff --git a/imports/plugins/core/ui/server/i18n/el.json b/imports/plugins/core/ui/server/no-meteor/i18n/el.json similarity index 73% rename from imports/plugins/core/ui/server/i18n/el.json rename to imports/plugins/core/ui/server/no-meteor/i18n/el.json index e09da1b7d90..ce4e7c120bd 100644 --- a/imports/plugins/core/ui/server/i18n/el.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/el.json @@ -2,7 +2,7 @@ "i18n": "el", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "θέματα", @@ -30,6 +30,11 @@ "ofText": "του", "rowsText": "Σειρές" } + }, + "mediaGallery": { + "deleteImage": "Κάντε κλικ για να αφαιρέσετε την εικόνα", + "addedImage": "Αυτή είναι μια νέα εικόνα. Δημοσιεύστε για να αποθηκεύσετε τις αλλαγές.", + "removedImage": "Η εικόνα έχει διαγραφεί. Δημοσιεύστε για να αποθηκεύσετε τις αλλαγές." } } } diff --git a/imports/plugins/core/ui/server/i18n/en.json b/imports/plugins/core/ui/server/no-meteor/i18n/en.json similarity index 73% rename from imports/plugins/core/ui/server/i18n/en.json rename to imports/plugins/core/ui/server/no-meteor/i18n/en.json index 67e8a7558dc..562cc1d6305 100644 --- a/imports/plugins/core/ui/server/i18n/en.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/en.json @@ -2,7 +2,7 @@ "i18n": "en", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "reactionUI": { "components": { "navbar": "Navigation Bar", @@ -22,6 +22,11 @@ "ofText": "of", "rowsText": "rows" } + }, + "mediaGallery": { + "deleteImage": "Click to remove image", + "addedImage": "This is a new image. Publish to save changes.", + "removedImage": "Image has been deleted. Publish to save changes." } } } diff --git a/imports/plugins/core/ui/server/i18n/es.json b/imports/plugins/core/ui/server/no-meteor/i18n/es.json similarity index 77% rename from imports/plugins/core/ui/server/i18n/es.json rename to imports/plugins/core/ui/server/no-meteor/i18n/es.json index ea87192f86b..cf582ff0908 100644 --- a/imports/plugins/core/ui/server/i18n/es.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/es.json @@ -2,7 +2,7 @@ "i18n": "es", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "temas", @@ -30,6 +30,11 @@ "ofText": "de", "rowsText": "Filas" } + }, + "mediaGallery": { + "deleteImage": "Haga clic para eliminar la imagen", + "addedImage": "Esta es una nueva imagen. Publicar para guardar los cambios.", + "removedImage": "Se ha eliminado la imagen. Publicar para guardar los cambios." } } } diff --git a/imports/plugins/core/ui/server/i18n/fr.json b/imports/plugins/core/ui/server/no-meteor/i18n/fr.json similarity index 77% rename from imports/plugins/core/ui/server/i18n/fr.json rename to imports/plugins/core/ui/server/no-meteor/i18n/fr.json index 3a21188fc56..a21ffd7fadb 100644 --- a/imports/plugins/core/ui/server/i18n/fr.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/fr.json @@ -2,7 +2,7 @@ "i18n": "fr", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Thèmes", @@ -30,6 +30,11 @@ "ofText": "de", "rowsText": "Lignes" } + }, + "mediaGallery": { + "deleteImage": "Cliquez pour supprimer l'image", + "addedImage": "C'est une nouvelle image. Publiez pour enregistrer les modifications.", + "removedImage": "L'image a été supprimée. Publiez pour enregistrer les modifications." } } } diff --git a/imports/plugins/core/ui/server/i18n/he.json b/imports/plugins/core/ui/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/core/ui/server/i18n/he.json rename to imports/plugins/core/ui/server/no-meteor/i18n/he.json diff --git a/imports/plugins/core/ui/server/i18n/hr.json b/imports/plugins/core/ui/server/no-meteor/i18n/hr.json similarity index 79% rename from imports/plugins/core/ui/server/i18n/hr.json rename to imports/plugins/core/ui/server/no-meteor/i18n/hr.json index 1c05cdc9f64..726f1a03cc3 100644 --- a/imports/plugins/core/ui/server/i18n/hr.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/hr.json @@ -2,7 +2,7 @@ "i18n": "hr", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Teme", @@ -30,6 +30,11 @@ "ofText": "od", "rowsText": "redovi" } + }, + "mediaGallery": { + "deleteImage": "Kliknite da biste uklonili sliku", + "addedImage": "Ovo je nova slika. Objavi za spremanje promjena.", + "removedImage": "Slika je izbrisana. Objavi za spremanje promjena." } } } diff --git a/imports/plugins/core/ui/server/i18n/hu.json b/imports/plugins/core/ui/server/no-meteor/i18n/hu.json similarity index 79% rename from imports/plugins/core/ui/server/i18n/hu.json rename to imports/plugins/core/ui/server/no-meteor/i18n/hu.json index db3eef746f7..26d133c18f4 100644 --- a/imports/plugins/core/ui/server/i18n/hu.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/hu.json @@ -2,7 +2,7 @@ "i18n": "hu", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "témák", @@ -30,6 +30,11 @@ "ofText": "nak,-nek", "rowsText": "sorok" } + }, + "mediaGallery": { + "deleteImage": "Kattintson a kép eltávolítása", + "addedImage": "Ez egy új képet. Adja változások mentéséhez.", + "removedImage": "Képet törölték. Adja változások mentéséhez." } } } diff --git a/imports/plugins/included/discount-codes/server/i18n/index.js b/imports/plugins/core/ui/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/included/discount-codes/server/i18n/index.js rename to imports/plugins/core/ui/server/no-meteor/i18n/index.js index 822f1bdf134..fe4f9543713 100644 --- a/imports/plugins/included/discount-codes/server/i18n/index.js +++ b/imports/plugins/core/ui/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; import cs from "./cs.json"; @@ -30,4 +28,31 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/core/ui/server/i18n/it.json b/imports/plugins/core/ui/server/no-meteor/i18n/it.json similarity index 77% rename from imports/plugins/core/ui/server/i18n/it.json rename to imports/plugins/core/ui/server/no-meteor/i18n/it.json index 0694d40f933..6e4ca63ab72 100644 --- a/imports/plugins/core/ui/server/i18n/it.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/it.json @@ -2,7 +2,7 @@ "i18n": "it", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Temi", @@ -30,6 +30,11 @@ "ofText": "di", "rowsText": "righe" } + }, + "mediaGallery": { + "deleteImage": "Fare clic per rimuovere l'immagine", + "addedImage": "Questa è una nuova immagine. Pubblica per salvare le modifiche.", + "removedImage": "L'immagine è stata cancellata. Pubblica per salvare le modifiche." } } } diff --git a/imports/plugins/core/ui/server/i18n/my.json b/imports/plugins/core/ui/server/no-meteor/i18n/my.json similarity index 72% rename from imports/plugins/core/ui/server/i18n/my.json rename to imports/plugins/core/ui/server/no-meteor/i18n/my.json index 3347f19259c..4a533525642 100644 --- a/imports/plugins/core/ui/server/i18n/my.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/my.json @@ -2,7 +2,7 @@ "i18n": "my", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "themes", @@ -30,6 +30,11 @@ "ofText": "၏", "rowsText": "အတန်း" } + }, + "mediaGallery": { + "deleteImage": "image ကိုဖယ်ရှားပစ်ရန်ကလစ်နှိပ်ပါ", + "addedImage": "ဒါကအသစ်တခုပုံရိပ်ဖြစ်ပါတယ်။ အပြောင်းအလဲများကိုကယ်ဖို့ Publish ။", + "removedImage": "Image ကိုဖျက်ထားသည်။ အပြောင်းအလဲများကိုကယ်ဖို့ Publish ။" } } } diff --git a/imports/plugins/core/ui/server/i18n/nb.json b/imports/plugins/core/ui/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/core/ui/server/i18n/nb.json rename to imports/plugins/core/ui/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/core/ui/server/i18n/nl.json b/imports/plugins/core/ui/server/no-meteor/i18n/nl.json similarity index 77% rename from imports/plugins/core/ui/server/i18n/nl.json rename to imports/plugins/core/ui/server/no-meteor/i18n/nl.json index cb96c21a3de..7c0cb7e78d1 100644 --- a/imports/plugins/core/ui/server/i18n/nl.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/nl.json @@ -2,7 +2,7 @@ "i18n": "nl", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Thema's", @@ -30,6 +30,11 @@ "ofText": "van", "rowsText": "rijen" } + }, + "mediaGallery": { + "deleteImage": "Klik om de afbeelding te verwijderen", + "addedImage": "Dit is een nieuwe afbeelding. Publiceer om wijzigingen op te slaan.", + "removedImage": "Afbeelding is verwijderd. Publiceer om wijzigingen op te slaan." } } } diff --git a/imports/plugins/core/ui/server/i18n/pl.json b/imports/plugins/core/ui/server/no-meteor/i18n/pl.json similarity index 78% rename from imports/plugins/core/ui/server/i18n/pl.json rename to imports/plugins/core/ui/server/no-meteor/i18n/pl.json index 5f135205ae8..8406f02849a 100644 --- a/imports/plugins/core/ui/server/i18n/pl.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/pl.json @@ -2,7 +2,7 @@ "i18n": "pl", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Motywy", @@ -30,6 +30,11 @@ "ofText": "z", "rowsText": "wydziwianie" } + }, + "mediaGallery": { + "deleteImage": "Kliknij, aby usunąć obraz", + "addedImage": "To jest nowy wizerunek. Opublikuj, aby zapisać zmiany.", + "removedImage": "Obraz został usunięty. Opublikuj, aby zapisać zmiany." } } } diff --git a/imports/plugins/core/ui/server/i18n/pt.json b/imports/plugins/core/ui/server/no-meteor/i18n/pt.json similarity index 78% rename from imports/plugins/core/ui/server/i18n/pt.json rename to imports/plugins/core/ui/server/no-meteor/i18n/pt.json index 676673b966f..a365666d2ab 100644 --- a/imports/plugins/core/ui/server/i18n/pt.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/pt.json @@ -2,7 +2,7 @@ "i18n": "pt", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Temas", @@ -30,6 +30,11 @@ "ofText": "de", "rowsText": "Linhas" } + }, + "mediaGallery": { + "deleteImage": "Clique para remover a imagem", + "addedImage": "Esta é uma nova imagem. Publique para salvar as alterações.", + "removedImage": "A imagem foi excluída. Publique para salvar as alterações." } } } diff --git a/imports/plugins/core/ui/server/i18n/ro.json b/imports/plugins/core/ui/server/no-meteor/i18n/ro.json similarity index 76% rename from imports/plugins/core/ui/server/i18n/ro.json rename to imports/plugins/core/ui/server/no-meteor/i18n/ro.json index 3a0f04814cd..101d10556e2 100644 --- a/imports/plugins/core/ui/server/i18n/ro.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/ro.json @@ -2,7 +2,7 @@ "i18n": "ro", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "tematică", @@ -30,6 +30,11 @@ "ofText": "de", "rowsText": "rânduri" } + }, + "mediaGallery": { + "deleteImage": "Faceți clic pentru a elimina imaginea", + "addedImage": "Aceasta este o imagine nouă. Publicați pentru a salva modificările.", + "removedImage": "Imaginea a fost ștearsă. Publicați pentru a salva modificările." } } } diff --git a/imports/plugins/core/ui/server/i18n/ru.json b/imports/plugins/core/ui/server/no-meteor/i18n/ru.json similarity index 76% rename from imports/plugins/core/ui/server/i18n/ru.json rename to imports/plugins/core/ui/server/no-meteor/i18n/ru.json index 1c8dbb3cd4a..532240070aa 100644 --- a/imports/plugins/core/ui/server/i18n/ru.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/ru.json @@ -2,7 +2,7 @@ "i18n": "ru", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Темы", @@ -30,6 +30,11 @@ "ofText": "из", "rowsText": "строки" } + }, + "mediaGallery": { + "deleteImage": "Нажмите, чтобы удалить изображение", + "addedImage": "Это новый образ. Публикация для сохранения изменений.", + "removedImage": "Изображение удалено. Публикация для сохранения изменений." } } } diff --git a/imports/plugins/core/ui/server/i18n/sl.json b/imports/plugins/core/ui/server/no-meteor/i18n/sl.json similarity index 78% rename from imports/plugins/core/ui/server/i18n/sl.json rename to imports/plugins/core/ui/server/no-meteor/i18n/sl.json index 34fc3d21ef5..5372872b464 100644 --- a/imports/plugins/core/ui/server/i18n/sl.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/sl.json @@ -2,7 +2,7 @@ "i18n": "sl", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Teme", @@ -30,6 +30,11 @@ "ofText": "za", "rowsText": "vrstice" } + }, + "mediaGallery": { + "deleteImage": "Kliknite, da odstranite sliko", + "addedImage": "To je nova podoba. Objavi, da shranite spremembe.", + "removedImage": "Slika je bila izbrisana. Objavi, da shranite spremembe." } } } diff --git a/imports/plugins/core/ui/server/i18n/sv.json b/imports/plugins/core/ui/server/no-meteor/i18n/sv.json similarity index 78% rename from imports/plugins/core/ui/server/i18n/sv.json rename to imports/plugins/core/ui/server/no-meteor/i18n/sv.json index 3f6b167d4e4..b6d38da8262 100644 --- a/imports/plugins/core/ui/server/i18n/sv.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/sv.json @@ -2,7 +2,7 @@ "i18n": "sv", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "teman", @@ -30,6 +30,11 @@ "ofText": "av", "rowsText": "rader" } + }, + "mediaGallery": { + "deleteImage": "Klicka för att ta bort bilden", + "addedImage": "Det här är en ny bild. Publicera för att spara ändringar.", + "removedImage": "Bilden har raderats. Publicera för att spara ändringar." } } } diff --git a/imports/plugins/core/ui/server/i18n/tr.json b/imports/plugins/core/ui/server/no-meteor/i18n/tr.json similarity index 77% rename from imports/plugins/core/ui/server/i18n/tr.json rename to imports/plugins/core/ui/server/no-meteor/i18n/tr.json index a1665fc5d45..376bb4719d0 100644 --- a/imports/plugins/core/ui/server/i18n/tr.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/tr.json @@ -2,7 +2,7 @@ "i18n": "tr", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "Temalar", @@ -30,6 +30,11 @@ "ofText": "arasında", "rowsText": "satırlar" } + }, + "mediaGallery": { + "deleteImage": "Resmi kaldırmak için tıklayın", + "addedImage": "Bu yeni bir görüntü. Değişiklikleri kaydetmek için yayınla.", + "removedImage": "Resim silindi. Değişiklikleri kaydetmek için yayınla." } } } diff --git a/imports/plugins/core/ui/server/i18n/vi.json b/imports/plugins/core/ui/server/no-meteor/i18n/vi.json similarity index 79% rename from imports/plugins/core/ui/server/i18n/vi.json rename to imports/plugins/core/ui/server/no-meteor/i18n/vi.json index 3e568967b8b..97c36fad517 100644 --- a/imports/plugins/core/ui/server/i18n/vi.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/vi.json @@ -2,7 +2,7 @@ "i18n": "vi", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "chủ đề", @@ -30,6 +30,11 @@ "ofText": "Của", "rowsText": "Hàng" } + }, + "mediaGallery": { + "deleteImage": "Nhấp để xóa hình ảnh", + "addedImage": "Đây là hình ảnh mới. Xuất bản để lưu thay đổi.", + "removedImage": "Hình ảnh đã bị xóa. Xuất bản để lưu thay đổi." } } } diff --git a/imports/plugins/core/ui/server/i18n/zh.json b/imports/plugins/core/ui/server/no-meteor/i18n/zh.json similarity index 79% rename from imports/plugins/core/ui/server/i18n/zh.json rename to imports/plugins/core/ui/server/no-meteor/i18n/zh.json index c9988584b83..c372cd24be4 100644 --- a/imports/plugins/core/ui/server/i18n/zh.json +++ b/imports/plugins/core/ui/server/no-meteor/i18n/zh.json @@ -2,7 +2,7 @@ "i18n": "zh", "ns": "reaction-ui", "translation": { - "reaction-catalog": { + "reaction-ui": { "admin": { "dashboard": { "themesLabel": "主题", @@ -30,6 +30,11 @@ "ofText": "的", "rowsText": "行" } + }, + "mediaGallery": { + "deleteImage": "点击删除图片", + "addedImage": "这是一个新的形象。发布以保存更改。", + "removedImage": "图片已被删除。发布以保存更改。" } } } diff --git a/imports/plugins/core/ui/server/no-meteor/register.js b/imports/plugins/core/ui/server/no-meteor/register.js new file mode 100644 index 00000000000..df7004d9524 --- /dev/null +++ b/imports/plugins/core/ui/server/no-meteor/register.js @@ -0,0 +1,14 @@ +import i18n from "./i18n"; + +/** + * @summary Import and call this function to add this plugin to your API. + * @param {ReactionNodeApp} app The ReactionNodeApp instance + * @returns {undefined} + */ +export default async function register(app) { + await app.registerPlugin({ + label: "UI", + name: "reaction-ui", + i18n + }); +} diff --git a/imports/plugins/core/ui/server/policy.js b/imports/plugins/core/ui/server/policy.js deleted file mode 100644 index d94fef228d3..00000000000 --- a/imports/plugins/core/ui/server/policy.js +++ /dev/null @@ -1,6 +0,0 @@ -import { BrowserPolicy } from "meteor/browser-policy-common"; - -BrowserPolicy.content.allowOriginForAll("*.facebook.com"); -BrowserPolicy.content.allowOriginForAll("connect.facebook.net"); -BrowserPolicy.content.allowOriginForAll("fonts.googleapis.com"); -BrowserPolicy.content.allowOriginForAll("fonts.gstatic.com"); diff --git a/imports/plugins/core/versions/server/i18n/en.json b/imports/plugins/core/versions/server/i18n/en.json deleted file mode 100644 index dd288fb3461..00000000000 --- a/imports/plugins/core/versions/server/i18n/en.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-migrations", - "translation": { - "reaction-migrations": { - "admin": { - "shortcut": {}, - "dashboard": {}, - "settings": {} - } - } - } -}] diff --git a/imports/plugins/core/versions/server/i18n/index.js b/imports/plugins/core/versions/server/i18n/index.js deleted file mode 100644 index 61a3373f63a..00000000000 --- a/imports/plugins/core/versions/server/i18n/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; -import en from "./en.json"; - -loadTranslations([en]); diff --git a/imports/plugins/core/versions/server/index.js b/imports/plugins/core/versions/server/index.js index 5f2d1138073..64e7a701e99 100644 --- a/imports/plugins/core/versions/server/index.js +++ b/imports/plugins/core/versions/server/index.js @@ -1,3 +1,2 @@ import "./startup"; import "./migrations/"; -import "./i18n"; diff --git a/imports/plugins/core/versions/server/migrations/59_drop_indexes.js b/imports/plugins/core/versions/server/migrations/59_drop_indexes.js index 3aa462206e4..f68863a55cf 100644 --- a/imports/plugins/core/versions/server/migrations/59_drop_indexes.js +++ b/imports/plugins/core/versions/server/migrations/59_drop_indexes.js @@ -6,6 +6,7 @@ import rawCollections from "/imports/collections/rawCollections"; const { db } = MongoInternals.defaultRemoteCollectionDriver().mongo; const Inventory = db.collection("Inventory"); +const Translations = db.collection("Translations"); /** * @private @@ -40,8 +41,7 @@ Migrations.add({ Orders, Packages, Products, - Shops, - Translations + Shops } = rawCollections; Accounts.dropIndex("c2_sessions", handleError); diff --git a/imports/plugins/core/versions/server/migrations/73_remove_translations_data.js b/imports/plugins/core/versions/server/migrations/73_remove_translations_data.js new file mode 100644 index 00000000000..b79863ab652 --- /dev/null +++ b/imports/plugins/core/versions/server/migrations/73_remove_translations_data.js @@ -0,0 +1,22 @@ +import { MongoInternals } from "meteor/mongo"; +import { Migrations } from "meteor/percolate:migrations"; +import rawCollections from "/imports/collections/rawCollections"; + +const { db } = MongoInternals.defaultRemoteCollectionDriver().mongo; + +Migrations.add({ + version: 73, + async up() { + const { Assets } = rawCollections; + + await Assets.deleteMany({ type: "i18n" }); + + try { + await db.dropCollection("Translations"); + } catch (error) { + // This seems to throw an error from mongo NPM pkg, but only after + // dropping the collections, so we'll just ignore + } + } + // Down migration is not possible. Translations data will be re-imported on startup anyway +}); diff --git a/imports/plugins/core/versions/server/migrations/index.js b/imports/plugins/core/versions/server/migrations/index.js index f36685b79c1..6af899693d7 100644 --- a/imports/plugins/core/versions/server/migrations/index.js +++ b/imports/plugins/core/versions/server/migrations/index.js @@ -71,3 +71,4 @@ import "./69_make_catalog_product_unique"; import "./70_remove_shop_app_version"; import "./71_add_allow_custom_user_locale"; import "./72_add_fulfillmentType_to_shipping_methods"; +import "./73_remove_translations_data"; diff --git a/imports/plugins/included/default-theme/server/i18n/en.json b/imports/plugins/included/default-theme/server/i18n/en.json deleted file mode 100644 index 5b82eb996ff..00000000000 --- a/imports/plugins/included/default-theme/server/i18n/en.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-default-theme", - "translation": { - "reaction-default-theme": { - "admin": { - "shortcut": {}, - "dashboard": {}, - "settings": {} - } - } - } -}] diff --git a/imports/plugins/included/default-theme/server/i18n/index.js b/imports/plugins/included/default-theme/server/i18n/index.js deleted file mode 100644 index 30788be39c3..00000000000 --- a/imports/plugins/included/default-theme/server/i18n/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -// import ar from "./ar.json"; -// import bg from "./bg.json"; -// import de from "./de.json"; -// import el from "./el.json"; -import en from "./en.json"; -// import es from "./es.json"; -// import fr from "./fr.json"; -// import he from "./he.json"; -// import hr from "./hr.json"; -// import it from "./it.json"; -// import my from "./my.json"; -// import nb from "./nb.json"; -// import nl from "./nl.json"; -// import pl from "./pl.json"; -// import pt from "./pt.json"; -// import ro from "./ro.json"; -// import ru from "./ru.json"; -// import sl from "./sl.json"; -// import sv from "./sv.json"; -// import tr from "./tr.json"; -// import vi from "./vi.json"; -// import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([en]); -// loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/default-theme/server/index.js b/imports/plugins/included/default-theme/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/included/default-theme/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/included/discount-codes/server/index.js b/imports/plugins/included/discount-codes/server/index.js index b1b0cd79673..59197e0b9ea 100644 --- a/imports/plugins/included/discount-codes/server/index.js +++ b/imports/plugins/included/discount-codes/server/index.js @@ -1,4 +1,3 @@ import "./publications/discounts"; import "./security/discounts"; -import "./i18n"; import "./methods"; diff --git a/imports/plugins/included/discount-codes/server/methods/methods.app-test.js b/imports/plugins/included/discount-codes/server/methods/methods.app-test.js deleted file mode 100644 index c6e29527f33..00000000000 --- a/imports/plugins/included/discount-codes/server/methods/methods.app-test.js +++ /dev/null @@ -1,70 +0,0 @@ -/* eslint-disable node/no-unsupported-features/es-syntax */ -/* eslint prefer-arrow-callback:0 */ -import { Meteor } from "meteor/meteor"; -import { Roles } from "meteor/alanning:roles"; -import { expect } from "meteor/practicalmeteor:chai"; -import { sinon } from "meteor/practicalmeteor:sinon"; -import { Discounts } from "/imports/plugins/core/discounts/lib/collections"; -import Reaction from "/imports/plugins/core/core/server/Reaction"; -import ReactionError from "@reactioncommerce/reaction-error"; - -const code = { - discount: 12, - label: "Discount 5", - description: "Discount by 5%", - discountMethod: "code", - code: "promocode" -}; - -describe("discount code methods", function () { - let sandbox; - - before(function (done) { - this.timeout(20000); - - Reaction.onAppStartupComplete(() => { - done(); - }); - }); - - beforeEach(function () { - sandbox = sinon.sandbox.create(); - }); - - afterEach(function () { - sandbox.restore(); - }); - - describe("discounts/addCode", function () { - it("should throw 403 error with discounts permission", function () { - sandbox.stub(Roles, "userIsInRole", () => false); - // this should actually trigger a whole lot of things - expect(() => Meteor.call("discounts/addCode", code)).to.throw(ReactionError, /Access Denied/); - }); - - // admin user - it("should add code when user has role", function () { - sandbox.stub(Roles, "userIsInRole", () => true); - const discountInsertSpy = sandbox.spy(Discounts, "insert"); - const discountId = Meteor.call("discounts/addCode", code); - expect(discountInsertSpy).to.have.been.called; - - const discountCount = Discounts.find(discountId).count(); - expect(discountCount).to.equal(1); - }); - }); - - describe("discounts/deleteCode", function () { - it("should delete rate with discounts permission", function () { - this.timeout(15000); - sandbox.stub(Roles, "userIsInRole", () => true); - const discountInsertSpy = sandbox.spy(Discounts, "insert"); - const discountId = Meteor.call("discounts/addCode", code); - expect(discountInsertSpy).to.have.been.called; - - Meteor.call("discounts/deleteCode", discountId); - const discountCount = Discounts.find(discountId).count(); - expect(discountCount).to.equal(0); - }); - }); -}); diff --git a/imports/plugins/included/discount-codes/server/i18n/ar.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/ar.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/ar.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/ar.json index 72ea8563563..04eba08ae53 100644 --- a/imports/plugins/included/discount-codes/server/i18n/ar.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/ar.json @@ -3,7 +3,7 @@ "i18n": "ar", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "تطبيق", "discountError": "عذرا، هناك خطأ تطبيق الخصم." diff --git a/imports/plugins/included/discount-codes/server/i18n/bg.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/bg.json similarity index 98% rename from imports/plugins/included/discount-codes/server/i18n/bg.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/bg.json index 7e79849e7ea..eb96600899a 100644 --- a/imports/plugins/included/discount-codes/server/i18n/bg.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/bg.json @@ -3,7 +3,7 @@ "i18n": "bg", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Приложи", "discountError": "За съжаление възникна грешка при прилагането на отстъпка." diff --git a/imports/plugins/included/discount-codes/server/i18n/cs.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/cs.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/cs.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/cs.json index dfb55ae2df9..3657949d829 100644 --- a/imports/plugins/included/discount-codes/server/i18n/cs.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/cs.json @@ -3,7 +3,7 @@ "i18n": "cs", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Aplikovat", "discountError": "Je nám líto, došlo k chybě při použití slevu." diff --git a/imports/plugins/included/discount-codes/server/i18n/de.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/de.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/de.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/de.json index f000d2b059e..4cf30cb12b6 100644 --- a/imports/plugins/included/discount-codes/server/i18n/de.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/de.json @@ -3,7 +3,7 @@ "i18n": "de", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Bewerben", "discountError": "Sorry, es ist ein Fehler aufgetreten Anwendung Rabatt." diff --git a/imports/plugins/included/discount-codes/server/i18n/el.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/el.json similarity index 98% rename from imports/plugins/included/discount-codes/server/i18n/el.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/el.json index a0be3dcd11c..9df2d31441b 100644 --- a/imports/plugins/included/discount-codes/server/i18n/el.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/el.json @@ -3,7 +3,7 @@ "i18n": "el", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Εφαρμόζεται", "discountError": "Συγνώμη, υπήρξε σφάλμα κατά την εφαρμογή έκπτωση." diff --git a/imports/plugins/included/discount-codes/server/i18n/en.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/en.json similarity index 98% rename from imports/plugins/included/discount-codes/server/i18n/en.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/en.json index df9200641a1..4f3c878cd82 100644 --- a/imports/plugins/included/discount-codes/server/i18n/en.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/en.json @@ -3,7 +3,7 @@ "i18n": "en", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Apply", "discountError": "Sorry, there was an error applying discount." diff --git a/imports/plugins/included/discount-codes/server/i18n/es.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/es.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/es.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/es.json index 71946297aae..75459ccd948 100644 --- a/imports/plugins/included/discount-codes/server/i18n/es.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/es.json @@ -3,7 +3,7 @@ "i18n": "es", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Aplicar", "discountError": "Ha habido un error al aplicar descuento." diff --git a/imports/plugins/included/discount-codes/server/i18n/fr.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/fr.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/fr.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/fr.json index e2f06d2afe2..470a48cb5cd 100644 --- a/imports/plugins/included/discount-codes/server/i18n/fr.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/fr.json @@ -3,7 +3,7 @@ "i18n": "fr", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Appliquer", "discountError": "Désolé, l'application de la réduction a échouée." diff --git a/imports/plugins/included/discount-codes/server/i18n/he.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/he.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/he.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/he.json index 94512791751..9ec5c13571a 100644 --- a/imports/plugins/included/discount-codes/server/i18n/he.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/he.json @@ -3,7 +3,7 @@ "i18n": "he", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "יישם", "discountError": "מצטערים, התגלתה שגיאה ביישום ההנחה." diff --git a/imports/plugins/included/discount-codes/server/i18n/hr.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/hr.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/hr.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/hr.json index 0f85555333c..0e6bdcb7bcd 100644 --- a/imports/plugins/included/discount-codes/server/i18n/hr.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/hr.json @@ -3,7 +3,7 @@ "i18n": "hr", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "primijeniti", "discountError": "Žao nam je, došlo je do pogreške primjenjujući popust." diff --git a/imports/plugins/included/discount-codes/server/i18n/hu.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/hu.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/hu.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/hu.json index ec6160a6440..e89fcbf1112 100644 --- a/imports/plugins/included/discount-codes/server/i18n/hu.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/hu.json @@ -3,7 +3,7 @@ "i18n": "hu", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "alkalmaz", "discountError": "Sajnáljuk, hiba történt alkalmazása kedvezmény." diff --git a/imports/plugins/included/marketplace/server/i18n/index.js b/imports/plugins/included/discount-codes/server/no-meteor/i18n/index.js similarity index 72% rename from imports/plugins/included/marketplace/server/i18n/index.js rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/index.js index 822f1bdf134..fe4f9543713 100644 --- a/imports/plugins/included/marketplace/server/i18n/index.js +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/index.js @@ -1,5 +1,3 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - import ar from "./ar.json"; import bg from "./bg.json"; import cs from "./cs.json"; @@ -30,4 +28,31 @@ import zh from "./zh.json"; // imports for easier handling by // automated translation software // -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/included/discount-codes/server/i18n/it.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/it.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/it.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/it.json index ec8c4c91e10..c66ecae2fd0 100644 --- a/imports/plugins/included/discount-codes/server/i18n/it.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/it.json @@ -3,7 +3,7 @@ "i18n": "it", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Applicare", "discountError": "Spiacente, c'è stato un errore di applicazione di sconto." diff --git a/imports/plugins/included/discount-codes/server/i18n/my.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/my.json similarity index 98% rename from imports/plugins/included/discount-codes/server/i18n/my.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/my.json index 90610189297..49b605b45e8 100644 --- a/imports/plugins/included/discount-codes/server/i18n/my.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/my.json @@ -3,7 +3,7 @@ "i18n": "my", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Apply", "discountError": "ဝမ်းနည်းပါတယ်, လျှော့စျေးလျှောက်ထားမှားယွင်းမှုတစ်ခုရှိ၏။" diff --git a/imports/plugins/included/discount-codes/server/i18n/nb.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/included/discount-codes/server/i18n/nb.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/included/discount-codes/server/i18n/nl.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/nl.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/nl.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/nl.json index 3ad122aa2f7..f916155490c 100644 --- a/imports/plugins/included/discount-codes/server/i18n/nl.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/nl.json @@ -3,7 +3,7 @@ "i18n": "nl", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Solliciteren", "discountError": "Sorry, was er een fout toe te passen korting." diff --git a/imports/plugins/included/discount-codes/server/i18n/pl.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/pl.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/pl.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/pl.json index eb3b2af4f70..086edd19d7e 100644 --- a/imports/plugins/included/discount-codes/server/i18n/pl.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/pl.json @@ -3,7 +3,7 @@ "i18n": "pl", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Ubiegać się", "discountError": "Niestety, wystąpił błąd podczas stosowania zniżki." diff --git a/imports/plugins/included/discount-codes/server/i18n/pt.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/pt.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/pt.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/pt.json index 730fbec7cd8..64e2d6e9b65 100644 --- a/imports/plugins/included/discount-codes/server/i18n/pt.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/pt.json @@ -3,7 +3,7 @@ "i18n": "pt", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Aplicar", "discountError": "Desculpe, houve um erro ao aplicar desconto." diff --git a/imports/plugins/included/discount-codes/server/i18n/ro.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/ro.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/ro.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/ro.json index b3940778f38..a681a264999 100644 --- a/imports/plugins/included/discount-codes/server/i18n/ro.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/ro.json @@ -3,7 +3,7 @@ "i18n": "ro", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "aplica", "discountError": "Ne pare rău, a apărut o eroare la aplicarea cu discount." diff --git a/imports/plugins/included/discount-codes/server/i18n/ru.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/ru.json similarity index 98% rename from imports/plugins/included/discount-codes/server/i18n/ru.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/ru.json index 29e18cdb234..8cb13b7261b 100644 --- a/imports/plugins/included/discount-codes/server/i18n/ru.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/ru.json @@ -3,7 +3,7 @@ "i18n": "ru", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Подать заявление", "discountError": "К сожалению, произошла ошибка при применении скидки." diff --git a/imports/plugins/included/discount-codes/server/i18n/sl.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/sl.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/sl.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/sl.json index f892ac6f368..ce6036dd843 100644 --- a/imports/plugins/included/discount-codes/server/i18n/sl.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/sl.json @@ -3,7 +3,7 @@ "i18n": "sl", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Uporabi", "discountError": "Žal je prišlo do napake uporabo popust." diff --git a/imports/plugins/included/discount-codes/server/i18n/sv.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/sv.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/sv.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/sv.json index 11b167d7bd6..cbbbc1a8072 100644 --- a/imports/plugins/included/discount-codes/server/i18n/sv.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/sv.json @@ -3,7 +3,7 @@ "i18n": "sv", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Tillämpas", "discountError": "Tyvärr fanns det ett fel tillämpa rabatt." diff --git a/imports/plugins/included/discount-codes/server/i18n/tr.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/tr.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/tr.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/tr.json index b123432e05c..7efb35a969d 100644 --- a/imports/plugins/included/discount-codes/server/i18n/tr.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/tr.json @@ -3,7 +3,7 @@ "i18n": "tr", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Uygulamak", "discountError": "Maalesef indirim uygulayan bir hata oluştu." diff --git a/imports/plugins/included/discount-codes/server/i18n/vi.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/vi.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/vi.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/vi.json index 506253cf073..bf9671ce38b 100644 --- a/imports/plugins/included/discount-codes/server/i18n/vi.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/vi.json @@ -3,7 +3,7 @@ "i18n": "vi", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "Ứng dụng", "discountError": "Xin lỗi, có lỗi khi áp dụng giảm giá." diff --git a/imports/plugins/included/discount-codes/server/i18n/zh.json b/imports/plugins/included/discount-codes/server/no-meteor/i18n/zh.json similarity index 97% rename from imports/plugins/included/discount-codes/server/i18n/zh.json rename to imports/plugins/included/discount-codes/server/no-meteor/i18n/zh.json index 9159eaaa7e1..b320f3f8a4c 100644 --- a/imports/plugins/included/discount-codes/server/i18n/zh.json +++ b/imports/plugins/included/discount-codes/server/no-meteor/i18n/zh.json @@ -3,7 +3,7 @@ "i18n": "zh", "ns": "discount-codes", "translation": { - "reaction-discounts": { + "discount-codes": { "checkoutPayment": { "applyDiscount": "申请", "discountError": "抱歉,申请折扣的错误。" diff --git a/imports/plugins/included/discount-codes/server/no-meteor/register.js b/imports/plugins/included/discount-codes/server/no-meteor/register.js index 237dad3a0dc..5d563cbe93a 100644 --- a/imports/plugins/included/discount-codes/server/no-meteor/register.js +++ b/imports/plugins/included/discount-codes/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import getCreditOffDiscount from "./util/getCreditOffDiscount"; import getItemPriceDiscount from "./util/getItemPriceDiscount"; import getPercentageOffDiscount from "./util/getPercentageOffDiscount"; @@ -14,6 +15,7 @@ export default async function register(app) { label: "Codes", name: "discount-codes", icon: "fa fa-gift", + i18n, functionsByType: { "discounts/codes/credit": [getCreditOffDiscount], "discounts/codes/discount": [getPercentageOffDiscount], diff --git a/imports/plugins/included/jobcontrol/server/i18n/en.json b/imports/plugins/included/jobcontrol/server/i18n/en.json deleted file mode 100644 index 42ca7019f48..00000000000 --- a/imports/plugins/included/jobcontrol/server/i18n/en.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-jobcontrol", - "translation": { - "reaction-jobcontrol": { - "admin": { - "shortcut": {}, - "dashboard": {}, - "settings": {} - } - } - } -}] diff --git a/imports/plugins/included/jobcontrol/server/i18n/index.js b/imports/plugins/included/jobcontrol/server/i18n/index.js deleted file mode 100644 index 30788be39c3..00000000000 --- a/imports/plugins/included/jobcontrol/server/i18n/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -// import ar from "./ar.json"; -// import bg from "./bg.json"; -// import de from "./de.json"; -// import el from "./el.json"; -import en from "./en.json"; -// import es from "./es.json"; -// import fr from "./fr.json"; -// import he from "./he.json"; -// import hr from "./hr.json"; -// import it from "./it.json"; -// import my from "./my.json"; -// import nb from "./nb.json"; -// import nl from "./nl.json"; -// import pl from "./pl.json"; -// import pt from "./pt.json"; -// import ro from "./ro.json"; -// import ru from "./ru.json"; -// import sl from "./sl.json"; -// import sv from "./sv.json"; -// import tr from "./tr.json"; -// import vi from "./vi.json"; -// import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([en]); -// loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/jobcontrol/server/index.js b/imports/plugins/included/jobcontrol/server/index.js index ebf149b1727..022d8ee1021 100644 --- a/imports/plugins/included/jobcontrol/server/index.js +++ b/imports/plugins/included/jobcontrol/server/index.js @@ -1,6 +1,5 @@ import { cleanupJob, addCleanupJobControlHook } from "./jobs/cleanup"; import { fetchRateJobs, setupFetchFlushCurrencyHooks } from "./jobs/exchangerates"; -import "./i18n"; addCleanupJobControlHook(); cleanupJob(); diff --git a/imports/plugins/included/marketplace/client/components/inviteOwner.js b/imports/plugins/included/marketplace/client/components/inviteOwner.js deleted file mode 100644 index fbf05ec3bc2..00000000000 --- a/imports/plugins/included/marketplace/client/components/inviteOwner.js +++ /dev/null @@ -1,122 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import React, { Component } from "react"; -import { registerComponent, Components } from "@reactioncommerce/reaction-components"; -import { i18next } from "/client/api"; -import ReactionAlerts from "/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts"; - -class InviteOwner extends Component { - constructor() { - super(); - this.state = { - alertId: "admin-invite-form", - name: "", - email: "", - group: "", - isLoading: false - }; - } - - onChange = (event) => { - this.setState({ [event.target.name]: event.target.value }); - } - - removeAlert = (oldAlert) => this.setState({ - alertArray: this.state.alertArray.filter((alert) => JSON.stringify(alert) === JSON.stringify(oldAlert)) - }); - - handleSubmit = (event) => { - event.preventDefault(); - this.setState({ isLoading: true }); - const { name, email, alertId } = this.state; - const alertOptions = { placement: alertId, id: alertId, autoHide: 4000 }; - const shopData = {}; // TODO: add optional shop data to the form (maybe just name?) - - Meteor.call("accounts/inviteShopOwner", { name, email }, shopData, (error, result) => { - let message = ""; - if (error) { - let messageKey; - if (error.reason === "Unable to send invitation email.") { - messageKey = "accountsUI.error.unableToSendInvitationEmail"; - } else if (error.reason !== "") { - message = error.reason; - } else { - messageKey = "accountsUI.error.errorSendingEmail"; - } - ReactionAlerts.add(message, "danger", Object.assign({}, alertOptions, { i18nKey: messageKey })); - } - - this.setState({ isLoading: false }); - - if (result) { - this.setState({ name: "", email: "" }); - Alerts.toast(i18next.t("accountsUI.info.invitationSent"), "success"); - } - }); - } - - renderSpinnerButton() { - if (this.state.isLoading) { - return ( -
- -
- ); - } - return ( - - ); - } - - render() { - return ( -
-

Invite Owner Form

- -
-
-
- -
-
- -
-
-
- {this.renderSpinnerButton()} -
-
-
-
-
- ); - } -} - -registerComponent("InviteOwner", InviteOwner); - -export default InviteOwner; diff --git a/imports/plugins/included/marketplace/client/containers/marketplaceShops.js b/imports/plugins/included/marketplace/client/containers/marketplaceShops.js index e19d4d02ab0..4baab31add6 100644 --- a/imports/plugins/included/marketplace/client/containers/marketplaceShops.js +++ b/imports/plugins/included/marketplace/client/containers/marketplaceShops.js @@ -9,19 +9,16 @@ const onWorkflowChange = (shopId, value) => { }; const composer = (props, onData) => { - // Subscribe to merchant shops and get all shops (excluding the primary shop) if subscription is ready - if (Meteor.subscribe("MerchantShops").ready()) { - const shops = Shops.find({ - _id: { - $nin: [Reaction.getPrimaryShopId()] - } - }).fetch(); + const shops = Shops.find({ + _id: { + $nin: [Reaction.getPrimaryShopId()] + } + }).fetch(); - onData(null, { - shops, - onWorkflowChange - }); - } + onData(null, { + shops, + onWorkflowChange + }); }; registerComponent("MarketplaceShops", MarketplaceShops, composeWithTracker(composer)); diff --git a/imports/plugins/included/marketplace/client/index.js b/imports/plugins/included/marketplace/client/index.js index 21f616f85d0..78678d99225 100644 --- a/imports/plugins/included/marketplace/client/index.js +++ b/imports/plugins/included/marketplace/client/index.js @@ -22,7 +22,5 @@ import "./templates/settings/merchant-settings.js"; import "./templates/settings/stripe.html"; import "./templates/settings/stripe.js"; -export { default as InviteOwner } from "./components/inviteOwner"; - export * from "./components"; export * from "./containers"; diff --git a/imports/plugins/included/marketplace/client/templates/dashboard/settings.html b/imports/plugins/included/marketplace/client/templates/dashboard/settings.html index d53ef17a706..b14a2af141b 100644 --- a/imports/plugins/included/marketplace/client/templates/dashboard/settings.html +++ b/imports/plugins/included/marketplace/client/templates/dashboard/settings.html @@ -6,8 +6,4 @@ {{/autoForm}} {{schema}} - -
- {{> React component=inviteOwner }} -
diff --git a/imports/plugins/included/marketplace/client/templates/dashboard/settings.js b/imports/plugins/included/marketplace/client/templates/dashboard/settings.js index a730e3d87fe..7bf25cf4898 100644 --- a/imports/plugins/included/marketplace/client/templates/dashboard/settings.js +++ b/imports/plugins/included/marketplace/client/templates/dashboard/settings.js @@ -1,6 +1,5 @@ import { Template } from "meteor/templating"; import { AutoForm } from "meteor/aldeed:autoform"; -import { Components } from "@reactioncommerce/reaction-components"; import { Reaction, i18next } from "/client/api"; import { Packages } from "/lib/collections"; import { MarketplacePackageConfig } from "../../../lib/collections/schemas"; @@ -19,9 +18,6 @@ Template.marketplaceShopSettings.helpers({ name: "reaction-marketplace", shopId: Reaction.getPrimaryShopId() }); - }, - inviteOwner() { - return Components.InviteOwner; } }); diff --git a/imports/plugins/included/marketplace/client/templates/shops/shopSelect.js b/imports/plugins/included/marketplace/client/templates/shops/shopSelect.js index 44f56bcb4ff..52dd6fcf373 100644 --- a/imports/plugins/included/marketplace/client/templates/shops/shopSelect.js +++ b/imports/plugins/included/marketplace/client/templates/shops/shopSelect.js @@ -5,7 +5,7 @@ import { Shops } from "/lib/collections"; Template.shopSelect.helpers({ shops() { - if (Reaction.Subscriptions.PrimaryShop.ready() && Reaction.Subscriptions.MerchantShops.ready()) { + if (Reaction.Subscriptions.PrimaryShop.ready()) { return Shops.find(); } diff --git a/imports/plugins/included/marketplace/server/index.js b/imports/plugins/included/marketplace/server/index.js index d15bada891f..695d8c2b1e2 100644 --- a/imports/plugins/included/marketplace/server/index.js +++ b/imports/plugins/included/marketplace/server/index.js @@ -1,4 +1,3 @@ import "./methods"; import "./stripe-connect"; -import "./i18n"; import "./publications"; diff --git a/imports/plugins/included/marketplace/server/i18n/ar.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/ar.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/included/marketplace/server/i18n/bg.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/bg.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/included/marketplace/server/i18n/cs.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/cs.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/included/marketplace/server/i18n/de.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/de.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/de.json diff --git a/imports/plugins/included/marketplace/server/i18n/el.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/el.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/el.json diff --git a/imports/plugins/included/marketplace/server/i18n/en.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/en.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/en.json diff --git a/imports/plugins/included/marketplace/server/i18n/es.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/es.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/es.json diff --git a/imports/plugins/included/marketplace/server/i18n/fr.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/fr.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/included/marketplace/server/i18n/he.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/he.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/he.json diff --git a/imports/plugins/included/marketplace/server/i18n/hr.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/hr.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/included/marketplace/server/i18n/hu.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/hu.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/included/marketplace/server/no-meteor/i18n/index.js b/imports/plugins/included/marketplace/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..fe4f9543713 --- /dev/null +++ b/imports/plugins/included/marketplace/server/no-meteor/i18n/index.js @@ -0,0 +1,58 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import cs from "./cs.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import hu from "./hu.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/included/marketplace/server/i18n/it.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/it.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/it.json diff --git a/imports/plugins/included/marketplace/server/i18n/my.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/my.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/my.json diff --git a/imports/plugins/included/marketplace/server/i18n/nb.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/nb.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/included/marketplace/server/i18n/nl.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/nl.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/included/marketplace/server/i18n/pl.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/pl.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/included/marketplace/server/i18n/pt.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/pt.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/included/marketplace/server/i18n/ro.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/ro.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/included/marketplace/server/i18n/ru.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/ru.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/included/marketplace/server/i18n/sl.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/sl.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/included/marketplace/server/i18n/sv.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/sv.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/included/marketplace/server/i18n/tr.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/tr.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/included/marketplace/server/i18n/vi.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/vi.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/included/marketplace/server/i18n/zh.json b/imports/plugins/included/marketplace/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/included/marketplace/server/i18n/zh.json rename to imports/plugins/included/marketplace/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/included/marketplace/server/no-meteor/register.js b/imports/plugins/included/marketplace/server/no-meteor/register.js index 167ae62bfe7..35719874fcb 100644 --- a/imports/plugins/included/marketplace/server/no-meteor/register.js +++ b/imports/plugins/included/marketplace/server/no-meteor/register.js @@ -1,4 +1,5 @@ /* eslint camelcase: 0 */ +import i18n from "./i18n"; import schemas from "./schemas"; import stripeCapturePayment from "./util/stripeCapturePayment"; import stripeCreateAuthorizedPayment from "./util/stripeCreateAuthorizedPayment"; @@ -15,6 +16,7 @@ export default async function register(app) { label: "Marketplace", name: "reaction-marketplace", icon: "fa fa-globe", + i18n, collections: { SellerShops: { name: "SellerShops" diff --git a/imports/plugins/included/notifications/server/i18n/ar.json b/imports/plugins/included/notifications/server/i18n/ar.json deleted file mode 100644 index c04e3063190..00000000000 --- a/imports/plugins/included/notifications/server/i18n/ar.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "ar", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "رسالة قصيرة", - "smsTitle": "رسالة قصيرة", - "smsDescription": "الإخطارات" - }, - "settings": { - "smsSettingsLabel": "إعدادات الرسائل القصيرة" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/bg.json b/imports/plugins/included/notifications/server/i18n/bg.json deleted file mode 100644 index 2cd6a3c8a76..00000000000 --- a/imports/plugins/included/notifications/server/i18n/bg.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "bg", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "СМС", - "smsTitle": "СМС", - "smsDescription": "Известия" - }, - "settings": { - "smsSettingsLabel": "настройки на SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/cs.json b/imports/plugins/included/notifications/server/i18n/cs.json deleted file mode 100644 index f0958d69dfc..00000000000 --- a/imports/plugins/included/notifications/server/i18n/cs.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "cs", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Oznámení" - }, - "settings": { - "smsSettingsLabel": "nastavení SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/de.json b/imports/plugins/included/notifications/server/i18n/de.json deleted file mode 100644 index 634102dafc9..00000000000 --- a/imports/plugins/included/notifications/server/i18n/de.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "de", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Benachrichtigungen" - }, - "settings": { - "smsSettingsLabel": "SMS-Einstellungen" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/el.json b/imports/plugins/included/notifications/server/i18n/el.json deleted file mode 100644 index 17a799fbe86..00000000000 --- a/imports/plugins/included/notifications/server/i18n/el.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "el", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "γραπτό μήνυμα", - "smsTitle": "γραπτό μήνυμα", - "smsDescription": "Ειδοποιήσεις" - }, - "settings": { - "smsSettingsLabel": "ρυθμίσεις SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/en.json b/imports/plugins/included/notifications/server/i18n/en.json deleted file mode 100644 index adf1086d74a..00000000000 --- a/imports/plugins/included/notifications/server/i18n/en.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS Notifications", - "smsTitle": "SMS", - "smsDescription": "Notifications" - }, - "settings": { - "smsSettingsLabel": "SMS Notifications" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/es.json b/imports/plugins/included/notifications/server/i18n/es.json deleted file mode 100644 index 10253c2ac7a..00000000000 --- a/imports/plugins/included/notifications/server/i18n/es.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "es", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Notificaciones" - }, - "settings": { - "smsSettingsLabel": "configuración de SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/fr.json b/imports/plugins/included/notifications/server/i18n/fr.json deleted file mode 100644 index 0079a07d386..00000000000 --- a/imports/plugins/included/notifications/server/i18n/fr.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "fr", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Notifications" - }, - "settings": { - "smsSettingsLabel": "Réglages SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/he.json b/imports/plugins/included/notifications/server/i18n/he.json deleted file mode 100644 index d1eb513621c..00000000000 --- a/imports/plugins/included/notifications/server/i18n/he.json +++ /dev/null @@ -1,5 +0,0 @@ -[{ - "i18n": "he", - "ns": "reaction-notification", - "translation": { } -}] diff --git a/imports/plugins/included/notifications/server/i18n/hr.json b/imports/plugins/included/notifications/server/i18n/hr.json deleted file mode 100644 index 9e1d56747ed..00000000000 --- a/imports/plugins/included/notifications/server/i18n/hr.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "hr", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Obavijesti" - }, - "settings": { - "smsSettingsLabel": "SMS postavke" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/hu.json b/imports/plugins/included/notifications/server/i18n/hu.json deleted file mode 100644 index fd042bf00ad..00000000000 --- a/imports/plugins/included/notifications/server/i18n/hu.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "hu", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Értesítések" - }, - "settings": { - "smsSettingsLabel": "SMS-beállítások" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/index.js b/imports/plugins/included/notifications/server/i18n/index.js deleted file mode 100644 index 822f1bdf134..00000000000 --- a/imports/plugins/included/notifications/server/i18n/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import cs from "./cs.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import hu from "./hu.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/notifications/server/i18n/it.json b/imports/plugins/included/notifications/server/i18n/it.json deleted file mode 100644 index 0c037b9db44..00000000000 --- a/imports/plugins/included/notifications/server/i18n/it.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "it", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Notifiche" - }, - "settings": { - "smsSettingsLabel": "impostazioni SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/my.json b/imports/plugins/included/notifications/server/i18n/my.json deleted file mode 100644 index 98d67bc1ed6..00000000000 --- a/imports/plugins/included/notifications/server/i18n/my.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "my", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "စာတို", - "smsTitle": "စာတို", - "smsDescription": "အသိပေးချက်များ" - }, - "settings": { - "smsSettingsLabel": "SMS ကို setting များကို" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/nb.json b/imports/plugins/included/notifications/server/i18n/nb.json deleted file mode 100644 index d51c3d1e4f6..00000000000 --- a/imports/plugins/included/notifications/server/i18n/nb.json +++ /dev/null @@ -1,5 +0,0 @@ -[{ - "i18n": "nb", - "ns": "reaction-notification", - "translation": { } -}] diff --git a/imports/plugins/included/notifications/server/i18n/nl.json b/imports/plugins/included/notifications/server/i18n/nl.json deleted file mode 100644 index eee13409af1..00000000000 --- a/imports/plugins/included/notifications/server/i18n/nl.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "nl", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Bekendmakingen" - }, - "settings": { - "smsSettingsLabel": "SMS-instellingen" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/pl.json b/imports/plugins/included/notifications/server/i18n/pl.json deleted file mode 100644 index 0dc79f13a8c..00000000000 --- a/imports/plugins/included/notifications/server/i18n/pl.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "pl", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Powiadomienia" - }, - "settings": { - "smsSettingsLabel": "ustawienia SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/pt.json b/imports/plugins/included/notifications/server/i18n/pt.json deleted file mode 100644 index ef544d6d294..00000000000 --- a/imports/plugins/included/notifications/server/i18n/pt.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "pt", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Notificações" - }, - "settings": { - "smsSettingsLabel": "definições de SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/ro.json b/imports/plugins/included/notifications/server/i18n/ro.json deleted file mode 100644 index f6a0d3b04ad..00000000000 --- a/imports/plugins/included/notifications/server/i18n/ro.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "ro", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Notificări" - }, - "settings": { - "smsSettingsLabel": "setările SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/ru.json b/imports/plugins/included/notifications/server/i18n/ru.json deleted file mode 100644 index 56fbd7a9513..00000000000 --- a/imports/plugins/included/notifications/server/i18n/ru.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "ru", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Уведомления" - }, - "settings": { - "smsSettingsLabel": "настройки SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/sl.json b/imports/plugins/included/notifications/server/i18n/sl.json deleted file mode 100644 index a806232226b..00000000000 --- a/imports/plugins/included/notifications/server/i18n/sl.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "sl", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Obvestila" - }, - "settings": { - "smsSettingsLabel": "nastavitve SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/sv.json b/imports/plugins/included/notifications/server/i18n/sv.json deleted file mode 100644 index 2a4f45a7c84..00000000000 --- a/imports/plugins/included/notifications/server/i18n/sv.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "sv", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Meddelanden" - }, - "settings": { - "smsSettingsLabel": "SMS-inställningar" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/tr.json b/imports/plugins/included/notifications/server/i18n/tr.json deleted file mode 100644 index 7f70743ced1..00000000000 --- a/imports/plugins/included/notifications/server/i18n/tr.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "tr", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "SMS", - "smsTitle": "SMS", - "smsDescription": "Bildirimler" - }, - "settings": { - "smsSettingsLabel": "SMS ayarları" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/vi.json b/imports/plugins/included/notifications/server/i18n/vi.json deleted file mode 100644 index c94d3b94748..00000000000 --- a/imports/plugins/included/notifications/server/i18n/vi.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "vi", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "tin nhắn", - "smsTitle": "tin nhắn", - "smsDescription": "thông báo" - }, - "settings": { - "smsSettingsLabel": "cài đặt SMS" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/i18n/zh.json b/imports/plugins/included/notifications/server/i18n/zh.json deleted file mode 100644 index 8f4051d1c70..00000000000 --- a/imports/plugins/included/notifications/server/i18n/zh.json +++ /dev/null @@ -1,18 +0,0 @@ -[{ - "i18n": "zh", - "ns": "reaction-notification", - "translation": { - "reaction-notification": { - "admin": { - "dashboard": { - "smsLabel": "短信", - "smsTitle": "短信", - "smsDescription": "通知" - }, - "settings": { - "smsSettingsLabel": "短信设置" - } - } - } - } -}] diff --git a/imports/plugins/included/notifications/server/index.js b/imports/plugins/included/notifications/server/index.js index 59f820257fb..d432564fcc4 100644 --- a/imports/plugins/included/notifications/server/index.js +++ b/imports/plugins/included/notifications/server/index.js @@ -1,3 +1,2 @@ import "./publications/notifications"; import "./methods"; -import "./i18n"; diff --git a/imports/plugins/included/payments-example/server/i18n/index.js b/imports/plugins/included/payments-example/server/i18n/index.js deleted file mode 100644 index 822f1bdf134..00000000000 --- a/imports/plugins/included/payments-example/server/i18n/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import cs from "./cs.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import hu from "./hu.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/payments-example/server/index.js b/imports/plugins/included/payments-example/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/included/payments-example/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/included/payments-example/server/i18n/ar.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/ar.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/ar.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/ar.json index 2889a0fc0ec..53cb2248a99 100644 --- a/imports/plugins/included/payments-example/server/i18n/ar.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/ar.json @@ -3,7 +3,7 @@ "i18n": "ar", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "مثال الدفع", diff --git a/imports/plugins/included/payments-example/server/i18n/bg.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/bg.json similarity index 97% rename from imports/plugins/included/payments-example/server/i18n/bg.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/bg.json index e175db48d9e..01466813687 100644 --- a/imports/plugins/included/payments-example/server/i18n/bg.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/bg.json @@ -3,7 +3,7 @@ "i18n": "bg", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Пример плащане", diff --git a/imports/plugins/included/payments-example/server/i18n/cs.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/cs.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/cs.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/cs.json index 7256dded98d..34606922ced 100644 --- a/imports/plugins/included/payments-example/server/i18n/cs.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/cs.json @@ -3,7 +3,7 @@ "i18n": "cs", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Příklad platba", diff --git a/imports/plugins/included/payments-example/server/i18n/de.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/de.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/de.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/de.json index 6b1cade933a..a076d2f5d67 100644 --- a/imports/plugins/included/payments-example/server/i18n/de.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/de.json @@ -3,7 +3,7 @@ "i18n": "de", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Beispiel Zahlung", diff --git a/imports/plugins/included/payments-example/server/i18n/el.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/el.json similarity index 97% rename from imports/plugins/included/payments-example/server/i18n/el.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/el.json index 5d852e97f17..cfb46869623 100644 --- a/imports/plugins/included/payments-example/server/i18n/el.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/el.json @@ -3,7 +3,7 @@ "i18n": "el", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "παράδειγμα πληρωμής", diff --git a/imports/plugins/included/payments-example/server/i18n/en.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/en.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/en.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/en.json index cf2131cf9ac..c405481c26e 100644 --- a/imports/plugins/included/payments-example/server/i18n/en.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/en.json @@ -3,7 +3,7 @@ "i18n": "en", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Example Payment", diff --git a/imports/plugins/included/payments-example/server/i18n/es.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/es.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/es.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/es.json index 8f695ecae32..e6f6decf6c1 100644 --- a/imports/plugins/included/payments-example/server/i18n/es.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/es.json @@ -3,7 +3,7 @@ "i18n": "es", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "ejemplo de Pago", diff --git a/imports/plugins/included/payments-example/server/i18n/fr.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/fr.json similarity index 97% rename from imports/plugins/included/payments-example/server/i18n/fr.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/fr.json index 6aaee6dbfcc..b084bc66af6 100644 --- a/imports/plugins/included/payments-example/server/i18n/fr.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/fr.json @@ -3,7 +3,7 @@ "i18n": "fr", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Exemple de passerelle de paiement", diff --git a/imports/plugins/included/payments-example/server/i18n/he.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/he.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/he.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/he.json index a2033097ce5..f315bd4636c 100644 --- a/imports/plugins/included/payments-example/server/i18n/he.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/he.json @@ -3,7 +3,7 @@ "i18n": "he", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "תשלום לדוגמה", diff --git a/imports/plugins/included/payments-example/server/i18n/hr.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/hr.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/hr.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/hr.json index bb5c81d1c2e..c5d3cea89db 100644 --- a/imports/plugins/included/payments-example/server/i18n/hr.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/hr.json @@ -3,7 +3,7 @@ "i18n": "hr", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Primjer plaćanja", diff --git a/imports/plugins/included/payments-example/server/i18n/hu.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/hu.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/hu.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/hu.json index 3df739d7330..51b4b12dea3 100644 --- a/imports/plugins/included/payments-example/server/i18n/hu.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/hu.json @@ -3,7 +3,7 @@ "i18n": "hu", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "példa Fizetési", diff --git a/imports/plugins/included/payments-example/server/no-meteor/i18n/index.js b/imports/plugins/included/payments-example/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..fe4f9543713 --- /dev/null +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/index.js @@ -0,0 +1,58 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import cs from "./cs.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import hu from "./hu.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/included/payments-example/server/i18n/it.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/it.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/it.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/it.json index a918c4a73d9..cc44f449a38 100644 --- a/imports/plugins/included/payments-example/server/i18n/it.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/it.json @@ -3,7 +3,7 @@ "i18n": "it", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "esempio di pagamento", diff --git a/imports/plugins/included/payments-example/server/i18n/my.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/my.json similarity index 97% rename from imports/plugins/included/payments-example/server/i18n/my.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/my.json index 42e48fe5f0f..c2b4617a35a 100644 --- a/imports/plugins/included/payments-example/server/i18n/my.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/my.json @@ -3,7 +3,7 @@ "i18n": "my", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "ဥပမာအားငွေပေးချေမှုရမည့်", diff --git a/imports/plugins/included/payments-example/server/i18n/nb.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/included/payments-example/server/i18n/nb.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/included/payments-example/server/i18n/nl.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/nl.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/nl.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/nl.json index 2fbc24674b8..fdd815004a4 100644 --- a/imports/plugins/included/payments-example/server/i18n/nl.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/nl.json @@ -3,7 +3,7 @@ "i18n": "nl", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "voorbeeld Betaling", diff --git a/imports/plugins/included/payments-example/server/i18n/pl.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/pl.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/pl.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/pl.json index a6dbb0c4823..9121c6ff326 100644 --- a/imports/plugins/included/payments-example/server/i18n/pl.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/pl.json @@ -3,7 +3,7 @@ "i18n": "pl", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Przykład Płatność", diff --git a/imports/plugins/included/payments-example/server/i18n/pt.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/pt.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/pt.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/pt.json index dd516517bcf..b95902e15cf 100644 --- a/imports/plugins/included/payments-example/server/i18n/pt.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/pt.json @@ -3,7 +3,7 @@ "i18n": "pt", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "exemplo de pagamento", diff --git a/imports/plugins/included/payments-example/server/i18n/ro.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/ro.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/ro.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/ro.json index ddd74f88c78..ef7ff30e1e1 100644 --- a/imports/plugins/included/payments-example/server/i18n/ro.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/ro.json @@ -3,7 +3,7 @@ "i18n": "ro", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Exemplul de plată", diff --git a/imports/plugins/included/payments-example/server/i18n/ru.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/ru.json similarity index 97% rename from imports/plugins/included/payments-example/server/i18n/ru.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/ru.json index 17b49fad660..a8b1cd164fb 100644 --- a/imports/plugins/included/payments-example/server/i18n/ru.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/ru.json @@ -3,7 +3,7 @@ "i18n": "ru", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Пример оплаты", diff --git a/imports/plugins/included/payments-example/server/i18n/sl.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/sl.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/sl.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/sl.json index 1bcdc0c1ba5..900e9724dbb 100644 --- a/imports/plugins/included/payments-example/server/i18n/sl.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/sl.json @@ -3,7 +3,7 @@ "i18n": "sl", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Primer plačila", diff --git a/imports/plugins/included/payments-example/server/i18n/sv.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/sv.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/sv.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/sv.json index 2e26a93af37..1e509cfb47f 100644 --- a/imports/plugins/included/payments-example/server/i18n/sv.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/sv.json @@ -3,7 +3,7 @@ "i18n": "sv", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "exempel Betalning", diff --git a/imports/plugins/included/payments-example/server/i18n/tr.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/tr.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/tr.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/tr.json index 3347c89540b..8aa72739261 100644 --- a/imports/plugins/included/payments-example/server/i18n/tr.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/tr.json @@ -3,7 +3,7 @@ "i18n": "tr", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Örnek Ödeme", diff --git a/imports/plugins/included/payments-example/server/i18n/vi.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/vi.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/vi.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/vi.json index de710899890..91f16f0c609 100644 --- a/imports/plugins/included/payments-example/server/i18n/vi.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/vi.json @@ -3,7 +3,7 @@ "i18n": "vi", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "Ví dụ thanh toán", diff --git a/imports/plugins/included/payments-example/server/i18n/zh.json b/imports/plugins/included/payments-example/server/no-meteor/i18n/zh.json similarity index 96% rename from imports/plugins/included/payments-example/server/i18n/zh.json rename to imports/plugins/included/payments-example/server/no-meteor/i18n/zh.json index aefef59bbb4..37499d333dc 100644 --- a/imports/plugins/included/payments-example/server/i18n/zh.json +++ b/imports/plugins/included/payments-example/server/no-meteor/i18n/zh.json @@ -3,7 +3,7 @@ "i18n": "zh", "ns": "example-paymentmethod", "translation": { - "reaction-payments": { + "example-paymentmethod": { "admin": { "shortcut": { "examplePaymentProviderLabel": "例如付款", diff --git a/imports/plugins/included/payments-example/server/no-meteor/register.js b/imports/plugins/included/payments-example/server/no-meteor/register.js index b6588f4b18f..7a13c7e8e7a 100644 --- a/imports/plugins/included/payments-example/server/no-meteor/register.js +++ b/imports/plugins/included/payments-example/server/no-meteor/register.js @@ -1,3 +1,4 @@ +import i18n from "./i18n"; import exampleCapturePayment from "./util/exampleCapturePayment"; import exampleCreateAuthorizedPayment from "./util/exampleCreateAuthorizedPayment"; import exampleCreateRefund from "./util/exampleCreateRefund"; @@ -15,6 +16,7 @@ export default async function register(app) { label: "ExamplePayment", name: "example-paymentmethod", icon: "fa fa-credit-card-alt", + i18n, graphQL: { schemas }, diff --git a/imports/plugins/included/payments-stripe/server/i18n/index.js b/imports/plugins/included/payments-stripe/server/i18n/index.js deleted file mode 100644 index 822f1bdf134..00000000000 --- a/imports/plugins/included/payments-stripe/server/i18n/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import cs from "./cs.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import hu from "./hu.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/payments-stripe/server/index.js b/imports/plugins/included/payments-stripe/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/included/payments-stripe/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/included/payments-stripe/server/i18n/ar.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/ar.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/ar.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/ar.json index 8a2e99ee55d..86c0a5f675e 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ar.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/ar.json @@ -3,7 +3,7 @@ "i18n": "ar", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/bg.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/bg.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/bg.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/bg.json index ad7f8dc00b7..ef37bfec764 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/bg.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/bg.json @@ -3,7 +3,7 @@ "i18n": "bg", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/cs.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/cs.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/cs.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/cs.json index 1e87351db23..73a3a090720 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/cs.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/cs.json @@ -3,7 +3,7 @@ "i18n": "cs", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/de.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/de.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/de.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/de.json index 2865b19e7e4..36f063e0e4a 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/de.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/de.json @@ -3,7 +3,7 @@ "i18n": "de", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/el.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/el.json similarity index 99% rename from imports/plugins/included/payments-stripe/server/i18n/el.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/el.json index e9b261b6ce0..7180d023afd 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/el.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/el.json @@ -3,7 +3,7 @@ "i18n": "el", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/en.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/en.json similarity index 99% rename from imports/plugins/included/payments-stripe/server/i18n/en.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/en.json index 0df87984bc9..35f3fe4522e 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/en.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/en.json @@ -3,7 +3,7 @@ "i18n": "en", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/es.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/es.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/es.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/es.json index ded7682da62..b4504e76b2f 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/es.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/es.json @@ -3,7 +3,7 @@ "i18n": "es", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/fr.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/fr.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/fr.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/fr.json index d409f41171c..ce3842840f2 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/fr.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/fr.json @@ -3,7 +3,7 @@ "i18n": "fr", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/he.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/he.json similarity index 95% rename from imports/plugins/included/payments-stripe/server/i18n/he.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/he.json index bdd08ff3960..16cac0bcdff 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/he.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/he.json @@ -3,7 +3,7 @@ "i18n": "he", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/hr.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/hr.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/hr.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/hr.json index 54b05dbfcf1..c9f007fe4fc 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/hr.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/hr.json @@ -3,7 +3,7 @@ "i18n": "hr", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/hu.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/hu.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/hu.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/hu.json index 4529021e4f8..65e6ad68fad 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/hu.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/hu.json @@ -3,7 +3,7 @@ "i18n": "hu", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/no-meteor/i18n/index.js b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..fe4f9543713 --- /dev/null +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/index.js @@ -0,0 +1,58 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import cs from "./cs.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import hu from "./hu.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/included/payments-stripe/server/i18n/it.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/it.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/it.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/it.json index b882b562826..f2f7923dc08 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/it.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/it.json @@ -3,7 +3,7 @@ "i18n": "it", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/my.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/my.json similarity index 99% rename from imports/plugins/included/payments-stripe/server/i18n/my.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/my.json index 2cea1ecd33c..65e04520641 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/my.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/my.json @@ -3,7 +3,7 @@ "i18n": "my", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/nb.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/nb.json similarity index 93% rename from imports/plugins/included/payments-stripe/server/i18n/nb.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/nb.json index 423372b3f56..8b0b768ccad 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/nb.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/nb.json @@ -3,7 +3,7 @@ "i18n": "nb", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/nl.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/nl.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/nl.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/nl.json index 3dc2e9d4eac..050a785c891 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/nl.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/nl.json @@ -3,7 +3,7 @@ "i18n": "nl", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/pl.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/pl.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/pl.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/pl.json index 93ae8f9fe9d..793ef4daff1 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/pl.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/pl.json @@ -3,7 +3,7 @@ "i18n": "pl", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/pt.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/pt.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/pt.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/pt.json index 45b13ae9f83..2bd33e8b62d 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/pt.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/pt.json @@ -3,7 +3,7 @@ "i18n": "pt", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/ro.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/ro.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/ro.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/ro.json index bdd1bc8c87a..1c5218660b8 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ro.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/ro.json @@ -3,7 +3,7 @@ "i18n": "ro", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/ru.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/ru.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/ru.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/ru.json index 21af64ca98e..d0b651e123b 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/ru.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/ru.json @@ -3,7 +3,7 @@ "i18n": "ru", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/sl.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/sl.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/sl.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/sl.json index f77a411fcc1..94fbc4d7564 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/sl.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/sl.json @@ -3,7 +3,7 @@ "i18n": "sl", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/sv.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/sv.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/sv.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/sv.json index 1d02e139af9..9a0480dba18 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/sv.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/sv.json @@ -3,7 +3,7 @@ "i18n": "sv", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/tr.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/tr.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/tr.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/tr.json index bc7131087ce..06b6bbcf905 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/tr.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/tr.json @@ -3,7 +3,7 @@ "i18n": "tr", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/vi.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/vi.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/vi.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/vi.json index 858ca3ea33e..877dd3ce2bd 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/vi.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/vi.json @@ -3,7 +3,7 @@ "i18n": "vi", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/i18n/zh.json b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/zh.json similarity index 98% rename from imports/plugins/included/payments-stripe/server/i18n/zh.json rename to imports/plugins/included/payments-stripe/server/no-meteor/i18n/zh.json index 610fe66ab22..004f915841e 100644 --- a/imports/plugins/included/payments-stripe/server/i18n/zh.json +++ b/imports/plugins/included/payments-stripe/server/no-meteor/i18n/zh.json @@ -3,7 +3,7 @@ "i18n": "zh", "ns": "reaction-stripe", "translation": { - "reaction-payments": { + "reaction-stripe": { "admin": { "shortcut": { "stripeLabel": "Stripe" diff --git a/imports/plugins/included/payments-stripe/server/no-meteor/register.js b/imports/plugins/included/payments-stripe/server/no-meteor/register.js index 00ba9ab0053..c27b5128e21 100644 --- a/imports/plugins/included/payments-stripe/server/no-meteor/register.js +++ b/imports/plugins/included/payments-stripe/server/no-meteor/register.js @@ -1,5 +1,6 @@ /* eslint camelcase: 0 */ import { STRIPE_PACKAGE_NAME } from "../../lib/constants"; +import i18n from "./i18n"; import schemas from "./schemas"; import stripeCapturePayment from "./util/stripeCapturePayment"; import stripeCreateAuthorizedPayment from "./util/stripeCreateAuthorizedPayment"; @@ -16,6 +17,7 @@ export default async function register(app) { label: "Stripe", name: STRIPE_PACKAGE_NAME, icon: "fa fa-cc-stripe", + i18n, graphQL: { schemas }, diff --git a/imports/plugins/included/product-admin/client/blocks/VariantDetailForm.js b/imports/plugins/included/product-admin/client/blocks/VariantDetailForm.js index f17fc0d1b27..c9e2fc43731 100644 --- a/imports/plugins/included/product-admin/client/blocks/VariantDetailForm.js +++ b/imports/plugins/included/product-admin/client/blocks/VariantDetailForm.js @@ -23,7 +23,7 @@ function VariantDetailForm(props) { hasChildVariants, variant } = props; - const currency = findCurrency(null, true); + const currency = findCurrency(); return ( diff --git a/imports/plugins/included/product-admin/client/components/VariantForm.js b/imports/plugins/included/product-admin/client/components/VariantForm.js index 3ccafec6733..b4f52614625 100644 --- a/imports/plugins/included/product-admin/client/components/VariantForm.js +++ b/imports/plugins/included/product-admin/client/components/VariantForm.js @@ -301,7 +301,7 @@ class VariantForm extends Component { render() { const { classes, variant } = this.props; - const currency = findCurrency(null, true); + const currency = findCurrency(); return (
diff --git a/imports/plugins/included/product-admin/server/i18n/index.js b/imports/plugins/included/product-admin/server/i18n/index.js deleted file mode 100644 index 822f1bdf134..00000000000 --- a/imports/plugins/included/product-admin/server/i18n/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import cs from "./cs.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import hu from "./hu.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/product-admin/server/index.js b/imports/plugins/included/product-admin/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/included/product-admin/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/included/product-admin/server/i18n/ar.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/ar.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/ar.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/ar.json diff --git a/imports/plugins/included/product-admin/server/i18n/bg.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/bg.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/bg.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/bg.json diff --git a/imports/plugins/included/product-admin/server/i18n/cs.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/cs.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/cs.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/cs.json diff --git a/imports/plugins/included/product-admin/server/i18n/de.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/de.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/de.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/de.json diff --git a/imports/plugins/included/product-admin/server/i18n/el.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/el.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/el.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/el.json diff --git a/imports/plugins/included/product-admin/server/i18n/en.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/en.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/en.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/en.json diff --git a/imports/plugins/included/product-admin/server/i18n/es.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/es.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/es.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/es.json diff --git a/imports/plugins/included/product-admin/server/i18n/fr.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/fr.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/fr.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/fr.json diff --git a/imports/plugins/included/product-admin/server/i18n/he.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/he.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/he.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/he.json diff --git a/imports/plugins/included/product-admin/server/i18n/hr.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/hr.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/hr.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/hr.json diff --git a/imports/plugins/included/product-admin/server/i18n/hu.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/hu.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/hu.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/hu.json diff --git a/imports/plugins/included/product-admin/server/no-meteor/i18n/index.js b/imports/plugins/included/product-admin/server/no-meteor/i18n/index.js new file mode 100644 index 00000000000..fe4f9543713 --- /dev/null +++ b/imports/plugins/included/product-admin/server/no-meteor/i18n/index.js @@ -0,0 +1,58 @@ +import ar from "./ar.json"; +import bg from "./bg.json"; +import cs from "./cs.json"; +import de from "./de.json"; +import el from "./el.json"; +import en from "./en.json"; +import es from "./es.json"; +import fr from "./fr.json"; +import he from "./he.json"; +import hr from "./hr.json"; +import hu from "./hu.json"; +import it from "./it.json"; +import my from "./my.json"; +import nb from "./nb.json"; +import nl from "./nl.json"; +import pl from "./pl.json"; +import pt from "./pt.json"; +import ro from "./ro.json"; +import ru from "./ru.json"; +import sl from "./sl.json"; +import sv from "./sv.json"; +import tr from "./tr.json"; +import vi from "./vi.json"; +import zh from "./zh.json"; + +// +// we want all the files in individual +// imports for easier handling by +// automated translation software +// +export default { + translations: [ + ...ar, + ...bg, + ...cs, + ...de, + ...el, + ...en, + ...es, + ...fr, + ...he, + ...hr, + ...hu, + ...it, + ...my, + ...nb, + ...nl, + ...pl, + ...pt, + ...ro, + ...ru, + ...sl, + ...sv, + ...tr, + ...vi, + ...zh + ] +}; diff --git a/imports/plugins/included/product-admin/server/i18n/it.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/it.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/it.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/it.json diff --git a/imports/plugins/included/product-admin/server/i18n/my.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/my.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/my.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/my.json diff --git a/imports/plugins/included/product-admin/server/i18n/nb.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/nb.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/nb.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/nb.json diff --git a/imports/plugins/included/product-admin/server/i18n/nl.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/nl.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/nl.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/nl.json diff --git a/imports/plugins/included/product-admin/server/i18n/pl.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/pl.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/pl.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/pl.json diff --git a/imports/plugins/included/product-admin/server/i18n/pt.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/pt.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/pt.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/pt.json diff --git a/imports/plugins/included/product-admin/server/i18n/ro.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/ro.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/ro.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/ro.json diff --git a/imports/plugins/included/product-admin/server/i18n/ru.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/ru.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/ru.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/ru.json diff --git a/imports/plugins/included/product-admin/server/i18n/sl.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/sl.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/sl.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/sl.json diff --git a/imports/plugins/included/product-admin/server/i18n/sv.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/sv.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/sv.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/sv.json diff --git a/imports/plugins/included/product-admin/server/i18n/tr.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/tr.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/tr.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/tr.json diff --git a/imports/plugins/included/product-admin/server/i18n/vi.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/vi.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/vi.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/vi.json diff --git a/imports/plugins/included/product-admin/server/i18n/zh.json b/imports/plugins/included/product-admin/server/no-meteor/i18n/zh.json similarity index 100% rename from imports/plugins/included/product-admin/server/i18n/zh.json rename to imports/plugins/included/product-admin/server/no-meteor/i18n/zh.json diff --git a/imports/plugins/included/product-admin/server/no-meteor/register.js b/imports/plugins/included/product-admin/server/no-meteor/register.js index f88c6276c54..353ca4f09a4 100644 --- a/imports/plugins/included/product-admin/server/no-meteor/register.js +++ b/imports/plugins/included/product-admin/server/no-meteor/register.js @@ -1,3 +1,5 @@ +import i18n from "./i18n"; + /** * @summary Import and call this function to add this plugin to your API. * @param {ReactionNodeApp} app The ReactionNodeApp instance @@ -8,6 +10,7 @@ export default async function register(app) { label: "Product Admin", name: "reaction-product-admin", icon: "fa fa-box", + i18n, registry: [ // `ProductAdmin` is a role that currently clones the `createProduct` role // which is overused in too many places. By adding `ProductAdmin`, we can use diff --git a/imports/plugins/included/product-detail-simple/register.js b/imports/plugins/included/product-detail-simple/register.js deleted file mode 100644 index 1c1ca57a4a7..00000000000 --- a/imports/plugins/included/product-detail-simple/register.js +++ /dev/null @@ -1,7 +0,0 @@ -import Reaction from "/imports/plugins/core/core/server/Reaction"; - -Reaction.registerPackage({ - label: "Product Detail Simple", - name: "product-detail-simple", - icon: "fa fa-cubes" -}); diff --git a/imports/plugins/included/product-detail-simple/server/i18n/ar.json b/imports/plugins/included/product-detail-simple/server/i18n/ar.json deleted file mode 100644 index ea18cf1a71d..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/ar.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "ar", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "تفاصيل المنتج" - }, - "inventoryAlerts": { - "adjustedQuantity": "تم تعديل كمية المنتج الخاص بك إلى الكمية القصوى في الأوراق المالية" - }, - "mediaGallery": { - "deleteImage": "انقر لإزالة الصورة", - "addedImage": "هذه صورة جديدة. نشر لحفظ التغييرات.", - "removedImage": "تم حذف الصورة. نشر لحفظ التغييرات." - } - }, - "availableOptions": "خيارات متاحة" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/bg.json b/imports/plugins/included/product-detail-simple/server/i18n/bg.json deleted file mode 100644 index 9fee484275f..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/bg.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "bg", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "информация за продукта" - }, - "inventoryAlerts": { - "adjustedQuantity": "Вашият продукт количество бе коригиран до макс количество на склад" - }, - "mediaGallery": { - "deleteImage": "Кликнете, за да премахнете изображението", - "addedImage": "Това е ново изображение. Публикуване, за да запазите промените.", - "removedImage": "Изображението бе изтрито. Публикуване, за да запазите промените." - } - }, - "availableOptions": "Налични варианти" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/cs.json b/imports/plugins/included/product-detail-simple/server/i18n/cs.json deleted file mode 100644 index 1f1389648c9..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/cs.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "cs", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Detaily produktu" - }, - "inventoryAlerts": { - "adjustedQuantity": "Váš množství produktu byla upravena tak, aby max množství na skladě" - }, - "mediaGallery": { - "deleteImage": "Klepnutím odeberete obrázek", - "addedImage": "Toto je nový obrázek. Publikujte, chcete-li uložit změny.", - "removedImage": "Obrázek byl smazán. Publikujte, chcete-li uložit změny." - } - }, - "availableOptions": "dostupné možnosti" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/de.json b/imports/plugins/included/product-detail-simple/server/i18n/de.json deleted file mode 100644 index 8b2737e5f56..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/de.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "de", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Produktdetails" - }, - "inventoryAlerts": { - "adjustedQuantity": "Ihre Produktmenge wurde die Höchstmenge eingestellt auf Lager" - }, - "mediaGallery": { - "deleteImage": "Klicken Sie, um das Bild zu entfernen", - "addedImage": "Dies ist ein neues Bild. Veröffentlichen, um Änderungen zu speichern.", - "removedImage": "Bild wurde gelöscht. Veröffentlichen, um Änderungen zu speichern." - } - }, - "availableOptions": "Verfügbare Optionen" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/el.json b/imports/plugins/included/product-detail-simple/server/i18n/el.json deleted file mode 100644 index 7f6b0f10466..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/el.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "el", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "λεπτομέρειες προιόντος" - }, - "inventoryAlerts": { - "adjustedQuantity": "ποσότητα του προϊόντος σας έχει ρυθμιστεί στο μέγιστο ποσότητα στο απόθεμα" - }, - "mediaGallery": { - "deleteImage": "Κάντε κλικ για να αφαιρέσετε την εικόνα", - "addedImage": "Αυτή είναι μια νέα εικόνα. Δημοσιεύστε για να αποθηκεύσετε τις αλλαγές.", - "removedImage": "Η εικόνα έχει διαγραφεί. Δημοσιεύστε για να αποθηκεύσετε τις αλλαγές." - } - }, - "availableOptions": "διαθέσιμες Επιλογές" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/en.json b/imports/plugins/included/product-detail-simple/server/i18n/en.json deleted file mode 100644 index 12cf9f5c839..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/en.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "en", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Product Details" - }, - "inventoryAlerts": { - "adjustedQuantity": "Your product quantity has been adjusted to the max quantity in stock" - }, - "mediaGallery": { - "deleteImage": "Click to remove image", - "addedImage": "This is a new image. Publish to save changes.", - "removedImage": "Image has been deleted. Publish to save changes." - } - }, - "availableOptions": "Available Options" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/es.json b/imports/plugins/included/product-detail-simple/server/i18n/es.json deleted file mode 100644 index b3a7234454c..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/es.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "es", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "detalles del producto" - }, - "inventoryAlerts": { - "adjustedQuantity": "Su cantidad de producto se ha ajustado a la cantidad máxima en stock" - }, - "mediaGallery": { - "deleteImage": "Haga clic para eliminar la imagen", - "addedImage": "Esta es una nueva imagen. Publicar para guardar los cambios.", - "removedImage": "Se ha eliminado la imagen. Publicar para guardar los cambios." - } - }, - "availableOptions": "Opciones disponibles" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/fr.json b/imports/plugins/included/product-detail-simple/server/i18n/fr.json deleted file mode 100644 index 8c7562054c0..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/fr.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "fr", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "détails du produit" - }, - "inventoryAlerts": { - "adjustedQuantity": "Votre quantité de produit a été ajustée à la quantité maximale en stock" - }, - "mediaGallery": { - "deleteImage": "Cliquez pour supprimer l'image", - "addedImage": "C'est une nouvelle image. Publiez pour enregistrer les modifications.", - "removedImage": "L'image a été supprimée. Publiez pour enregistrer les modifications." - } - }, - "availableOptions": "Options disponibles" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/he.json b/imports/plugins/included/product-detail-simple/server/i18n/he.json deleted file mode 100644 index 5efe38e72b6..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/he.json +++ /dev/null @@ -1,9 +0,0 @@ -[{ - "i18n": "he", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "availableOptions": "אפשרויות זמינות" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/hr.json b/imports/plugins/included/product-detail-simple/server/i18n/hr.json deleted file mode 100644 index b88edbc0905..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/hr.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "hr", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "detalji o proizvodu" - }, - "inventoryAlerts": { - "adjustedQuantity": "Vaš proizvod količina je prilagođena max količini na lageru" - }, - "mediaGallery": { - "deleteImage": "Kliknite da biste uklonili sliku", - "addedImage": "Ovo je nova slika. Objavi za spremanje promjena.", - "removedImage": "Slika je izbrisana. Objavi za spremanje promjena." - } - }, - "availableOptions": "Dostupne opcije" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/hu.json b/imports/plugins/included/product-detail-simple/server/i18n/hu.json deleted file mode 100644 index 8a1cdda3184..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/hu.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "hu", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "termék leírás" - }, - "inventoryAlerts": { - "adjustedQuantity": "A termék mennyisége állították be a max mennyiség raktáron" - }, - "mediaGallery": { - "deleteImage": "Kattintson a kép eltávolítása", - "addedImage": "Ez egy új képet. Adja változások mentéséhez.", - "removedImage": "Képet törölték. Adja változások mentéséhez." - } - }, - "availableOptions": "elérhető opciók" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/index.js b/imports/plugins/included/product-detail-simple/server/i18n/index.js deleted file mode 100644 index 822f1bdf134..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/index.js +++ /dev/null @@ -1,33 +0,0 @@ -import { loadTranslations } from "/imports/plugins/core/core/server/startup/i18n"; - -import ar from "./ar.json"; -import bg from "./bg.json"; -import cs from "./cs.json"; -import de from "./de.json"; -import el from "./el.json"; -import en from "./en.json"; -import es from "./es.json"; -import fr from "./fr.json"; -import he from "./he.json"; -import hr from "./hr.json"; -import hu from "./hu.json"; -import it from "./it.json"; -import my from "./my.json"; -import nb from "./nb.json"; -import nl from "./nl.json"; -import pl from "./pl.json"; -import pt from "./pt.json"; -import ro from "./ro.json"; -import ru from "./ru.json"; -import sl from "./sl.json"; -import sv from "./sv.json"; -import tr from "./tr.json"; -import vi from "./vi.json"; -import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/included/product-detail-simple/server/i18n/it.json b/imports/plugins/included/product-detail-simple/server/i18n/it.json deleted file mode 100644 index eaab691bad3..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/it.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "it", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Dettagli del prodotto" - }, - "inventoryAlerts": { - "adjustedQuantity": "La vostra quantità di prodotto è stato adattato per la quantità massima in magazzino" - }, - "mediaGallery": { - "deleteImage": "Fare clic per rimuovere l'immagine", - "addedImage": "Questa è una nuova immagine. Pubblica per salvare le modifiche.", - "removedImage": "L'immagine è stata cancellata. Pubblica per salvare le modifiche." - } - }, - "availableOptions": "Opzioni disponibili" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/my.json b/imports/plugins/included/product-detail-simple/server/i18n/my.json deleted file mode 100644 index 64250adda5d..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/my.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "my", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "ကုန်ပစ္စည်းအသေးစိတ်" - }, - "inventoryAlerts": { - "adjustedQuantity": "သင့်ရဲ့ကုန်ပစ္စည်းအရေအတွက်စတော့ရှယ်ယာအတွက် max ကိုအရေအတွက်မှချိန်ညှိထားပြီး" - }, - "mediaGallery": { - "deleteImage": "image ကိုဖယ်ရှားပစ်ရန်ကလစ်နှိပ်ပါ", - "addedImage": "ဒါကအသစ်တခုပုံရိပ်ဖြစ်ပါတယ်။ အပြောင်းအလဲများကိုကယ်ဖို့ Publish ။", - "removedImage": "Image ကိုဖျက်ထားသည်။ အပြောင်းအလဲများကိုကယ်ဖို့ Publish ။" - } - }, - "availableOptions": "ရရှိနိုင် Options ကို" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/nb.json b/imports/plugins/included/product-detail-simple/server/i18n/nb.json deleted file mode 100644 index 4ac7614789f..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/nb.json +++ /dev/null @@ -1,5 +0,0 @@ -[{ - "i18n": "nb", - "ns": "product-detail-simple", - "translation": { } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/nl.json b/imports/plugins/included/product-detail-simple/server/i18n/nl.json deleted file mode 100644 index f5268831a2f..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/nl.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "nl", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Productdetails" - }, - "inventoryAlerts": { - "adjustedQuantity": "Uw product hoeveelheid is aangepast aan de maximale hoeveelheid in voorraad" - }, - "mediaGallery": { - "deleteImage": "Klik om de afbeelding te verwijderen", - "addedImage": "Dit is een nieuwe afbeelding. Publiceer om wijzigingen op te slaan.", - "removedImage": "Afbeelding is verwijderd. Publiceer om wijzigingen op te slaan." - } - }, - "availableOptions": "Beschikbare opties" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/pl.json b/imports/plugins/included/product-detail-simple/server/i18n/pl.json deleted file mode 100644 index 2be203cfd23..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/pl.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "pl", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Szczegóły Produktu" - }, - "inventoryAlerts": { - "adjustedQuantity": "Twoja ilość produktów została dostosowana do maksymalnej ilości w magazynie" - }, - "mediaGallery": { - "deleteImage": "Kliknij, aby usunąć obraz", - "addedImage": "To jest nowy wizerunek. Opublikuj, aby zapisać zmiany.", - "removedImage": "Obraz został usunięty. Opublikuj, aby zapisać zmiany." - } - }, - "availableOptions": "Dostępne opcje" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/pt.json b/imports/plugins/included/product-detail-simple/server/i18n/pt.json deleted file mode 100644 index 6c986074210..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/pt.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "pt", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Detalhes do produto" - }, - "inventoryAlerts": { - "adjustedQuantity": "Sua quantidade de produto foi ajustado para a quantidade máxima em estoque" - }, - "mediaGallery": { - "deleteImage": "Clique para remover a imagem", - "addedImage": "Esta é uma nova imagem. Publique para salvar as alterações.", - "removedImage": "A imagem foi excluída. Publique para salvar as alterações." - } - }, - "availableOptions": "Opções disponíveis" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/ro.json b/imports/plugins/included/product-detail-simple/server/i18n/ro.json deleted file mode 100644 index be649a3dd99..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/ro.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "ro", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Detalii produs" - }, - "inventoryAlerts": { - "adjustedQuantity": "Cantitatea dvs. de produs a fost ajustat la cantitatea maximă în stoc" - }, - "mediaGallery": { - "deleteImage": "Faceți clic pentru a elimina imaginea", - "addedImage": "Aceasta este o imagine nouă. Publicați pentru a salva modificările.", - "removedImage": "Imaginea a fost ștearsă. Publicați pentru a salva modificările." - } - }, - "availableOptions": "Opțiuni disponibile" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/ru.json b/imports/plugins/included/product-detail-simple/server/i18n/ru.json deleted file mode 100644 index 40fa6ae4842..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/ru.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "ru", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "информация о продукте" - }, - "inventoryAlerts": { - "adjustedQuantity": "Ваше количество продукта было скорректировано до максимального количества в наличии" - }, - "mediaGallery": { - "deleteImage": "Нажмите, чтобы удалить изображение", - "addedImage": "Это новый образ. Публикация для сохранения изменений.", - "removedImage": "Изображение удалено. Публикация для сохранения изменений." - } - }, - "availableOptions": "Доступные опции" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/sl.json b/imports/plugins/included/product-detail-simple/server/i18n/sl.json deleted file mode 100644 index 8ce59648e04..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/sl.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "sl", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Podrobnosti produkta" - }, - "inventoryAlerts": { - "adjustedQuantity": "Vaš količina izdelka je bil prilagojen za maksimalno količino na zalogi" - }, - "mediaGallery": { - "deleteImage": "Kliknite, da odstranite sliko", - "addedImage": "To je nova podoba. Objavi, da shranite spremembe.", - "removedImage": "Slika je bila izbrisana. Objavi, da shranite spremembe." - } - }, - "availableOptions": "Opcije na voljo" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/sv.json b/imports/plugins/included/product-detail-simple/server/i18n/sv.json deleted file mode 100644 index 19014835935..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/sv.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "sv", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Produktinformation" - }, - "inventoryAlerts": { - "adjustedQuantity": "Din produkt mängd har justerats till max antal i lager" - }, - "mediaGallery": { - "deleteImage": "Klicka för att ta bort bilden", - "addedImage": "Det här är en ny bild. Publicera för att spara ändringar.", - "removedImage": "Bilden har raderats. Publicera för att spara ändringar." - } - }, - "availableOptions": "tillgängliga alternativ" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/tr.json b/imports/plugins/included/product-detail-simple/server/i18n/tr.json deleted file mode 100644 index 4bae0ccd041..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/tr.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "tr", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Ürün Detayları" - }, - "inventoryAlerts": { - "adjustedQuantity": "Ürününüz miktar stok maksimum miktara ayarlandı" - }, - "mediaGallery": { - "deleteImage": "Resmi kaldırmak için tıklayın", - "addedImage": "Bu yeni bir görüntü. Değişiklikleri kaydetmek için yayınla.", - "removedImage": "Resim silindi. Değişiklikleri kaydetmek için yayınla." - } - }, - "availableOptions": "mevcut seçenekler" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/vi.json b/imports/plugins/included/product-detail-simple/server/i18n/vi.json deleted file mode 100644 index ad240de63ee..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/vi.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "vi", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "Thông tin chi tiết sản phẩm" - }, - "inventoryAlerts": { - "adjustedQuantity": "số lượng sản phẩm của bạn đã được điều chỉnh theo số lượng tối đa trong kho" - }, - "mediaGallery": { - "deleteImage": "Nhấp để xóa hình ảnh", - "addedImage": "Đây là hình ảnh mới. Xuất bản để lưu thay đổi.", - "removedImage": "Hình ảnh đã bị xóa. Xuất bản để lưu thay đổi." - } - }, - "availableOptions": "Tùy chọn có sẵn" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/i18n/zh.json b/imports/plugins/included/product-detail-simple/server/i18n/zh.json deleted file mode 100644 index ea3475f5130..00000000000 --- a/imports/plugins/included/product-detail-simple/server/i18n/zh.json +++ /dev/null @@ -1,22 +0,0 @@ -[{ - "i18n": "zh", - "ns": "product-detail-simple", - "translation": { - "product-detail-simple": { - "admin": { - "settings": { - "productDetailsLabel": "产品详情" - }, - "inventoryAlerts": { - "adjustedQuantity": "您的产品数量进行了调整,在股票的最大数量" - }, - "mediaGallery": { - "deleteImage": "点击删除图片", - "addedImage": "这是一个新的形象。发布以保存更改。", - "removedImage": "图片已被删除。发布以保存更改。" - } - }, - "availableOptions": "可用选项" - } - } -}] diff --git a/imports/plugins/included/product-detail-simple/server/index.js b/imports/plugins/included/product-detail-simple/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/included/product-detail-simple/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/included/product-variant/components/productGrid.js b/imports/plugins/included/product-variant/components/productGrid.js index 9fb81a12415..3f77380ba78 100644 --- a/imports/plugins/included/product-variant/components/productGrid.js +++ b/imports/plugins/included/product-variant/components/productGrid.js @@ -1,6 +1,8 @@ /* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */ -import React, { Component } from "react"; +import React, { Component, Fragment } from "react"; import PropTypes from "prop-types"; +import gql from "graphql-tag"; +import { Mutation } from "react-apollo"; import { Components } from "@reactioncommerce/reaction-components"; import { Session } from "meteor/session"; import { i18next } from "/client/api"; @@ -24,6 +26,27 @@ import Typography from "@material-ui/core/Typography"; import Chip from "@reactioncommerce/catalyst/Chip"; import withStyles from "@material-ui/core/styles/withStyles"; +const publishProductsToCatalog = gql` + mutation ($productIds: [ID]!) { + publishProductsToCatalog(productIds: $productIds) { + product { + productId + title + isDeleted + supportedFulfillmentTypes + variants { + _id + title + options { + _id + title + } + } + } + } + } +`; + const styles = (theme) => ({ leftChip: { marginBottom: theme.spacing(2), @@ -84,7 +107,6 @@ const styles = (theme) => ({ } }); -// TODO: refactor to function class ProductGrid extends Component { static propTypes = { classes: PropTypes.object, @@ -110,11 +132,11 @@ class ProductGrid extends Component { } static defaultProps = { - onArchiveProducts() {}, - onDuplicateProducts() {}, - onPublishProducts() {}, - onSelectAllProducts() {}, - onSetProductVisibility() {}, + onArchiveProducts() { }, + onDuplicateProducts() { }, + onPublishProducts() { }, + onSelectAllProducts() { }, + onSetProductVisibility() { }, productMediaById: {} }; @@ -165,7 +187,7 @@ class ProductGrid extends Component { {i18next.t("admin.productTable.bulkActions.filteredProducts")} - { selected } + {selected}
); @@ -248,8 +270,8 @@ class ProductGrid extends Component { this.handleCloseBulkActions(); } - handleBulkActionPublish = () => { - this.props.onPublishProducts(this.props.selectedProductIds); + handleBulkActionPublish = (mutation) => { + this.props.onPublishProducts(this.props.selectedProductIds, mutation); this.handleCloseBulkActions(); } @@ -281,7 +303,6 @@ class ProductGrid extends Component { const { bulkActionMenuAnchorEl } = this.state; const count = selectedProductIds.length; const isEnabled = Array.isArray(selectedProductIds) && selectedProductIds.length; - return (