From db4e8d2aa500a9da59f994e64df4f8999ebe6965 Mon Sep 17 00:00:00 2001 From: Aaron Judd Date: Wed, 21 Jun 2017 19:17:34 -0700 Subject: [PATCH] Release 1.3.0 (#2417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Features - **Meteor 1.5 (#2371)** - **Order fulfillment UI updates (#2400)** - **React Router updated (#2123)** - **React Navbar (and deprecated Blaze navbar) (#2306)** - **Re-introduce icon toolbar as shortcutBar (#2261)** - **React unit testing example (#2170)** - **[WIP] [Style guide](https://styleguide.reactioncommerce.com)** ## Changes / Fixes - __Update current user's name on Navbar and profile page when address is added. (#2455)__ - __Fix #2422 on email invite link leading to blank screen (#2437)__ - __Fix #2459 router range error fix (#2476)__ - __Remove older Blaze based launchdock plugin (#2467)__ - __Remove random regex checks on names. Fixes #2461 (#2471)__ - __Update media gallery new / deleted image indicators (#2469)__ - __Fix #2356 on tag menu-sidebar glitch (#2472)__ - __Fix #2452 on UI icon toolbar (#2460)__ - __set css property overflow on horizontal to hidden (#2458)__ - __Navbar hover issue (#2451)__ - __update memory usage in CircleCI build (#2462)__ - __refactor default admin user creation (#2453)__ - __Bunyan and Loggly updates (#2425)__ - __Updated chai package__ - __add missing "orders not found" text (#2424)__ - __Add closeOnClick option to DropDownMenu component (#2418)__ - **Fixed console error when dragging product images (#2443)** - **Remove unmaintained Browserstack acceptance tests (#2430)** - **Add css style to differentiate read from unread notifications (#2442)** - **Added module aliases @reactioncommerce/reaction-ui (#2436)** - **Switch to Reaction’s new fork of Nodemailer (#2427)** - **Admin should be able to invite a user with the same name (#2386)** - **Updated yarn.lock and removed npm-shrinkwrap.json** - **use route permissions in register.js files (#2388)** - **Updated, refreshed order/fulfillment UI (#2400)** - **Change line width to match GH PR review width (#2407)** - **Fix Improper Cart Merge (#2387)** - **Implement missing router functions (#2393)** - **Correct the way we record tax overrides** - **CollectionFS cfs:tempstore and cfs:worker to Fix concurrency issues with GridFS uploads (#2096)** - **Fix typo in inventory test description (#2364)** - **Added Nigerian Naira to currency list in (#2366)** - **Fix git tagging on CircleCI 2.0 (#2362)** - **Adding the license description with link on README (#2365)** - **Better handling for unique routes for React Router (#2327)** - **Don't throwback a step if tax fails** - **Updated UI colors for styleguide (#2339)** - **Add loading component to Fix error (#2340)** - **Allow a MAIL_URL string without auth (#2330)** - **Defer Fixture load until the default shop is loaded (#2329)** - **Fix conditional in Circle deploy script (#2338)** - **Fix refunds not showing (#2317)** - **Add Verification Url to Welcome Email (#2216)** - **CircleCI 2.0 and docker base update (#2334)** - **i18n translation updates (#2302 #2420)** - **Change customer notification message when order is processed. (#2290)** - **Allow loader to show when one is passed in and defined BUGFIX (#2303)** - **Add the Vietnamese Dong as a supported currency (#2248)** - **Updated shipping / payment error messages in checkout (#2271)** - **Fix #2203 Long Strings Handling in Product Option Title (#2266)** - **Simplify core layout component (#2257)** - **Fix multiple refunds for stripe (#2260)** --- .babelrc | 4 - .bithoundrc | 1 - .circleci/build.sh | 28 + .circleci/config.yml | 56 + .circleci/deploy.sh | 59 + .circleci/docker-compose.yml | 17 + .circleci/install.sh | 39 + .editorconfig | 2 +- .eslintrc | 1 + .meteor/.finished-upgraders | 1 + .meteor/packages | 34 +- .meteor/release | 2 +- .meteor/versions | 56 +- .reaction/ci/build.sh | 4 +- .reaction/ci/deploy-development.sh | 30 - .reaction/ci/deploy-production.sh | 29 - Dockerfile | 2 +- circle.yml | 31 - client/api/index.js | 6 +- client/lib/buffer.js | 7 + .../modules/accounts/components/auth/index.js | 3 + .../accounts/components/auth/loginButtons.js | 76 + .../accounts/components/auth/signIn.js | 182 + .../accounts/components/auth/signUp.js | 185 + .../components/dropdown/mainDropdown.js | 132 + .../accounts/components/helpers/index.js | 1 + .../components/helpers/loginFormMessages.js | 41 + client/modules/accounts/components/index.js | 3 + .../components/passwordReset/forgot.js | 142 + .../components/passwordReset/index.js | 2 + .../passwordReset/updatePasswordOverlay.js | 179 + .../accounts/containers/auth/authContainer.js | 220 + .../modules/accounts/containers/auth/index.js | 2 + .../containers/auth/loginContainer.js | 94 + .../dropdown/mainDropdownContainer.js | 159 + .../accounts/containers/helpers/index.js | 1 + .../containers/helpers/messagesContainer.js | 40 + client/modules/accounts/containers/index.js | 3 + .../passwordReset/forgotContainer.js | 123 + .../containers/passwordReset/index.js | 2 + .../passwordReset/passwordOverlayContainer.js | 131 + client/modules/accounts/helpers/helpers.js | 34 +- client/modules/accounts/helpers/templates.js | 6 +- .../accounts/templates/addressBook/add/add.js | 61 +- .../templates/addressBook/addressBook.js | 25 +- .../templates/addressBook/edit/edit.js | 84 +- .../templates/addressBook/form/form.js | 4 +- .../templates/addressBook/review/review.html | 145 + .../templates/addressBook/review/review.js | 116 + .../templates/dashboard/dashboard.html | 2 +- .../accounts/templates/dashboard/dashboard.js | 7 + .../accounts/templates/dropdown/dropdown.html | 2 +- .../accounts/templates/dropdown/dropdown.js | 10 - .../templates/dropdown/helpers/helpers.js | 19 + .../templates/dropdown/helpers/index.js | 2 + .../templates/dropdown/helpers/templates.js | 79 + .../templates/dropdown/helpers/util.js | 96 + .../accounts/templates/forgot/forgot.html | 31 - .../accounts/templates/forgot/forgot.js | 66 - .../templates/login/loginButtons.html | 20 - .../accounts/templates/login/loginForm.html | 27 +- .../accounts/templates/login/loginForm.js | 157 +- .../accounts/templates/login/loginForm.less | 7 +- .../accounts/templates/signIn/signIn.html | 57 - .../accounts/templates/signIn/signIn.js | 76 - .../accounts/templates/signUp/signUp.html | 51 - .../accounts/templates/signUp/signUp.js | 81 - .../updatePassword/updatePassword.html | 40 +- .../updatePassword/updatePassword.js | 94 +- .../templates/verify/verifyAccount.html | 12 + .../templates/verify/verifyAccount.js | 21 + client/modules/core/helpers/utils.js | 2 +- client/modules/i18n/startup.js | 5 +- .../templates/currency/components/currency.js | 73 + .../currency/containers/currencyContainer.js | 96 + .../i18n/templates/currency/currency.html | 19 - .../i18n/templates/currency/currency.js | 85 - .../i18n/templates/header/components/i18n.js | 65 + .../header/containers/i18nContainer.js | 55 + .../modules/i18n/templates/header/i18n.html | 19 - client/modules/i18n/templates/header/i18n.js | 56 - client/modules/router/main.js | 2 +- imports/plugins/core/accounts/register.js | 6 + imports/plugins/core/accounts/server/index.js | 1 + imports/plugins/core/accounts/server/init.js | 9 + .../checkout/client/components/cartIcon.js | 31 + .../client/container/cartIconContainer.js | 29 + .../core/checkout/server/methods/workflow.js | 4 +- .../core/dashboard/client/components/index.js | 1 + .../client/components/shortcutBar.js | 91 + .../dashboard/client/components/toolbar.js | 30 +- .../client/containers/packageListContainer.js | 29 +- .../client/templates/import/import.html | 2 +- .../templates/shop/settings/settings.html | 6 +- .../templates/shop/settings/settings.js | 16 +- .../core/dashboard/server/i18n/ar.json | 25 +- .../core/dashboard/server/i18n/bg.json | 25 +- .../core/dashboard/server/i18n/cs.json | 25 +- .../core/dashboard/server/i18n/de.json | 25 +- .../core/dashboard/server/i18n/el.json | 25 +- .../core/dashboard/server/i18n/en.json | 25 +- .../core/dashboard/server/i18n/es.json | 25 +- .../core/dashboard/server/i18n/fr.json | 25 +- .../core/dashboard/server/i18n/he.json | 29 +- .../core/dashboard/server/i18n/hr.json | 25 +- .../core/dashboard/server/i18n/hu.json | 25 +- .../core/dashboard/server/i18n/it.json | 25 +- .../core/dashboard/server/i18n/my.json | 25 +- .../core/dashboard/server/i18n/nb.json | 15 +- .../core/dashboard/server/i18n/nl.json | 25 +- .../core/dashboard/server/i18n/pl.json | 25 +- .../core/dashboard/server/i18n/pt.json | 25 +- .../core/dashboard/server/i18n/ro.json | 25 +- .../core/dashboard/server/i18n/ru.json | 25 +- .../core/dashboard/server/i18n/sl.json | 25 +- .../core/dashboard/server/i18n/sv.json | 25 +- .../core/dashboard/server/i18n/tr.json | 25 +- .../core/dashboard/server/i18n/vi.json | 25 +- .../core/dashboard/server/i18n/zh.json | 25 +- .../email/client/components/emailConfig.js | 12 +- .../email/client/components/emailSettings.js | 10 +- .../client/components/localizationSettings.js | 8 +- imports/plugins/core/i18n/server/i18n/ar.json | 15 +- imports/plugins/core/i18n/server/i18n/bg.json | 15 +- imports/plugins/core/i18n/server/i18n/cs.json | 15 +- imports/plugins/core/i18n/server/i18n/de.json | 15 +- imports/plugins/core/i18n/server/i18n/el.json | 15 +- imports/plugins/core/i18n/server/i18n/en.json | 15 +- imports/plugins/core/i18n/server/i18n/es.json | 15 +- imports/plugins/core/i18n/server/i18n/fr.json | 15 +- imports/plugins/core/i18n/server/i18n/he.json | 10 +- imports/plugins/core/i18n/server/i18n/hr.json | 15 +- imports/plugins/core/i18n/server/i18n/hu.json | 15 +- imports/plugins/core/i18n/server/i18n/it.json | 15 +- imports/plugins/core/i18n/server/i18n/my.json | 15 +- imports/plugins/core/i18n/server/i18n/nl.json | 15 +- imports/plugins/core/i18n/server/i18n/pl.json | 15 +- imports/plugins/core/i18n/server/i18n/pt.json | 15 +- imports/plugins/core/i18n/server/i18n/ro.json | 15 +- imports/plugins/core/i18n/server/i18n/ru.json | 15 +- imports/plugins/core/i18n/server/i18n/sl.json | 15 +- imports/plugins/core/i18n/server/i18n/sv.json | 15 +- imports/plugins/core/i18n/server/i18n/tr.json | 15 +- imports/plugins/core/i18n/server/i18n/vi.json | 15 +- imports/plugins/core/i18n/server/i18n/zh.json | 15 +- .../layout/client/components/cartDrawer.js | 12 - .../core/layout/client/components/content.js | 18 - .../layout/client/components/coreLayout.js | 25 +- .../core/layout/client/components/header.js | 20 - .../core/layout/client/components/index.js | 1 + .../client/templates/layout/alerts/alerts.js | 3 + .../templates/layout/alerts/inlineAlerts.js | 3 +- .../templates/layout/alerts/reactionAlerts.js | 3 +- .../__snapshots__/orderSummary.spec.js.snap | 211 + .../__tests__/components/orderSummary.spec.js | 57 + .../client/components/invoiceActions.js | 89 + .../orders/client/components/orderSummary.js | 59 +- .../orders/client/components/ordersList.js | 184 + .../orders/client/components/productImage.js | 60 + .../containers/invoiceActionsContainer.js | 51 + .../containers/orderSummaryContainer.js | 32 +- .../client/containers/ordersListContainer.js | 101 + imports/plugins/core/orders/client/index.js | 5 - .../client/templates/details/detail.html | 29 - .../orders/client/templates/details/detail.js | 35 - .../core/orders/client/templates/orders.html | 127 +- .../core/orders/client/templates/orders.js | 189 +- .../client/templates/social/orderSocial.html | 43 - .../templates/workflow/orderCompleted.html | 2 - .../templates/workflow/orderSummary.html | 2 - .../templates/workflow/shippingInvoice.html | 194 +- .../templates/workflow/shippingInvoice.js | 14 +- .../templates/workflow/shippingTracking.html | 124 +- .../client/templates/workflow/workflow.html | 33 +- .../plugins/core/orders/server/i18n/ar.json | 21 + .../plugins/core/orders/server/i18n/bg.json | 21 + .../plugins/core/orders/server/i18n/cs.json | 21 + .../plugins/core/orders/server/i18n/de.json | 21 + .../plugins/core/orders/server/i18n/el.json | 21 + .../plugins/core/orders/server/i18n/en.json | 21 + .../plugins/core/orders/server/i18n/es.json | 21 + .../plugins/core/orders/server/i18n/fr.json | 21 + .../plugins/core/orders/server/i18n/he.json | 25 +- .../plugins/core/orders/server/i18n/hr.json | 21 + .../plugins/core/orders/server/i18n/hu.json | 21 + .../plugins/core/orders/server/i18n/it.json | 21 + .../plugins/core/orders/server/i18n/my.json | 21 + .../plugins/core/orders/server/i18n/nb.json | 17 +- .../plugins/core/orders/server/i18n/nl.json | 21 + .../plugins/core/orders/server/i18n/pl.json | 21 + .../plugins/core/orders/server/i18n/pt.json | 21 + .../plugins/core/orders/server/i18n/ro.json | 21 + .../plugins/core/orders/server/i18n/ru.json | 21 + .../plugins/core/orders/server/i18n/sl.json | 21 + .../plugins/core/orders/server/i18n/sv.json | 21 + .../plugins/core/orders/server/i18n/tr.json | 21 + .../plugins/core/orders/server/i18n/vi.json | 21 + .../plugins/core/orders/server/i18n/zh.json | 21 + .../client/checkout/payment/methods.html | 19 +- .../client/checkout/payment/methods.js | 7 +- .../plugins/core/payments/server/i18n/ar.json | 1 + .../plugins/core/payments/server/i18n/bg.json | 1 + .../plugins/core/payments/server/i18n/cs.json | 1 + .../plugins/core/payments/server/i18n/de.json | 1 + .../plugins/core/payments/server/i18n/el.json | 1 + .../plugins/core/payments/server/i18n/en.json | 1 + .../plugins/core/payments/server/i18n/es.json | 1 + .../plugins/core/payments/server/i18n/fr.json | 1 + .../plugins/core/payments/server/i18n/hr.json | 1 + .../plugins/core/payments/server/i18n/hu.json | 1 + .../plugins/core/payments/server/i18n/it.json | 1 + .../plugins/core/payments/server/i18n/my.json | 1 + .../plugins/core/payments/server/i18n/nl.json | 1 + .../plugins/core/payments/server/i18n/pl.json | 1 + .../plugins/core/payments/server/i18n/pt.json | 1 + .../plugins/core/payments/server/i18n/ro.json | 1 + .../plugins/core/payments/server/i18n/ru.json | 1 + .../plugins/core/payments/server/i18n/sl.json | 1 + .../plugins/core/payments/server/i18n/sv.json | 1 + .../plugins/core/payments/server/i18n/tr.json | 1 + .../plugins/core/payments/server/i18n/vi.json | 1 + .../plugins/core/payments/server/i18n/zh.json | 1 + .../client/containers/publishContainer.js | 6 +- .../core/revisions/server/i18n/ar.json | 2 +- .../core/revisions/server/i18n/bg.json | 2 +- .../core/revisions/server/i18n/cs.json | 2 +- .../core/revisions/server/i18n/de.json | 2 +- .../core/revisions/server/i18n/el.json | 2 +- .../core/revisions/server/i18n/en.json | 2 +- .../core/revisions/server/i18n/es.json | 2 +- .../core/revisions/server/i18n/fr.json | 2 +- .../core/revisions/server/i18n/hr.json | 2 +- .../core/revisions/server/i18n/hu.json | 2 +- .../core/revisions/server/i18n/it.json | 2 +- .../core/revisions/server/i18n/my.json | 2 +- .../core/revisions/server/i18n/nl.json | 2 +- .../core/revisions/server/i18n/pl.json | 2 +- .../core/revisions/server/i18n/pt.json | 2 +- .../core/revisions/server/i18n/ro.json | 2 +- .../core/revisions/server/i18n/ru.json | 2 +- .../core/revisions/server/i18n/sl.json | 2 +- .../core/revisions/server/i18n/sv.json | 2 +- .../core/revisions/server/i18n/tr.json | 2 +- .../core/revisions/server/i18n/vi.json | 2 +- .../core/revisions/server/i18n/zh.json | 2 +- imports/plugins/core/router/client/app.js | 6 +- imports/plugins/core/router/client/startup.js | 10 +- .../core/router/lib/__tests__/router.spec.js | 100 + imports/plugins/core/router/lib/router.js | 344 +- .../client/templates/checkout/shipping.html | 19 +- .../client/templates/checkout/shipping.js | 10 +- .../plugins/core/shipping/server/i18n/ar.json | 1 + .../plugins/core/shipping/server/i18n/bg.json | 1 + .../plugins/core/shipping/server/i18n/cs.json | 1 + .../plugins/core/shipping/server/i18n/de.json | 1 + .../plugins/core/shipping/server/i18n/el.json | 1 + .../plugins/core/shipping/server/i18n/en.json | 1 + .../plugins/core/shipping/server/i18n/es.json | 1 + .../plugins/core/shipping/server/i18n/fr.json | 1 + .../plugins/core/shipping/server/i18n/hr.json | 1 + .../plugins/core/shipping/server/i18n/hu.json | 1 + .../plugins/core/shipping/server/i18n/it.json | 1 + .../plugins/core/shipping/server/i18n/my.json | 1 + .../plugins/core/shipping/server/i18n/nl.json | 1 + .../plugins/core/shipping/server/i18n/pl.json | 1 + .../plugins/core/shipping/server/i18n/pt.json | 1 + .../plugins/core/shipping/server/i18n/ro.json | 1 + .../plugins/core/shipping/server/i18n/ru.json | 1 + .../plugins/core/shipping/server/i18n/sl.json | 1 + .../plugins/core/shipping/server/i18n/sv.json | 1 + .../plugins/core/shipping/server/i18n/tr.json | 1 + .../plugins/core/shipping/server/i18n/vi.json | 1 + .../plugins/core/shipping/server/i18n/zh.json | 1 + .../core/taxes/client/settings/custom.js | 5 +- .../plugins/core/taxes/server/i18n/ar.json | 1 + .../plugins/core/taxes/server/i18n/bg.json | 1 + .../plugins/core/taxes/server/i18n/cs.json | 1 + .../plugins/core/taxes/server/i18n/de.json | 1 + .../plugins/core/taxes/server/i18n/el.json | 1 + .../plugins/core/taxes/server/i18n/en.json | 1 + .../plugins/core/taxes/server/i18n/es.json | 1 + .../plugins/core/taxes/server/i18n/fr.json | 1 + .../plugins/core/taxes/server/i18n/he.json | 1 + .../plugins/core/taxes/server/i18n/hr.json | 1 + .../plugins/core/taxes/server/i18n/hu.json | 1 + .../plugins/core/taxes/server/i18n/it.json | 1 + .../plugins/core/taxes/server/i18n/my.json | 1 + .../plugins/core/taxes/server/i18n/nl.json | 1 + .../plugins/core/taxes/server/i18n/pl.json | 1 + .../plugins/core/taxes/server/i18n/pt.json | 1 + .../plugins/core/taxes/server/i18n/ro.json | 1 + .../plugins/core/taxes/server/i18n/ru.json | 1 + .../plugins/core/taxes/server/i18n/sl.json | 1 + .../plugins/core/taxes/server/i18n/sv.json | 1 + .../plugins/core/taxes/server/i18n/tr.json | 1 + .../plugins/core/taxes/server/i18n/vi.json | 1 + .../plugins/core/taxes/server/i18n/zh.json | 1 + .../components/navbar/components/brand.js | 42 + .../components/navbar/components/navbar.js | 130 + .../navbar/containers/navbarContainer.js | 39 + .../client/components/navbar/navbar.html | 21 +- .../client/components/navbar/navbar.js | 61 +- .../ui-tagnav/client/components/tagGroup.js | 170 + .../client/components/tagGroup/tagGroup.html | 11 - .../client/components/tagGroup/tagGroup.js | 50 - .../client/components/tagGroupBody.js | 174 + .../client/components/tagGroupHeader.js | 72 + .../ui-tagnav/client/components/tagNav.js | 115 + .../client/components/tagNav/tagNav.html | 36 - .../client/components/tagNav/tagNav.js | 381 - .../client/components/tagTree/tagTree.html | 31 - .../client/components/tagTree/tagTree.js | 101 - .../client/containers/tagNavContainer.js | 454 ++ .../core/ui-tagnav/client/helpers/tags.js | 28 +- .../plugins/core/ui-tagnav/client/index.js | 8 - .../__tests__/__snapshots__/badge.js.snap | 17 + .../components/badge/__tests__/badge.js | 42 + .../core/ui/client/components/badge/badge.js | 70 + .../core/ui/client/components/badge/index.js | 1 + .../ui/client/components/button/button.jsx | 15 +- .../ui/client/components/button/iconButton.js | 6 + .../__snapshots__/clickToCopy.js.snap | 28 + .../clickToCopy/__tests__/clickToCopy.js | 41 + .../components/clickToCopy/clickToCopy.js | 87 + .../ui/client/components/clickToCopy/index.js | 1 + .../ui/client/components/divider/divider.js | 5 +- .../core/ui/client/components/forms/form.js | 4 +- .../core/ui/client/components/index.js | 2 + .../core/ui/client/components/media/media.js | 20 +- .../client/components/media/mediaGallery.js | 27 +- .../ui/client/components/menu/dropDownMenu.js | 66 +- .../core/ui/client/components/menu/menu.js | 17 +- .../ui/client/components/menu/menuItem.js | 10 +- .../ui/client/components/popover/popover.js | 54 +- .../core/ui/client/components/tags/tag.jsx | 72 +- .../core/ui/client/components/tags/tags.jsx | 101 +- .../client/components/textfield/textfield.js | 6 +- .../client/components/toolbar/toolbarGroup.js | 6 +- .../__snapshots__/translation.js.snap | 7 + .../translation/__tests__/translation.js | 38 + .../included/analytics/client/startup.js | 1 + .../client/templates/reactionAnalytics.html | 6 +- .../included/analytics/server/i18n/ar.json | 9 + .../included/analytics/server/i18n/bg.json | 9 + .../included/analytics/server/i18n/cs.json | 9 + .../included/analytics/server/i18n/de.json | 9 + .../included/analytics/server/i18n/el.json | 9 + .../included/analytics/server/i18n/en.json | 9 + .../included/analytics/server/i18n/es.json | 9 + .../included/analytics/server/i18n/fr.json | 9 + .../included/analytics/server/i18n/he.json | 10 +- .../included/analytics/server/i18n/hr.json | 9 + .../included/analytics/server/i18n/hu.json | 9 + .../included/analytics/server/i18n/it.json | 9 + .../included/analytics/server/i18n/my.json | 9 + .../included/analytics/server/i18n/nb.json | 13 +- .../included/analytics/server/i18n/nl.json | 9 + .../included/analytics/server/i18n/pl.json | 9 + .../included/analytics/server/i18n/pt.json | 9 + .../included/analytics/server/i18n/ro.json | 9 + .../included/analytics/server/i18n/ru.json | 9 + .../included/analytics/server/i18n/sl.json | 9 + .../included/analytics/server/i18n/sv.json | 9 + .../included/analytics/server/i18n/tr.json | 9 + .../included/analytics/server/i18n/vi.json | 9 + .../included/analytics/server/i18n/zh.json | 9 + .../default-theme/client/styles/badge.less | 101 + .../default-theme/client/styles/base.less | 32 - .../client/styles/buttonSelect.less | 16 +- .../client/styles/cart/addressBook.less | 47 + .../client/styles/dashboard/console.less | 87 +- .../client/styles/dashboard/orders.less | 164 +- .../client/styles/dropdowns.less | 6 + .../client/styles/layout/layout.less | 1 + .../default-theme/client/styles/main.less | 1 + .../default-theme/client/styles/media.less | 16 +- .../default-theme/client/styles/navbar.less | 69 +- .../client/styles/products/childVariant.less | 1 + .../client/styles/products/productDetail.less | 1 + .../client/styles/products/productGrid.less | 2 +- .../client/styles/search/results.less | 2 +- .../default-theme/client/styles/tagGroup.less | 6 +- .../default-theme/client/styles/tagNav.less | 12 +- .../default-theme/client/styles/tags.less | 2 +- .../client/styles/themeEditor.less | 2 +- .../default-theme/client/styles/toolbar.less | 21 + .../client/styles/variables.less | 367 +- .../server/methods/inventory.app-test.js | 96 +- .../included/jobcontrol/server/jobs/cart.js | 4 +- .../launchdock-connect/client/index.js | 9 - .../client/templates/connect.html | 53 - .../client/templates/connect.js | 29 - .../client/templates/dashboard.html | 112 - .../client/templates/dashboard.js | 220 - .../client/templates/dashboard.less | 83 - .../client/templates/settings.html | 45 - .../client/templates/settings.js | 40 - .../launchdock-connect/lib/collections.js | 18 - .../launchdock-connect/lib/launchdock.js | 49 - .../included/launchdock-connect/register.js | 32 - .../launchdock-connect/server/hooks.js | 29 - .../launchdock-connect/server/i18n/ar.json | 18 - .../launchdock-connect/server/i18n/bg.json | 18 - .../launchdock-connect/server/i18n/cs.json | 18 - .../launchdock-connect/server/i18n/de.json | 18 - .../launchdock-connect/server/i18n/el.json | 18 - .../launchdock-connect/server/i18n/en.json | 18 - .../launchdock-connect/server/i18n/es.json | 18 - .../launchdock-connect/server/i18n/fr.json | 18 - .../launchdock-connect/server/i18n/he.json | 5 - .../launchdock-connect/server/i18n/hr.json | 18 - .../launchdock-connect/server/i18n/hu.json | 18 - .../launchdock-connect/server/i18n/index.js | 33 - .../launchdock-connect/server/i18n/it.json | 18 - .../launchdock-connect/server/i18n/my.json | 18 - .../launchdock-connect/server/i18n/nb.json | 5 - .../launchdock-connect/server/i18n/nl.json | 18 - .../launchdock-connect/server/i18n/pl.json | 18 - .../launchdock-connect/server/i18n/pt.json | 18 - .../launchdock-connect/server/i18n/ro.json | 18 - .../launchdock-connect/server/i18n/ru.json | 18 - .../launchdock-connect/server/i18n/sl.json | 18 - .../launchdock-connect/server/i18n/sv.json | 18 - .../launchdock-connect/server/i18n/tr.json | 18 - .../launchdock-connect/server/i18n/vi.json | 18 - .../launchdock-connect/server/i18n/zh.json | 18 - .../launchdock-connect/server/index.js | 6 - .../launchdock-connect/server/methods.js | 97 - .../launchdock-connect/server/publications.js | 19 - .../notifications/client/styles/dropdown.css | 8 +- .../client/styles/notifications.less | 6 +- .../server/methods/notifications.js | 4 +- .../schemas/{package.js => authnet.js} | 7 +- .../lib/collections/schemas/index.js | 2 +- .../server/methods/authnet.js | 32 +- .../client/checkout/braintree.js | 28 +- .../lib/collections/schemas/braintree.js | 6 +- .../server/methods/braintreeApi.js | 13 +- .../server/methods/exampleapi.js | 4 +- .../client/templates/checkout/return/done.js | 2 +- .../lib/collections/schemas/paypal.js | 6 +- .../payments-paypal/server/methods/express.js | 4 +- .../payments-stripe/client/checkout/stripe.js | 2 +- .../lib/collections/schemas/stripe.js | 4 - .../client/components/productDetail.js | 2 +- .../client/components/variantList.js | 2 +- .../client/containers/publishContainer.js | 20 +- .../product-detail-simple/server/i18n/ar.json | 3 +- .../product-detail-simple/server/i18n/bg.json | 3 +- .../product-detail-simple/server/i18n/cs.json | 3 +- .../product-detail-simple/server/i18n/de.json | 3 +- .../product-detail-simple/server/i18n/el.json | 3 +- .../product-detail-simple/server/i18n/en.json | 8 +- .../product-detail-simple/server/i18n/es.json | 3 +- .../product-detail-simple/server/i18n/fr.json | 3 +- .../product-detail-simple/server/i18n/he.json | 6 +- .../product-detail-simple/server/i18n/hr.json | 3 +- .../product-detail-simple/server/i18n/hu.json | 3 +- .../product-detail-simple/server/i18n/it.json | 3 +- .../product-detail-simple/server/i18n/my.json | 3 +- .../product-detail-simple/server/i18n/nl.json | 3 +- .../product-detail-simple/server/i18n/pl.json | 3 +- .../product-detail-simple/server/i18n/pt.json | 3 +- .../product-detail-simple/server/i18n/ro.json | 3 +- .../product-detail-simple/server/i18n/ru.json | 3 +- .../product-detail-simple/server/i18n/sl.json | 3 +- .../product-detail-simple/server/i18n/sv.json | 3 +- .../product-detail-simple/server/i18n/tr.json | 3 +- .../product-detail-simple/server/i18n/vi.json | 3 +- .../product-detail-simple/server/i18n/zh.json | 3 +- .../variants/variantForm/childVariant.js | 2 +- .../publications/searchresults.app-test.js | 12 +- .../client/templates/settings/rates.js | 6 +- .../social/client/components/settings.js | 2 +- .../included/social/server/i18n/ar.json | 31 +- .../included/social/server/i18n/bg.json | 31 +- .../included/social/server/i18n/cs.json | 31 +- .../included/social/server/i18n/de.json | 31 +- .../included/social/server/i18n/el.json | 31 +- .../included/social/server/i18n/en.json | 33 +- .../included/social/server/i18n/es.json | 31 +- .../included/social/server/i18n/fr.json | 31 +- .../included/social/server/i18n/he.json | 22 +- .../included/social/server/i18n/hr.json | 31 +- .../included/social/server/i18n/hu.json | 31 +- .../included/social/server/i18n/it.json | 31 +- .../included/social/server/i18n/my.json | 31 +- .../included/social/server/i18n/nb.json | 18 +- .../included/social/server/i18n/nl.json | 31 +- .../included/social/server/i18n/pl.json | 31 +- .../included/social/server/i18n/pt.json | 31 +- .../included/social/server/i18n/ro.json | 31 +- .../included/social/server/i18n/ru.json | 31 +- .../included/social/server/i18n/sl.json | 31 +- .../included/social/server/i18n/sv.json | 31 +- .../included/social/server/i18n/tr.json | 31 +- .../included/social/server/i18n/vi.json | 31 +- .../included/social/server/i18n/zh.json | 31 +- .../taxes-avalara/server/hooks/hooks.js | 8 +- .../taxes-avalara/server/methods/taxCalc.js | 63 +- .../included/taxes-taxjar/server/i18n/nb.json | 2 +- .../test-utils/__mocks__/client/api/index.js | 5 + .../test-utils/__mocks__/meteor/accounts.js | 0 .../__mocks__/meteor/alanning:roles.js | 0 .../__mocks__/meteor/aldeed-simple-schema.js | 7 + imports/test-utils/__mocks__/meteor/blaze.js | 4 + .../meteor/gadicc:blaze-react-component.js | 1 + .../__mocks__/meteor/kadira:dochead.js | 5 + imports/test-utils/__mocks__/meteor/meteor.js | 5 + imports/test-utils/__mocks__/meteor/mongo.js | 0 imports/test-utils/__mocks__/meteor/random.js | 3 + .../__mocks__/meteor/reactive-dict.js | 5 + .../__mocks__/meteor/reactive-var.js | 0 .../test-utils/__mocks__/meteor/templating.js | 0 .../test-utils/__mocks__/meteor/tracker.js | 9 + lib/api/account-validation.js | 3 +- lib/api/catalog.js | 2 +- lib/api/compose.js | 2 +- lib/api/index.js | 1 + lib/collections/schemas/accounts.js | 9 + lib/collections/schemas/address.js | 6 + lib/collections/schemas/notifications.js | 4 +- lib/collections/schemas/payments.js | 6 +- lib/collections/schemas/revisions.js | 1 + npm-shrinkwrap.json | 6684 ----------------- package.json | 73 +- packages/tempstore/.npm/package/.gitignore | 1 + packages/tempstore/.npm/package/README | 7 + .../.npm/package/npm-shrinkwrap.json | 14 + packages/tempstore/.travis.yml | 5 + packages/tempstore/.versions | 29 + packages/tempstore/CHANGELOG.md | 169 + packages/tempstore/LICENSE.md | 20 + packages/tempstore/README.md | 24 + packages/tempstore/api.md | 112 + packages/tempstore/internal.api.md | 225 + packages/tempstore/package.js | 34 + packages/tempstore/tempStore.js | 399 + packages/tempstore/tests/server-tests.js | 39 + packages/worker/.travis.yml | 5 + packages/worker/.versions | 32 + packages/worker/CHANGELOG.md | 123 + packages/worker/LICENSE.md | 20 + packages/worker/README.md | 8 + packages/worker/api.md | 38 + packages/worker/fileWorker.js | 186 + packages/worker/internal.api.md | 143 + packages/worker/package.js | 36 + packages/worker/tests/client-tests.js | 44 + packages/worker/tests/server-tests.js | 49 + private/data/Shops.json | 20 + private/data/i18n/ar.json | 38 +- private/data/i18n/bg.json | 38 +- private/data/i18n/cs.json | 38 +- private/data/i18n/de.json | 44 +- private/data/i18n/el.json | 38 +- private/data/i18n/en.json | 46 +- private/data/i18n/es.json | 38 +- private/data/i18n/fr.json | 38 +- private/data/i18n/he.json | 31 +- private/data/i18n/hr.json | 38 +- private/data/i18n/hu.json | 38 +- private/data/i18n/it.json | 38 +- private/data/i18n/my.json | 38 +- private/data/i18n/nb.json | 6 +- private/data/i18n/nl.json | 38 +- private/data/i18n/pl.json | 38 +- private/data/i18n/pt.json | 38 +- private/data/i18n/ro.json | 38 +- private/data/i18n/ru.json | 38 +- private/data/i18n/sl.json | 38 +- private/data/i18n/sv.json | 38 +- private/data/i18n/tr.json | 38 +- private/data/i18n/vi.json | 38 +- private/data/i18n/zh.json | 38 +- .../templates/accounts/sendWelcomeEmail.html | 2 +- server/api/core/core.js | 107 +- server/api/core/email/config.js | 20 +- server/api/core/import.js | 6 +- server/api/geocoder.js | 17 +- server/api/index.js | 19 +- server/api/logger/index.js | 1 + server/api/logger/loggly.js | 67 + server/api/{logger.js => logger/main.js} | 19 +- server/jobs/email.js | 2 +- server/methods/accounts/accounts.js | 930 ++- server/methods/core/cart-merge.app-test.js | 28 + server/methods/core/cart.js | 23 +- server/methods/core/orders.js | 3 +- server/publications/collections/accounts.js | 1 + .../members-publications.app-test.js | 4 +- .../orders-publications.app-test.js | 4 +- server/publications/collections/products.js | 7 - server/publications/collections/sessions.js | 1 - server/startup/accounts.js | 9 +- server/startup/load-data.js | 22 +- tests/acceptance-tests/config/settings.yml | 11 - .../config/test-suite-config.yml | 17 - tests/acceptance-tests/config/user-data.yml | 24 - .../acceptance-tests/elements/element-ids.yml | 3 - .../acceptance-tests/elements/element-map.yml | 94 - .../lib/admin-order-actions.js | 23 - .../lib/basic-user-actions.js | 59 - tests/acceptance-tests/lib/get-elements.js | 18 - tests/acceptance-tests/lib/get-test-config.js | 11 - .../lib/user-permissions-reset.js | 27 - .../acceptance-tests/lib/user-shop-actions.js | 112 - tests/acceptance-tests/lib/visa-generator.js | 13 - .../authnet/authorizenet-refund.app-test.js | 56 - .../authnet/authorizenet-void.app-test.js | 50 - .../guest-authorizenet-checkout.app-test.js | 38 - ...register-authorizenet-checkout.app-test.js | 37 - .../braintree/braintree-refund.app-test.js | 54 - .../braintree/braintree-void.app-test.js | 51 - .../guest-braintree-checkout.app-test.js | 39 - .../register-braintree-checkout.app-test.js | 38 - .../example-payment-refund.app-test.js | 48 - ...guest-example-payment-checkout.app-test.js | 39 - ...ister-example-payment-checkout.app-test.js | 37 - .../paypal/guest-paypal-checkout.app-test.js | 40 - .../paypal/paypal-refund.app-test.js | 49 - .../register-paypal-checkout.app-test.js | 39 - .../stripe/guest-stripe-checkout.app-test.js | 38 - .../register-stripe-checkout.app-test.js | 38 - .../stripe/stripe-refund.app-test.js | 49 - .../dashboard-permissions.app-test.js | 41 - .../shop-settings-permissions.app-test.js | 38 - .../smoke-tests/simple-login.app-test.js | 32 - tests/runner/browserstack.conf.js | 70 - tests/runner/local.conf.js | 40 - tests/runner/test-suite.js | 48 - yarn.lock | 2723 ++++++- 632 files changed, 14901 insertions(+), 14443 deletions(-) delete mode 100644 .babelrc create mode 100755 .circleci/build.sh create mode 100644 .circleci/config.yml create mode 100755 .circleci/deploy.sh create mode 100644 .circleci/docker-compose.yml create mode 100755 .circleci/install.sh delete mode 100755 .reaction/ci/deploy-development.sh delete mode 100755 .reaction/ci/deploy-production.sh delete mode 100644 circle.yml create mode 100644 client/lib/buffer.js create mode 100644 client/modules/accounts/components/auth/index.js create mode 100644 client/modules/accounts/components/auth/loginButtons.js create mode 100644 client/modules/accounts/components/auth/signIn.js create mode 100644 client/modules/accounts/components/auth/signUp.js create mode 100644 client/modules/accounts/components/dropdown/mainDropdown.js create mode 100644 client/modules/accounts/components/helpers/index.js create mode 100644 client/modules/accounts/components/helpers/loginFormMessages.js create mode 100644 client/modules/accounts/components/index.js create mode 100644 client/modules/accounts/components/passwordReset/forgot.js create mode 100644 client/modules/accounts/components/passwordReset/index.js create mode 100644 client/modules/accounts/components/passwordReset/updatePasswordOverlay.js create mode 100644 client/modules/accounts/containers/auth/authContainer.js create mode 100644 client/modules/accounts/containers/auth/index.js create mode 100644 client/modules/accounts/containers/auth/loginContainer.js create mode 100644 client/modules/accounts/containers/dropdown/mainDropdownContainer.js create mode 100644 client/modules/accounts/containers/helpers/index.js create mode 100644 client/modules/accounts/containers/helpers/messagesContainer.js create mode 100644 client/modules/accounts/containers/index.js create mode 100644 client/modules/accounts/containers/passwordReset/forgotContainer.js create mode 100644 client/modules/accounts/containers/passwordReset/index.js create mode 100644 client/modules/accounts/containers/passwordReset/passwordOverlayContainer.js create mode 100644 client/modules/accounts/templates/addressBook/review/review.html create mode 100644 client/modules/accounts/templates/addressBook/review/review.js create mode 100644 client/modules/accounts/templates/dropdown/helpers/helpers.js create mode 100644 client/modules/accounts/templates/dropdown/helpers/index.js create mode 100644 client/modules/accounts/templates/dropdown/helpers/templates.js create mode 100644 client/modules/accounts/templates/dropdown/helpers/util.js delete mode 100644 client/modules/accounts/templates/forgot/forgot.html delete mode 100644 client/modules/accounts/templates/forgot/forgot.js delete mode 100644 client/modules/accounts/templates/login/loginButtons.html delete mode 100644 client/modules/accounts/templates/signIn/signIn.html delete mode 100644 client/modules/accounts/templates/signIn/signIn.js delete mode 100644 client/modules/accounts/templates/signUp/signUp.html delete mode 100644 client/modules/accounts/templates/signUp/signUp.js create mode 100644 client/modules/accounts/templates/verify/verifyAccount.html create mode 100644 client/modules/accounts/templates/verify/verifyAccount.js create mode 100644 client/modules/i18n/templates/currency/components/currency.js create mode 100644 client/modules/i18n/templates/currency/containers/currencyContainer.js delete mode 100644 client/modules/i18n/templates/currency/currency.html delete mode 100644 client/modules/i18n/templates/currency/currency.js create mode 100644 client/modules/i18n/templates/header/components/i18n.js create mode 100644 client/modules/i18n/templates/header/containers/i18nContainer.js delete mode 100644 client/modules/i18n/templates/header/i18n.html delete mode 100644 client/modules/i18n/templates/header/i18n.js create mode 100644 imports/plugins/core/accounts/server/init.js create mode 100644 imports/plugins/core/checkout/client/components/cartIcon.js create mode 100644 imports/plugins/core/checkout/client/container/cartIconContainer.js create mode 100644 imports/plugins/core/dashboard/client/components/shortcutBar.js delete mode 100644 imports/plugins/core/layout/client/components/cartDrawer.js delete mode 100644 imports/plugins/core/layout/client/components/content.js delete mode 100644 imports/plugins/core/layout/client/components/header.js create mode 100644 imports/plugins/core/orders/client/__tests__/components/__snapshots__/orderSummary.spec.js.snap create mode 100644 imports/plugins/core/orders/client/__tests__/components/orderSummary.spec.js create mode 100644 imports/plugins/core/orders/client/components/invoiceActions.js create mode 100644 imports/plugins/core/orders/client/components/ordersList.js create mode 100644 imports/plugins/core/orders/client/components/productImage.js create mode 100644 imports/plugins/core/orders/client/containers/invoiceActionsContainer.js create mode 100644 imports/plugins/core/orders/client/containers/ordersListContainer.js delete mode 100644 imports/plugins/core/orders/client/templates/details/detail.html delete mode 100644 imports/plugins/core/orders/client/templates/details/detail.js delete mode 100644 imports/plugins/core/orders/client/templates/social/orderSocial.html delete mode 100644 imports/plugins/core/orders/client/templates/workflow/orderCompleted.html delete mode 100644 imports/plugins/core/orders/client/templates/workflow/orderSummary.html create mode 100644 imports/plugins/core/router/lib/__tests__/router.spec.js create mode 100644 imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js create mode 100644 imports/plugins/core/ui-navbar/client/components/navbar/components/navbar.js create mode 100644 imports/plugins/core/ui-navbar/client/components/navbar/containers/navbarContainer.js create mode 100644 imports/plugins/core/ui-tagnav/client/components/tagGroup.js delete mode 100644 imports/plugins/core/ui-tagnav/client/components/tagGroup/tagGroup.html delete mode 100644 imports/plugins/core/ui-tagnav/client/components/tagGroup/tagGroup.js create mode 100644 imports/plugins/core/ui-tagnav/client/components/tagGroupBody.js create mode 100644 imports/plugins/core/ui-tagnav/client/components/tagGroupHeader.js create mode 100644 imports/plugins/core/ui-tagnav/client/components/tagNav.js delete mode 100644 imports/plugins/core/ui-tagnav/client/components/tagNav/tagNav.html delete mode 100644 imports/plugins/core/ui-tagnav/client/components/tagNav/tagNav.js delete mode 100644 imports/plugins/core/ui-tagnav/client/components/tagTree/tagTree.html delete mode 100644 imports/plugins/core/ui-tagnav/client/components/tagTree/tagTree.js create mode 100644 imports/plugins/core/ui-tagnav/client/containers/tagNavContainer.js create mode 100644 imports/plugins/core/ui/client/components/badge/__tests__/__snapshots__/badge.js.snap create mode 100644 imports/plugins/core/ui/client/components/badge/__tests__/badge.js create mode 100644 imports/plugins/core/ui/client/components/badge/badge.js create mode 100644 imports/plugins/core/ui/client/components/badge/index.js create mode 100644 imports/plugins/core/ui/client/components/clickToCopy/__tests__/__snapshots__/clickToCopy.js.snap create mode 100644 imports/plugins/core/ui/client/components/clickToCopy/__tests__/clickToCopy.js create mode 100644 imports/plugins/core/ui/client/components/clickToCopy/clickToCopy.js create mode 100644 imports/plugins/core/ui/client/components/clickToCopy/index.js create mode 100644 imports/plugins/core/ui/client/components/translation/__tests__/__snapshots__/translation.js.snap create mode 100644 imports/plugins/core/ui/client/components/translation/__tests__/translation.js create mode 100644 imports/plugins/included/default-theme/client/styles/badge.less delete mode 100644 imports/plugins/included/launchdock-connect/client/index.js delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/connect.html delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/connect.js delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/dashboard.html delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/dashboard.js delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/dashboard.less delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/settings.html delete mode 100644 imports/plugins/included/launchdock-connect/client/templates/settings.js delete mode 100644 imports/plugins/included/launchdock-connect/lib/collections.js delete mode 100644 imports/plugins/included/launchdock-connect/lib/launchdock.js delete mode 100644 imports/plugins/included/launchdock-connect/register.js delete mode 100644 imports/plugins/included/launchdock-connect/server/hooks.js delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/ar.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/bg.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/cs.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/de.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/el.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/en.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/es.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/fr.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/he.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/hr.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/hu.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/index.js delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/it.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/my.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/nb.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/nl.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/pl.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/pt.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/ro.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/ru.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/sl.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/sv.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/tr.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/vi.json delete mode 100644 imports/plugins/included/launchdock-connect/server/i18n/zh.json delete mode 100644 imports/plugins/included/launchdock-connect/server/index.js delete mode 100644 imports/plugins/included/launchdock-connect/server/methods.js delete mode 100644 imports/plugins/included/launchdock-connect/server/publications.js rename imports/plugins/included/payments-authnet/lib/collections/schemas/{package.js => authnet.js} (89%) create mode 100644 imports/test-utils/__mocks__/client/api/index.js create mode 100644 imports/test-utils/__mocks__/meteor/accounts.js create mode 100644 imports/test-utils/__mocks__/meteor/alanning:roles.js create mode 100644 imports/test-utils/__mocks__/meteor/aldeed-simple-schema.js create mode 100644 imports/test-utils/__mocks__/meteor/blaze.js create mode 100644 imports/test-utils/__mocks__/meteor/gadicc:blaze-react-component.js create mode 100644 imports/test-utils/__mocks__/meteor/kadira:dochead.js create mode 100644 imports/test-utils/__mocks__/meteor/meteor.js create mode 100644 imports/test-utils/__mocks__/meteor/mongo.js create mode 100644 imports/test-utils/__mocks__/meteor/random.js create mode 100644 imports/test-utils/__mocks__/meteor/reactive-dict.js create mode 100644 imports/test-utils/__mocks__/meteor/reactive-var.js create mode 100644 imports/test-utils/__mocks__/meteor/templating.js create mode 100644 imports/test-utils/__mocks__/meteor/tracker.js delete mode 100644 npm-shrinkwrap.json create mode 100644 packages/tempstore/.npm/package/.gitignore create mode 100644 packages/tempstore/.npm/package/README create mode 100644 packages/tempstore/.npm/package/npm-shrinkwrap.json create mode 100644 packages/tempstore/.travis.yml create mode 100644 packages/tempstore/.versions create mode 100644 packages/tempstore/CHANGELOG.md create mode 100644 packages/tempstore/LICENSE.md create mode 100644 packages/tempstore/README.md create mode 100644 packages/tempstore/api.md create mode 100644 packages/tempstore/internal.api.md create mode 100644 packages/tempstore/package.js create mode 100644 packages/tempstore/tempStore.js create mode 100644 packages/tempstore/tests/server-tests.js create mode 100644 packages/worker/.travis.yml create mode 100644 packages/worker/.versions create mode 100644 packages/worker/CHANGELOG.md create mode 100644 packages/worker/LICENSE.md create mode 100644 packages/worker/README.md create mode 100644 packages/worker/api.md create mode 100644 packages/worker/fileWorker.js create mode 100644 packages/worker/internal.api.md create mode 100644 packages/worker/package.js create mode 100644 packages/worker/tests/client-tests.js create mode 100644 packages/worker/tests/server-tests.js create mode 100644 server/api/logger/index.js create mode 100644 server/api/logger/loggly.js rename server/api/{logger.js => logger/main.js} (73%) delete mode 100644 tests/acceptance-tests/config/settings.yml delete mode 100644 tests/acceptance-tests/config/test-suite-config.yml delete mode 100644 tests/acceptance-tests/config/user-data.yml delete mode 100644 tests/acceptance-tests/elements/element-ids.yml delete mode 100644 tests/acceptance-tests/elements/element-map.yml delete mode 100644 tests/acceptance-tests/lib/admin-order-actions.js delete mode 100644 tests/acceptance-tests/lib/basic-user-actions.js delete mode 100644 tests/acceptance-tests/lib/get-elements.js delete mode 100644 tests/acceptance-tests/lib/get-test-config.js delete mode 100644 tests/acceptance-tests/lib/user-permissions-reset.js delete mode 100644 tests/acceptance-tests/lib/user-shop-actions.js delete mode 100644 tests/acceptance-tests/lib/visa-generator.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/authnet/authorizenet-refund.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/authnet/authorizenet-void.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/authnet/guest-authorizenet-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/authnet/register-authorizenet-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/braintree/braintree-refund.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/braintree/braintree-void.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/braintree/guest-braintree-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/braintree/register-braintree-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/example/example-payment-refund.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/example/guest-example-payment-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/example/register-example-payment-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/paypal/guest-paypal-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/paypal/paypal-refund.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/paypal/register-paypal-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/stripe/guest-stripe-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/stripe/register-stripe-checkout.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/payment-processors/stripe/stripe-refund.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/permissions/dashboard-permissions.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/permissions/shop-settings-permissions.app-test.js delete mode 100644 tests/acceptance-tests/test/specs/smoke-tests/simple-login.app-test.js delete mode 100644 tests/runner/browserstack.conf.js delete mode 100644 tests/runner/local.conf.js delete mode 100644 tests/runner/test-suite.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 0d172c5c9e0..00000000000 --- a/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "plugins": ["lodash"], - "presets": ["stage-2"] -} diff --git a/.bithoundrc b/.bithoundrc index 291cc454954..2d0ff78570b 100644 --- a/.bithoundrc +++ b/.bithoundrc @@ -59,7 +59,6 @@ "mute": [ "wdio-mocha-framework", "griddle-react", - "nodemailer", "twilio", "react-addons-create-fragment", "react-addons-pure-render-mixin", diff --git a/.circleci/build.sh b/.circleci/build.sh new file mode 100755 index 00000000000..56d37c5cbe4 --- /dev/null +++ b/.circleci/build.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +set -e + +DOCKER_NAMESPACE=${DOCKER_NAMESPACE:-"reactioncommerce/reaction"} + +shopt -s nocasematch + +# if we're not on a deployment branch or a Docker/Release related PR branch, skip the Docker build/test +if ! [[ "$CIRCLE_BRANCH" == "master" || "$CIRCLE_BRANCH" == "development" || + "$CIRCLE_BRANCH" =~ "docker" || "$CIRCLE_BRANCH" =~ "release" ]]; then + echo "Not running a Docker build test branch. Skipping the build." + exit 0 +fi + +# build new image +docker build --build-arg TOOL_NODE_FLAGS="--max-old-space-size=4096" -t reactioncommerce/reaction:latest . + +# run the container and wait for it to boot +docker-compose -f .circleci/docker-compose.yml up -d +sleep 30 + +# use curl to ensure the app returns 200's +docker exec reaction bash -c "apt-get update && apt-get install -y curl && \ + curl --retry 10 --retry-delay 10 -v http://localhost:3000" + +# now change the image tag to the configured name +docker tag reactioncommerce/reaction:latest $DOCKER_NAMESPACE:latest diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..5f9e1a11fb2 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,56 @@ +version: 2 + +jobs: + build: + working_directory: /home/reaction + + docker: + - image: node:7 + + environment: + - DOCKER_VERSION: 17.03.1-ce + - DOCKER_COMPOSE_VERSION: 1.13.0 + - METEOR_ALLOW_SUPERUSER: true + + steps: + - setup_remote_docker + - checkout + + # install OS dependencies + - restore_cache: + name: Restoring Meteor cache + key: meteor + + - run: .circleci/install.sh + + - save_cache: + name: Saving Meteor to cache + key: meteor + paths: + - ~/.meteor + + # install app dependencies + + - run: meteor npm install + + # run tests + - restore_cache: + name: Restoring Meteor dev_bundle cache + key: dev_bundle + + - run: npm test + - run: reaction test + + + - save_cache: + name: Saving Meteor dev_bundle to cache + key: dev_bundle + paths: + - /home/reaction/.meteor/local + + - run: .circleci/build.sh + + # deploy the build (if on a deployment branch) + - deploy: + name: Docker Image Deploment + command: .circleci/deploy.sh diff --git a/.circleci/deploy.sh b/.circleci/deploy.sh new file mode 100755 index 00000000000..2c6b23a9fc1 --- /dev/null +++ b/.circleci/deploy.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +## Required environment variables in your CircleCI dashboard +# (used to push to Docker Hub) +# +# $DOCKER_USER - Docker Hub username +# $DOCKER_PASS - Docker Hub password +# $DOCKER_EMAIL - Docker Hub email + + +## Optional Environment Variables +# (used to customize the destination on Docker Hub without having to edit the CircleCI config) +# +# $DOCKER_NAMESPACE - the image name for production deployments [Default]: reactioncommerce/reaction +# $DOCKER_NAMESPACE_DEV - the image name for development deployments [Default]: reactioncommerce/prequel + + +if [[ "$CIRCLE_BRANCH" != "master" && "$CIRCLE_BRANCH" != "development" ]]; then + echo "Not running a deployment branch." + exit 0 +fi + + +## Development +if [[ "$CIRCLE_BRANCH" == "development" ]]; then + set -e + + DOCKER_NAMESPACE=${DOCKER_NAMESPACE:-"reactioncommerce/reaction"} + DOCKER_NAMESPACE_DEV=${DOCKER_NAMESPACE_DEV:-"reactioncommerce/prequel"} + + docker tag $DOCKER_NAMESPACE:latest $DOCKER_NAMESPACE_DEV:latest + docker tag $DOCKER_NAMESPACE_DEV:latest $DOCKER_NAMESPACE_DEV:$CIRCLE_BUILD_NUM + + docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS + + docker push $DOCKER_NAMESPACE_DEV:$CIRCLE_BUILD_NUM + docker push $DOCKER_NAMESPACE_DEV:latest +fi + + +# Master branch deployment (only runs when a version git tag exists - syntax: "v1.2.3") +if [[ "$CIRCLE_BRANCH" == "master" ]]; then + VERSION=$(git describe --tags | grep "^v[0-9]\+\.[0-9]\+\.[0-9]\+$") + + if [[ "$VERSION" ]]; then + set -e + + DOCKER_NAMESPACE=${DOCKER_NAMESPACE:-"reactioncommerce/reaction"} + + docker tag $DOCKER_NAMESPACE:latest $DOCKER_NAMESPACE:$VERSION + + docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS + + docker push $DOCKER_NAMESPACE:$VERSION + docker push $DOCKER_NAMESPACE:latest + else + echo "On the master branch, but no version tag was found. Skipping image deployment." + fi +fi diff --git a/.circleci/docker-compose.yml b/.circleci/docker-compose.yml new file mode 100644 index 00000000000..ca1fb799719 --- /dev/null +++ b/.circleci/docker-compose.yml @@ -0,0 +1,17 @@ +# Usage: +# docker-compose up -d + +reaction: + container_name: reaction + image: reactioncommerce/reaction:latest + links: + - mongo + ports: + - "3000:3000" + environment: + ROOT_URL: "http://localhost" + MONGO_URL: "mongodb://mongo:27017/reaction" + +mongo: + image: mongo:latest + command: mongod --storageEngine=wiredTiger diff --git a/.circleci/install.sh b/.circleci/install.sh new file mode 100755 index 00000000000..13f1cdc8162 --- /dev/null +++ b/.circleci/install.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +set -x + +# install OS dependencies +apt-get update +apt-get install -y locales + + +# fix Meteor/Mongo locale issue on Debian +# https://github.com/meteor/meteor/issues/4019 +locale-gen en_US.UTF-8 +localedef -i en_GB -f UTF-8 en_US.UTF-8 + + +# install Docker client +curl -L -o /tmp/docker-$DOCKER_VERSION.tgz https://get.docker.com/builds/Linux/x86_64/docker-$DOCKER_VERSION.tgz +tar -xz -C /tmp -f /tmp/docker-$DOCKER_VERSION.tgz +mv /tmp/docker/* /usr/bin +docker -v + + +# install Docker Compose +curl -L https://github.com/docker/compose/releases/download/$DOCKER_COMPOSE_VERSION/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose +chmod +x /usr/local/bin/docker-compose + + +# install Meteor if it's not already +if [[ -f ~/.meteor/meteor ]]; then + printf "\nMeteor already installed. Creating symlink.\n" + ln -s ~/.meteor/meteor /usr/local/bin/meteor; +else + printf "\Installing Meteor\n" + curl https://install.meteor.com | /bin/sh +fi + + +# install Reaction CLI +yarn global add reaction-cli diff --git a/.editorconfig b/.editorconfig index 038fae93405..b4e10c59cee 100644 --- a/.editorconfig +++ b/.editorconfig @@ -12,7 +12,7 @@ insert_final_newline = true trim_trailing_whitespace = false [*.js] -max_line_length = 160 +max_line_length = 120 indent_brace_style = 1TBS spaces_around_operators = true quote_type = double diff --git a/.eslintrc b/.eslintrc index 40c516a2e27..088b394af73 100644 --- a/.eslintrc +++ b/.eslintrc @@ -54,6 +54,7 @@ "args": "after-used" }], "no-use-before-define": [2, "nofunc"], // http://eslint.org/docs/rules/no-use-before-define + "no-implicit-globals": 2, // http://eslint.org/docs/rules/no-implicit-globals /** * Possible errors diff --git a/.meteor/.finished-upgraders b/.meteor/.finished-upgraders index a8020370920..2a56593d3f8 100644 --- a/.meteor/.finished-upgraders +++ b/.meteor/.finished-upgraders @@ -15,3 +15,4 @@ notices-for-facebook-graph-api-2 1.4.0-remove-old-dev-bundle-link 1.4.1-add-shell-server-package 1.4.3-split-account-service-packages +1.5-add-dynamic-import-package diff --git a/.meteor/packages b/.meteor/packages index 1f5ce282dcf..4819d8145da 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -7,21 +7,20 @@ # Core Meteor Packages ### -meteor-base@1.0.4 # Packages every Meteor app needs to have +meteor-base@1.1.0 # Packages every Meteor app needs to have mobile-experience@1.0.4 # Packages for a great mobile UX blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views es5-shim@4.6.15 # ECMAScript 5 compatibility for older browsers. -ecmascript@0.7.3 # Enable ECMAScript2015+ syntax in app code +ecmascript@0.8.0 # Enable ECMAScript2015+ syntax in app code audit-argument-checks@1.0.7 # ensure meteor method argument validation browser-policy@1.1.0 # security-related policies enforced by newer browsers juliancwirko:postcss # CSS post-processing plugin (replaces standard-minifier-css) -abernix:standard-minifier-js # a minifier plugin used for Meteor apps by default session@1.1.7 # ReactiveDict whose contents are preserved across Hot Code Push tracker@1.1.3 # Meteor transparent reactive programming library -mongo@1.1.17 +mongo@1.1.18 random@1.0.10 reactive-var@1.0.11 -reactive-dict@1.1.8 +reactive-dict@1.1.9 check@1.2.5 http@1.2.12 ddp-rate-limiter@1.0.7 @@ -34,17 +33,19 @@ service-configuration@1.0.11 amplify mdg:validated-method shell-server@0.2.3 +dynamic-import # Meteor Auth Packages -accounts-base@1.2.17 +accounts-base@1.3.0 accounts-password@1.3.6 -accounts-facebook@1.1.1 -accounts-google@1.1.2 -accounts-twitter@1.2.1 +accounts-facebook@1.2.0 +accounts-google@1.2.0 +accounts-twitter@1.3.0 oauth-encryption@1.2.1 -# accounts-github -# accounts-weibo -# accounts-oauth +facebook-config-ui@1.0.0 +google-config-ui@1.0.0 +twitter-config-ui@1.0.0 + # Community Packages alanning:roles @@ -59,7 +60,6 @@ cfs:standard-packages cfs:storage-adapter cfs:ui dispatch:run-as-user -jeremy:stripe jparker:gravatar juliancwirko:s-alert juliancwirko:s-alert-stackslide @@ -72,8 +72,8 @@ ongoworks:security raix:ui-dropped-event risul:moment-timezone tmeasday:publish-counts -vsivsi:job-collection@1.4.0 -react-meteor-data +vsivsi:job-collection@=1.4.0 +react-meteor-data@=0.2.9 percolate:migrations gadicc:blaze-react-component @@ -94,6 +94,4 @@ johanbrook:publication-collector # meteorhacks:sikka # additional ddp, login security # Custom Packages -facebook-config-ui@1.0.0 -google-config-ui@1.0.0 -twitter-config-ui@1.0.0 +abernix:standard-minifier-js@2.1.0-beta.0 diff --git a/.meteor/release b/.meteor/release index fb6f3bc15e2..025f64e7073 100644 --- a/.meteor/release +++ b/.meteor/release @@ -1 +1 @@ -METEOR@1.4.4.2 +METEOR@1.5 diff --git a/.meteor/versions b/.meteor/versions index eeb4ef9e5fd..df4ffca00aa 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -1,11 +1,11 @@ -abernix:minifier-js@1.3.19 -abernix:standard-minifier-js@1.3.19 -accounts-base@1.2.17 -accounts-facebook@1.1.1 -accounts-google@1.1.2 +abernix:minifier-js@2.1.0-beta.0 +abernix:standard-minifier-js@2.1.0-beta.0 +accounts-base@1.3.0 +accounts-facebook@1.2.0 +accounts-google@1.2.0 accounts-oauth@1.1.15 -accounts-password@1.3.6 -accounts-twitter@1.2.1 +accounts-password@1.3.7 +accounts-twitter@1.3.0 alanning:roles@1.2.16 aldeed:autoform@5.8.1 aldeed:browser-tests@0.1.1 @@ -19,14 +19,14 @@ allow-deny@1.0.5 amplify@1.0.0 audit-argument-checks@1.0.7 autoupdate@1.3.12 -babel-compiler@6.18.2 +babel-compiler@6.19.3 babel-runtime@1.0.1 base64@1.0.10 binary-heap@1.0.10 blaze@2.3.2 blaze-html-templates@1.1.2 blaze-tools@1.0.10 -boilerplate-generator@1.0.11 +boilerplate-generator@1.1.0 browser-policy@1.1.0 browser-policy-common@1.0.11 browser-policy-content@1.1.0 @@ -55,7 +55,7 @@ cfs:ui@0.1.3 cfs:upload-http@0.0.20 cfs:worker@0.1.4 check@1.2.5 -coffeescript@1.12.3_1 +coffeescript@1.12.6_1 dburles:factory@1.1.0 ddp@1.2.5 ddp-client@1.3.4 @@ -66,13 +66,16 @@ deps@1.0.12 diff-sequence@1.0.7 dispatch:mocha@0.4.1 dispatch:run-as-user@1.1.1 -ecmascript@0.7.3 -ecmascript-runtime@0.3.15 +dynamic-import@0.1.1 +ecmascript@0.8.1 +ecmascript-runtime@0.4.1 +ecmascript-runtime-client@0.4.2 +ecmascript-runtime-server@0.4.1 ejson@1.0.13 -email@1.2.1 +email@1.2.3 es5-shim@4.6.15 facebook-config-ui@1.0.0 -facebook-oauth@1.3.0 +facebook-oauth@1.3.1 fastclick@1.0.13 gadicc:blaze-react-component@1.4.0 geojson-utils@1.0.10 @@ -83,8 +86,7 @@ html-tools@1.0.11 htmljs@1.0.11 http@1.2.12 id-map@1.0.9 -jeremy:stripe@1.6.0 -johanbrook:publication-collector@1.0.7 +johanbrook:publication-collector@1.0.8 jparker:crypto-core@0.1.0 jparker:crypto-md5@0.1.1 jparker:gravatar@0.5.1 @@ -96,28 +98,28 @@ kadira:dochead@1.5.0 launch-screen@1.1.1 less@2.7.9 livedata@1.0.18 -localstorage@1.0.12 +localstorage@1.1.0 logging@1.1.17 matb33:collection-hooks@0.8.4 mdg:validated-method@1.1.0 mdg:validation-error@0.5.1 meteor@1.6.1 -meteor-base@1.0.4 +meteor-base@1.1.0 meteorhacks:ssr@2.2.0 meteorhacks:subs-manager@1.6.4 minifier-css@1.2.16 -minimongo@1.0.23 +minimongo@1.2.1 mobile-experience@1.0.4 mobile-status-bar@1.0.14 -modules@0.8.2 -modules-runtime@0.7.10 -momentjs:moment@2.17.1 -mongo@1.1.17 +modules@0.9.2 +modules-runtime@0.8.0 +momentjs:moment@2.18.1 +mongo@1.1.18 mongo-id@1.0.6 mongo-livedata@1.0.12 mrt:later@1.6.1 natestrauser:select2@4.0.3 -npm-bcrypt@0.9.2 +npm-bcrypt@0.9.3 npm-mongo@2.2.24 oauth@1.1.13 oauth-encryption@1.2.1 @@ -130,13 +132,13 @@ 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.8.8 +promise@0.8.9 raix:eventemitter@0.1.3 raix:ui-dropped-event@0.0.7 random@1.0.10 rate-limit@1.0.8 react-meteor-data@0.2.9 -reactive-dict@1.1.8 +reactive-dict@1.1.9 reactive-var@1.0.11 reload@1.1.11 retry@1.0.9 @@ -162,5 +164,5 @@ ui@1.0.13 underscore@1.0.10 url@1.1.0 vsivsi:job-collection@1.4.0 -webapp@1.3.15 +webapp@1.3.16 webapp-hashing@1.0.9 diff --git a/.reaction/ci/build.sh b/.reaction/ci/build.sh index 5c506849b91..5b94fa8becf 100755 --- a/.reaction/ci/build.sh +++ b/.reaction/ci/build.sh @@ -4,8 +4,8 @@ set -e DOCKER_NAMESPACE=${DOCKER_NAMESPACE:-"reactioncommerce/reaction"} -# if we're not on a deployment branch, skip the Docker build/test -if [[ -z "$CIRCLE_TAG" && "$CIRCLE_BRANCH" != "development" ]]; then +# if we're not on a deployment branch or a Docker related PR branch, skip the Docker build/test +if [[ -z "$CIRCLE_TAG" && "$CIRCLE_BRANCH" != "development" && "$CIRCLE_BRANCH" != *"docker"* ]]; then echo "Not running a deployment branch. Skipping the Docker build test." exit 0 fi diff --git a/.reaction/ci/deploy-development.sh b/.reaction/ci/deploy-development.sh deleted file mode 100755 index 21ce1efa595..00000000000 --- a/.reaction/ci/deploy-development.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -set -e - -## Required environment variables in your CircleCI dashboard -# (used to push to Docker Hub) -# -# $DOCKER_USER - Docker Hub username -# $DOCKER_PASS - Docker Hub password -# $DOCKER_EMAIL - Docker Hub email - - -## Optional Environment Variables -# (used to customize the destination on Docker Hub without having to edit the circle.yml) -# -# $DOCKER_NAMESPACE - the image name for production deployments [Default]: reactioncommerce/reaction -# $DOCKER_NAMESPACE_DEV - the name image for development deployments [Default]: reactioncommerce/prequel - - -# Development branch deployment -DOCKER_NAMESPACE=${DOCKER_NAMESPACE:-"reactioncommerce/reaction"} -DOCKER_NAMESPACE_DEV=${DOCKER_NAMESPACE_DEV:-"reactioncommerce/prequel"} - -docker tag $DOCKER_NAMESPACE:latest $DOCKER_NAMESPACE_DEV:latest -docker tag $DOCKER_NAMESPACE_DEV:latest $DOCKER_NAMESPACE_DEV:$CIRCLE_BUILD_NUM - -docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS - -docker push $DOCKER_NAMESPACE_DEV:$CIRCLE_BUILD_NUM -docker push $DOCKER_NAMESPACE_DEV:latest diff --git a/.reaction/ci/deploy-production.sh b/.reaction/ci/deploy-production.sh deleted file mode 100755 index d9834be7ed7..00000000000 --- a/.reaction/ci/deploy-production.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/bash - -set -e - -## Required environment variables in your CircleCI dashboard -# (used to push to Docker Hub) -# -# $DOCKER_USER - Docker Hub username -# $DOCKER_PASS - Docker Hub password -# $DOCKER_EMAIL - Docker Hub email - - -## Optional Environment Variables -# (used to customize the destination on Docker Hub without having to edit the circle.yml) -# -# $DOCKER_NAMESPACE - the image name for production deployments [Default]: reactioncommerce/reaction -# $DOCKER_NAMESPACE_DEV - the name image for development deployments [Default]: reactioncommerce/prequel - - -# Master branch deployment (only runs when a version git tag exists - syntax: "v1.2.3") -# The git tag is available in $CIRCLE_TAG -DOCKER_NAMESPACE=${DOCKER_NAMESPACE:-"reactioncommerce/reaction"} - -docker tag $DOCKER_NAMESPACE:latest $DOCKER_NAMESPACE:$CIRCLE_TAG - -docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS - -docker push $DOCKER_NAMESPACE:$CIRCLE_TAG -docker push $DOCKER_NAMESPACE:latest diff --git a/Dockerfile b/Dockerfile index 64239ed39ad..b757d25bd91 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM reactioncommerce/base:v1.3.1 +FROM reactioncommerce/base:v2.0.0 # Default environment variables ENV ROOT_URL "http://localhost" diff --git a/circle.yml b/circle.yml deleted file mode 100644 index cd1650b52e8..00000000000 --- a/circle.yml +++ /dev/null @@ -1,31 +0,0 @@ -machine: - node: - version: 7.4.0 - services: - - docker - -dependencies: - cache_directories: - - "~/.meteor" - override: - - if [[ -L ~/.meteor/meteor ]]; then ln -s ~/.meteor/meteor ~/bin/meteor; export PATH="$PATH:~/bin"; fi - - hash meteor 2>/dev/null || curl https://install.meteor.com | /bin/sh - - npm i -g reaction-cli - - meteor npm install - -test: - override: - - reaction test - - .reaction/ci/build.sh - -deployment: - prequel: - branch: development - commands: - - .reaction/ci/deploy-development.sh - - release: - tag: /v[0-9]+(\.[0-9]+)*/ - owner: reactioncommerce - commands: - - .reaction/ci/deploy-production.sh diff --git a/client/api/index.js b/client/api/index.js index 64322a572fc..b588f6f5efb 100644 --- a/client/api/index.js +++ b/client/api/index.js @@ -1,10 +1,8 @@ import { Reaction } from "/client/modules/core"; import { Router } from "/client/modules/router"; -// Legacy globals -// TODO: add deprecation warnings -ReactionCore = Reaction; -ReactionRouter = Router; +window.ReactionCore = Reaction; +window.ReactionRouter = Router; export { Reaction, diff --git a/client/lib/buffer.js b/client/lib/buffer.js new file mode 100644 index 00000000000..87b267caf3b --- /dev/null +++ b/client/lib/buffer.js @@ -0,0 +1,7 @@ +// this is an expensive polyfill for clientside Buffer usage +// TODO refactor to remove this buffer dependency +global.Buffer = global.Buffer || require("buffer").Buffer; // eslint-disable-line + +// how to refactor +// you can easily drop a breakpoint on the error in your browser's inspector, then refresh the page to hit the breakpoint and see via the call stack which package is trying to use Buffer +// https://github.com/meteor/meteor/issues/8645 diff --git a/client/modules/accounts/components/auth/index.js b/client/modules/accounts/components/auth/index.js new file mode 100644 index 00000000000..526fc99f7cf --- /dev/null +++ b/client/modules/accounts/components/auth/index.js @@ -0,0 +1,3 @@ +export LoginButtons from "./loginButtons"; +export SignIn from "./signIn"; +export SignUp from "./signUp"; diff --git a/client/modules/accounts/components/auth/loginButtons.js b/client/modules/accounts/components/auth/loginButtons.js new file mode 100644 index 00000000000..1b7b958d682 --- /dev/null +++ b/client/modules/accounts/components/auth/loginButtons.js @@ -0,0 +1,76 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Button, Divider, Translation } from "/imports/plugins/core/ui/client/components"; + +class LoginButtons extends Component { + static propTypes = { + capitalizeName: PropTypes.func, + currentView: PropTypes.string, + loginServices: PropTypes.func, + onSeparator: PropTypes.func, + onSocialClick: PropTypes.func + } + + renderLoginButtons() { + const enabledServices = this.props.loginServices().filter((service) =>{ + return service.enabled; + }); + + return ( +
+ {this.props.loginServices && + enabledServices.map((service) => ( + + )) + } +
+ ); + } + + renderSeparator() { + if (this.props.onSeparator()) { + return ( +
+ +
+ ); + } + } + + render() { + return ( +
+ {this.renderLoginButtons()} + {this.renderSeparator()} +
+ ); + } +} + +export default LoginButtons; diff --git a/client/modules/accounts/components/auth/signIn.js b/client/modules/accounts/components/auth/signIn.js new file mode 100644 index 00000000000..212fae21aaf --- /dev/null +++ b/client/modules/accounts/components/auth/signIn.js @@ -0,0 +1,182 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import classnames from "classnames"; +import { Button, TextField, Translation } from "/imports/plugins/core/ui/client/components"; + +class SignIn extends Component { + static propTypes = { + credentials: PropTypes.object, + isLoading: PropTypes.bool, + loginFormMessages: PropTypes.func, + messages: PropTypes.object, + onError: PropTypes.func, + onForgotPasswordClick: PropTypes.func, + onFormSubmit: PropTypes.func, + onSignUpClick: PropTypes.func, + uniqueId: PropTypes.string + } + + constructor(props) { + super(props); + + this.state = { + email: props.credentials.email, + password: props.credentials.password + }; + + this.handleFieldChange = this.handleFieldChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + + handleFieldChange = (event, value, field) => { + this.setState({ + [field]: value + }); + } + + handleSubmit = (event) => { + if (this.props.onFormSubmit) { + this.props.onFormSubmit(event, this.state.email, this.state.password); + } + } + + renderEmailErrors() { + if (this.props.onError(this.props.messages.errors && this.props.messages.errors.email)) { + return ( + + + + ); + } + } + + renderPasswordErrors() { + return ( + + {this.props.onError(this.props.messages.errors && this.props.messages.errors.password) && + this.props.messages.errors.password.map((error, i) => ( + + )) + } + + ); + } + + renderFormMessages() { + if (this.props.loginFormMessages) { + return ( +
+ {this.props.loginFormMessages()} +
+ ); + } + } + + renderSpinnerOnWait() { + if (this.props.isLoading === true) { + return ( +
+ +
+ ); + } + return ( + + ); + } + + renderAdminIcons() { + return ( + Reaction.Apps(this.props.adminShortcuts).map((shortcut) => ( + + )) + ); + } + + renderUserIcons() { + return ( + Reaction.Apps(this.props.userShortcuts).map((option) => ( + + )) + ); + } + + renderSignOutButton() { + return ( + + ); + } + + renderSignInComponent() { + return ( +
+
+ +
+
+ +
+
+ ); + } + + render() { + return ( +
+ {this.props.currentUser ? +
+ + + {this.renderUserIcons()} + {this.renderAdminIcons()} + {this.renderSignOutButton()} + + +
+ : +
+ {this.renderSignInComponent()} +
+ } +
+ ); + } +} + +export default MainDropdown; diff --git a/client/modules/accounts/components/helpers/index.js b/client/modules/accounts/components/helpers/index.js new file mode 100644 index 00000000000..be7e8d25998 --- /dev/null +++ b/client/modules/accounts/components/helpers/index.js @@ -0,0 +1 @@ +export LoginFormMessages from "./loginFormMessages"; diff --git a/client/modules/accounts/components/helpers/loginFormMessages.js b/client/modules/accounts/components/helpers/loginFormMessages.js new file mode 100644 index 00000000000..a07b8ccc0d3 --- /dev/null +++ b/client/modules/accounts/components/helpers/loginFormMessages.js @@ -0,0 +1,41 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; + +class LoginFormMessages extends Component { + static propTypes = { + formMessages: PropTypes.object, + loginFormMessages: PropTypes.func + } + + renderFormMessages() { + if (this.props.loginFormMessages) { + if (this.props.formMessages.info) { + return ( +
+

+ {this.props.loginFormMessages()} +

+
+ ); + } else if (this.props.formMessages.alerts) { + return ( +
+

+ {this.props.loginFormMessages()} +

+
+ ); + } + } + } + + render() { + return ( +
+ {this.renderFormMessages()} +
+ ); + } +} + +export default LoginFormMessages; diff --git a/client/modules/accounts/components/index.js b/client/modules/accounts/components/index.js new file mode 100644 index 00000000000..2d0c5401ca8 --- /dev/null +++ b/client/modules/accounts/components/index.js @@ -0,0 +1,3 @@ +export { SignIn, SignUp, LoginButtons } from "./auth"; +export { Forgot, UpdatePasswordOverlay } from "./passwordReset"; +export { LoginFormMessages } from "./helpers"; diff --git a/client/modules/accounts/components/passwordReset/forgot.js b/client/modules/accounts/components/passwordReset/forgot.js new file mode 100644 index 00000000000..187aa7321a2 --- /dev/null +++ b/client/modules/accounts/components/passwordReset/forgot.js @@ -0,0 +1,142 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import classnames from "classnames"; +import { Button, TextField, Translation } from "/imports/plugins/core/ui/client/components"; + +class Forgot extends Component { + static propTypes = { + credentials: PropTypes.object, + isDisabled: PropTypes.bool, + isLoading: PropTypes.bool, + loginFormMessages: PropTypes.func, + messages: PropTypes.object, + onError: PropTypes.func, + onFormSubmit: PropTypes.func, + onSignInClick: PropTypes.func, + uniqueId: PropTypes.string + } + + constructor(props) { + super(props); + + this.state = { + email: props.credentials.email + }; + + this.handleFieldChange = this.handleFieldChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + + handleFieldChange = (event, value, field) => { + this.setState({ + [field]: value + }); + } + + handleSubmit = (event) => { + if (this.props.onFormSubmit) { + this.props.onFormSubmit(event, this.state.email); + } + } + + renderFormMessages() { + if (this.props.loginFormMessages) { + return ( +
+ {this.props.loginFormMessages()} +
+ ); + } + } + + renderEmailErrors() { + if (this.props.onError(this.props.messages.errors && this.props.messages.errors.email)) { + return ( + + + + ); + } + } + + renderSpinnerOnWait() { + if (this.props.isLoading === true) { + return ( +
+ +
+ ); + } + return ( + + ); + } + + render() { + return ( +
+ {this.props.currencies.length > 1 && + + + + + + {this.props.currencies.map((currency) => ( + + ))} + + } +
+ ); + } +} + +export default Currency; diff --git a/client/modules/i18n/templates/currency/containers/currencyContainer.js b/client/modules/i18n/templates/currency/containers/currencyContainer.js new file mode 100644 index 00000000000..05d822be261 --- /dev/null +++ b/client/modules/i18n/templates/currency/containers/currencyContainer.js @@ -0,0 +1,96 @@ +import React, { Component } from "react"; +import { Meteor } from "meteor/meteor"; +import { Match } from "meteor/check"; +import { Reaction } from "/client/api"; +import { composeWithTracker } from "/lib/api/compose"; +import { Cart, Shops } from "/lib/collections"; +import Currency from "../components/currency"; + +class CurrencyContainer extends Component { + constructor(props) { + super(props); + this.handleChange = this.handleChange.bind(this); + } + + handleChange = (value) => { + const currency = value.split(" "); + const currencyName = currency[0]; + // + // this is a sanctioned use of Meteor.user.update + // and only possible because we allow it in the + // UserProfile and ShopMembers publications. + // + Meteor.users.update(Meteor.userId(), { $set: { "profile.currency": currencyName } }); + localStorage.setItem("currency", currencyName); + + const cart = Cart.findOne({ userId: Meteor.userId() }); + + // Attach changed currency to this users cart + Meteor.call("cart/setUserCurrency", cart._id, currencyName); + } + + render() { + return ( +
+ +
+ ); + } +} + +const composer = (props, onData) => { + let currentCurrency = "USD $"; + const currencies = []; + + if (Reaction.Subscriptions.Shops.ready() && Meteor.user()) { + const shop = Shops.findOne(Reaction.getShopId(), { + fields: { + currencies: 1, + currency: 1 + } + }); + if (Match.test(shop, Object) && shop.currency) { + const localStorageCurrency = localStorage.getItem("currency"); + const locale = Reaction.Locale.get(); + + if (localStorageCurrency) { + currentCurrency = localStorageCurrency + " " + shop.currencies[localStorageCurrency].symbol; + } else if (locale && locale.currency && locale.currency.enabled) { + currentCurrency = locale.locale.currency + " " + locale.currency.symbol; + } else { + currentCurrency = shop.currency + " " + shop.currencies[shop.currency].symbol; + } + } + + if (Match.test(shop, Object) && shop.currencies) { + for (const currencyName in shop.currencies) { + if (shop.currencies[currencyName].enabled === true) { + const currency = { currency: currencyName }; + const localStorageCurrency = localStorage.getItem("currency"); + // only one currency will be "active". Either the one + // matching the localStorageCurrency if exists or else + // the one matching shop currency + if (localStorageCurrency) { + if (localStorageCurrency === currency.currency) { + currency.class = "active"; + } + } else if (shop.currency === currency.currency) { + currency.class = "active"; + } + currency.symbol = shop.currencies[currencyName].symbol; + currencies.push(currency); + } + } + } + } + + onData(null, { + currentCurrency: currentCurrency, + currencies: currencies + }); +}; + +export default composeWithTracker(composer)(CurrencyContainer); diff --git a/client/modules/i18n/templates/currency/currency.html b/client/modules/i18n/templates/currency/currency.html deleted file mode 100644 index 770ca3d4e48..00000000000 --- a/client/modules/i18n/templates/currency/currency.html +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/client/modules/i18n/templates/currency/currency.js b/client/modules/i18n/templates/currency/currency.js deleted file mode 100644 index 7aa0b39b26f..00000000000 --- a/client/modules/i18n/templates/currency/currency.js +++ /dev/null @@ -1,85 +0,0 @@ -import { Meteor } from "meteor/meteor"; -import { Reaction } from "/client/api"; -import { Cart, Shops } from "/lib/collections"; - -Template.currencySelect.helpers({ - currencies() { - const currencies = []; - if (Reaction.Subscriptions.Shops.ready() && Meteor.user()) { - const shop = Shops.findOne(Reaction.getShopId(), { - fields: { - currencies: 1, - currency: 1 - } - }); - Reaction.Locale.get(); - if (Match.test(shop, Object) && shop.currencies) { - for (const currencyName in shop.currencies) { - if (shop.currencies[currencyName].enabled === true) { - const currency = { currency: currencyName }; - const localStorageCurrency = localStorage.getItem("currency"); - // only one currency will be "active". Either the one - // matching the localStorageCurrency if exists or else - // the one matching shop currency - if (localStorageCurrency) { - if (localStorageCurrency === currency.currency) { - currency.class = "active"; - } - } else if (shop.currency === currency.currency) { - currency.class = "active"; - } - currency.symbol = shop.currencies[currencyName].symbol; - currencies.push(currency); - } - } - if (currencies.length > 1) { - return currencies; - } - } - } - if (currencies.length > 1) { - return currencies; - } - }, - - currentCurrency() { - if (Reaction.Subscriptions.Shops.ready() && Meteor.user()) { - const shop = Shops.findOne(Reaction.getShopId(), { - fields: { - currencies: 1, - currency: 1 - } - }); - if (Match.test(shop, Object) && shop.currency) { - const localStorageCurrency = localStorage.getItem("currency"); - if (localStorageCurrency) { - return localStorageCurrency + " " + shop.currencies[localStorageCurrency].symbol; - } - const locale = Reaction.Locale.get(); - if (locale && locale.currency && locale.currency.enabled) { - return locale.locale.currency + " " + locale.currency.symbol; - } - return shop.currency + " " + shop.currencies[shop.currency].symbol; - } - } - return "USD $"; - } -}); - -Template.currencySelect.events({ - "click .currency"(event) { - event.preventDefault(); - // - // this is a sanctioned use of Meteor.user.update - // and only possible because we allow it in the - // UserProfile and ShopMembers publications. - // - Meteor.users.update(Meteor.userId(), { $set: { "profile.currency": this.currency } }); - localStorage.setItem("currency", this.currency); - - const cart = Cart.findOne({ userId: Meteor.userId() }); - - // Attach changed currency to this users cart - Meteor.call("cart/setUserCurrency", cart._id, this.currency); - } -}); diff --git a/client/modules/i18n/templates/header/components/i18n.js b/client/modules/i18n/templates/header/components/i18n.js new file mode 100644 index 00000000000..fa38ce62a1d --- /dev/null +++ b/client/modules/i18n/templates/header/components/i18n.js @@ -0,0 +1,65 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Button, Divider, DropDownMenu, MenuItem } from "/imports/plugins/core/ui/client/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: value + }); + + this.props.handleChange(value); + } + + render() { + return ( +
+ {this.props.languages.length > 1 && +
+ + + + {this.props.languages.map((language) => ( + + ))} + +
+ } +
+ ); + } +} + +export default LanguageDropDown; diff --git a/client/modules/i18n/templates/header/containers/i18nContainer.js b/client/modules/i18n/templates/header/containers/i18nContainer.js new file mode 100644 index 00000000000..1ad62ab85fc --- /dev/null +++ b/client/modules/i18n/templates/header/containers/i18nContainer.js @@ -0,0 +1,55 @@ +import React, { Component } from "react"; +import { Reaction } from "/client/api"; +import { Shops } from "/lib/collections"; +import { composeWithTracker } from "/lib/api/compose"; +import Language from "../components/i18n"; + +class LanguageDropdownContainer extends Component { + handleChange = (value) => { + Meteor.users.update(Meteor.userId(), { $set: { "profile.lang": value } }); + } + render() { + return ( +
+ +
+ ); + } +} + +const composer = (props, onData) => { + const languages = []; + let currentLanguage = ""; + if (Reaction.Subscriptions.Shops.ready() && Meteor.user()) { + const shop = Shops.findOne(); + 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().profile; + 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: languages, + currentLanguage: currentLanguage + }); +}; + +export default composeWithTracker(composer)(LanguageDropdownContainer); diff --git a/client/modules/i18n/templates/header/i18n.html b/client/modules/i18n/templates/header/i18n.html deleted file mode 100644 index da9f628ace1..00000000000 --- a/client/modules/i18n/templates/header/i18n.html +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/client/modules/i18n/templates/header/i18n.js b/client/modules/i18n/templates/header/i18n.js deleted file mode 100644 index 285eb4e68fb..00000000000 --- a/client/modules/i18n/templates/header/i18n.js +++ /dev/null @@ -1,56 +0,0 @@ -import { Reaction } from "/client/api"; -import { Shops } from "/lib/collections"; -/** - * i18nChooser helpers - */ - -Template.i18nChooser.helpers({ - languages() { - const languages = []; - if (Reaction.Subscriptions.Shops.ready() && Meteor.user()) { - const shop = Shops.findOne(); - 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().profile; - if (profile && profile.lang) { - if (profile.lang === language.i18n) { - language.class = "active"; - } - } else if (shop.language === language.i18n) { - // we don't have a profile language - // use the shop default - language.class = "active"; - } - languages.push(language); - } - } - if (languages.length > 1) { - return languages; - } - } - } - if (languages.length > 1) { - return languages; - } - } -}); - -/** - * i18nChooser events - */ - -Template.i18nChooser.events({ - "click .i18n-language"(event) { - event.preventDefault(); - // - // this is a sanctioned use of Meteor.user.update - // and only possible because we allow it in the - // UserProfile and ShopMembers publications. - // - Meteor.users.update(Meteor.userId(), { $set: { "profile.lang": this.i18n } }); - } -}); diff --git a/client/modules/router/main.js b/client/modules/router/main.js index 167a8b70bef..5a0e777ddf2 100644 --- a/client/modules/router/main.js +++ b/client/modules/router/main.js @@ -1,3 +1,3 @@ -import { Router } from "/imports/plugins/core/router/lib"; +import { Router } from "@reactioncommerce/reaction-router"; export default Router; diff --git a/imports/plugins/core/accounts/register.js b/imports/plugins/core/accounts/register.js index c148837d8c3..34de811a562 100644 --- a/imports/plugins/core/accounts/register.js +++ b/imports/plugins/core/accounts/register.js @@ -17,6 +17,12 @@ Reaction.registerPackage({ template: "accountsDashboard", workflow: "coreAccountsWorkflow", priority: 1 + }, { + route: "/account/profile/verify:email?", + label: "Account Verify", + name: "account/verify", + workflow: "coreAccountsWorkflow", + template: "verifyAccount" }, { label: "Account Settings", icon: "fa fa-sign-in", diff --git a/imports/plugins/core/accounts/server/index.js b/imports/plugins/core/accounts/server/index.js index 3979f964b5a..0d4325a0404 100644 --- a/imports/plugins/core/accounts/server/index.js +++ b/imports/plugins/core/accounts/server/index.js @@ -1 +1,2 @@ import "./i18n"; +import "./init.js"; diff --git a/imports/plugins/core/accounts/server/init.js b/imports/plugins/core/accounts/server/init.js new file mode 100644 index 00000000000..dc20c007911 --- /dev/null +++ b/imports/plugins/core/accounts/server/init.js @@ -0,0 +1,9 @@ +import { Reaction, Hooks } from "/server/api"; + +Hooks.Events.add("afterCoreInit", () => { + Reaction.addRolesToDefaultRoleSet({ + allShops: true, + roleSets: ["defaultRoles", "defaultVisitorRole"], + roles: ["account/verify"] + }); +}); diff --git a/imports/plugins/core/checkout/client/components/cartIcon.js b/imports/plugins/core/checkout/client/components/cartIcon.js new file mode 100644 index 00000000000..a9cd220922c --- /dev/null +++ b/imports/plugins/core/checkout/client/components/cartIcon.js @@ -0,0 +1,31 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import Velocity from "velocity-animate"; +import { Reaction } from "/client/api"; + +class CartIcon extends Component { + static propTypes = { + cart: PropTypes.object + } + + handleClick = (event) => { + event.preventDefault(); + const cartDrawer = document.querySelector("#cart-drawer-container"); + Velocity(cartDrawer, { opacity: 1 }, 300, () => { + Reaction.toggleSession("displayCart"); + }); + } + + render() { + return ( +
+ + + +
{this.props.cart ? this.props.cart.cartCount() : 0}
+
+ ); + } +} + +export default CartIcon; diff --git a/imports/plugins/core/checkout/client/container/cartIconContainer.js b/imports/plugins/core/checkout/client/container/cartIconContainer.js new file mode 100644 index 00000000000..39bed4dc6c5 --- /dev/null +++ b/imports/plugins/core/checkout/client/container/cartIconContainer.js @@ -0,0 +1,29 @@ +import React, { Component } from "react"; +import { Cart } from "/lib/collections"; +import { composeWithTracker } from "/lib/api/compose"; +import { Reaction } from "/client/api"; +import CartIcon from "../components/cartIcon"; + +class CartIconContainer extends Component { + render() { + return ( +
+ +
+ ); + } +} + +const composer = (props, onData) => { + const subscription = Reaction.Subscriptions.Cart; + + if (subscription.ready()) { + const cart = Cart.findOne(); + + onData(null, { + cart: cart + }); + } +}; + +export default composeWithTracker(composer)(CartIconContainer); diff --git a/imports/plugins/core/checkout/server/methods/workflow.js b/imports/plugins/core/checkout/server/methods/workflow.js index b75e232a6db..5c2339e5607 100644 --- a/imports/plugins/core/checkout/server/methods/workflow.js +++ b/imports/plugins/core/checkout/server/methods/workflow.js @@ -1,5 +1,6 @@ import _ from "lodash"; import { Meteor } from "meteor/meteor"; +import { check, Match } from "meteor/check"; import { Cart, Orders, Packages, Shops } from "/lib/collections"; import { Logger, Reaction } from "/server/api"; @@ -125,8 +126,7 @@ Meteor.methods({ // check to see if the next step has already been processed. // templateProcessedinWorkflow boolean gotoNextWorkflowStep = nextWorkflowStep.template; - templateProcessedinWorkflow = _.includes(currentCart.workflow.workflow, - nextWorkflowStep.template); + templateProcessedinWorkflow = _.includes(currentCart.workflow.workflow, nextWorkflowStep.template); // debug info Logger.debug("currentWorkflowStatus: ", currentWorkflowStatus); diff --git a/imports/plugins/core/dashboard/client/components/index.js b/imports/plugins/core/dashboard/client/components/index.js index 50ef18b22f7..9e9f2f1992c 100644 --- a/imports/plugins/core/dashboard/client/components/index.js +++ b/imports/plugins/core/dashboard/client/components/index.js @@ -1,3 +1,4 @@ export { default as ActionView } from "./actionView"; export { default as PackageList } from "./packageList"; export { default as Toolbar } from "./toolbar"; +export { default as ShortcutBar } from "./shortcutBar"; diff --git a/imports/plugins/core/dashboard/client/components/shortcutBar.js b/imports/plugins/core/dashboard/client/components/shortcutBar.js new file mode 100644 index 00000000000..45261eac4fd --- /dev/null +++ b/imports/plugins/core/dashboard/client/components/shortcutBar.js @@ -0,0 +1,91 @@ +import React, { Component, PropTypes } from "react"; +import { map } from "lodash"; +import { FlatButton, Icon } from "/imports/plugins/core/ui/client/components"; +import { isEqual } from "lodash"; + +class ShortcutBar extends Component { + static propTypes = { + currentView: PropTypes.object, + groupedPackages: PropTypes.object, + handleOpenShortcut: PropTypes.func, + handleShowDashboard: PropTypes.func, + handleShowPackage: PropTypes.func + } + + renderAdminButton() { + return ( + + + + ); + } + + renderSections() { + if (this.props.groupedPackages) { + // Loop through the groups of packages + return map(this.props.groupedPackages, (group, groupName) => { + // Loop through the individual cards of packages + if (Array.isArray(group.packages)) { + const items = group.packages.map((packageData, index) => { + const isActive = isEqual(this.props.currentView, packageData); + + // Standard list element + return ( + + ); + }); + + return ( + + ); + } + + return null; + }); + } + + return null; + } + + render() { + return ( +
+ + {this.renderSections()} +
+ + ); + } +} + +export default ShortcutBar; diff --git a/imports/plugins/core/dashboard/client/components/toolbar.js b/imports/plugins/core/dashboard/client/components/toolbar.js index 94d6e3228b7..785a3dcebdc 100644 --- a/imports/plugins/core/dashboard/client/components/toolbar.js +++ b/imports/plugins/core/dashboard/client/components/toolbar.js @@ -80,17 +80,21 @@ class PublishControls extends Component { renderAdminButton() { return ( - { - Reaction.showActionView({ - i18nKeyTitle: "dashboard.coreTitle", - title: "Dashboard", - template: "dashboardPackages" - }); - }} - > - - + + + { + Reaction.showActionView({ + i18nKeyTitle: "dashboard.coreTitle", + title: "Dashboard", + template: "dashboardPackages" + }); + }} + > + + + ); } @@ -147,10 +151,8 @@ class PublishControls extends Component { {this.renderAddButton()} {this.renderPackageButons()} {this.renderCustomControls()} - - {this.renderAdminButton()} - {/* this.renderMoreOptionsButton() */} + {this.renderAdminButton()} ); } diff --git a/imports/plugins/core/dashboard/client/containers/packageListContainer.js b/imports/plugins/core/dashboard/client/containers/packageListContainer.js index 5e8ed51b1ce..4909e4ff3d7 100644 --- a/imports/plugins/core/dashboard/client/containers/packageListContainer.js +++ b/imports/plugins/core/dashboard/client/containers/packageListContainer.js @@ -14,6 +14,29 @@ function handleShowPackage(event, app) { Reaction.pushActionView(app); } +/** + * handleShowDashboard - Open full dashbaord menu + * @return {undefined} No return value + */ +function handleShowDashboard() { + Reaction.showActionView({ + i18nKeyTitle: "dashboard.coreTitle", + title: "Dashboard", + template: "dashboardPackages" + }); +} + +/** + * handleOpenShortcut - Push dashbaord & package into action view navigation stack + * @param {SyntheticEvent} event Original event + * @param {Object} app Package data + * @return {undefined} No return value + */ +function handleOpenShortcut(event, app) { + Reaction.hideActionViewDetail(); + Reaction.showActionView(app); +} + function composer(props, onData) { const audience = Roles.getRolesForUser(Meteor.userId(), Reaction.getShopId()); const settings = Reaction.Apps({ provides: "settings", enabled: true, audience }) || []; @@ -22,7 +45,7 @@ function composer(props, onData) { .filter((d) => typeof Template[d.template] !== "undefined") || []; onData(null, { - // packages, + currentView: Reaction.getActionView(), groupedPackages: { actions: { title: "Actions", @@ -37,7 +60,9 @@ function composer(props, onData) { }, // Callbacks - handleShowPackage + handleShowPackage, + handleShowDashboard, + handleOpenShortcut }); } diff --git a/imports/plugins/core/dashboard/client/templates/import/import.html b/imports/plugins/core/dashboard/client/templates/import/import.html index 4d0de1dd084..df59f6375fb 100644 --- a/imports/plugins/core/dashboard/client/templates/import/import.html +++ b/imports/plugins/core/dashboard/client/templates/import/import.html @@ -8,7 +8,7 @@ role="button" data-toggle="collapse" data-parent="#shopSettingsAccordian" - data-i18n="shopSettings.import">Import + data-i18n="admin.settings.import">Import
diff --git a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html index 27fa2420624..a4a4a187ce6 100644 --- a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html +++ b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.html @@ -22,7 +22,7 @@ role="button" data-toggle="collapse" data-parent="#shopSettingsAccordian" - data-i18n="shopSettings.general">General + data-i18n="admin.settings.general.label">General
@@ -58,7 +58,7 @@ role="button" data-toggle="collapse" data-parent="#shopSettingsAccordian" - data-i18n="shopSettings.address">Address + data-i18n="admin.settings.address.label">Address
@@ -91,7 +91,7 @@ role="button" data-toggle="collapse" data-parent="#shopSettingsAccordian" - data-i18n="shopSettings.options">Options + data-i18n="admin.settings.options.label">Options
diff --git a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js index bead40cfc8f..8f7e144af3e 100644 --- a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js +++ b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js @@ -143,12 +143,12 @@ Template.shopSettings.helpers({ AutoForm.hooks({ shopEditForm: { onSuccess: function () { - return Alerts.toast(i18next.t("shopSettings.shopGeneralSettingsSaved"), + return Alerts.toast(i18next.t("admin.alerts.shopGeneralSettingsSaved"), "success"); }, onError: function (operation, error) { return Alerts.toast( - `${i18next.t("shopSettings.shopGeneralSettingsFailed")} ${error}`, "error" + `${i18next.t("admin.alerts.shopGeneralSettingsFailed")} ${error}`, "error" ); } } @@ -157,12 +157,12 @@ AutoForm.hooks({ AutoForm.hooks({ shopEditAddressForm: { onSuccess: function () { - return Alerts.toast(i18next.t("shopSettings.shopAddressSettingsSaved"), + return Alerts.toast(i18next.t("admin.alerts.shopAddressSettingsSaved"), "success"); }, onError: function (operation, error) { return Alerts.toast( - `${i18next.t("shopSettings.shopAddressSettingsFailed")} ${error}`, "error" + `${i18next.t("admin.alerts.shopAddressSettingsFailed")} ${error}`, "error" ); } } @@ -172,12 +172,12 @@ AutoForm.hooks({ shopEditExternalServicesForm: { onSuccess: function () { return Alerts.toast( - i18next.t("shopSettings.shopExternalServicesSettingsSaved"), "success" + i18next.t("admin.alerts.shopExternalServicesSettingsSaved"), "success" ); }, onError: function (operation, error) { return Alerts.toast( - `${i18next.t("shopSettings.shopExternalServicesSettingsFailed")} ${error}`, + `${i18next.t("admin.alerts.shopExternalServicesSettingsFailed")} ${error}`, "error" ); } @@ -187,12 +187,12 @@ AutoForm.hooks({ AutoForm.hooks({ shopEditOptionsForm: { onSuccess: function () { - return Alerts.toast(i18next.t("shopSettings.shopOptionsSettingsSaved"), + return Alerts.toast(i18next.t("admin.alerts.shopOptionsSettingsSaved"), "success"); }, onError: function (operation, error) { return Alerts.toast( - `${i18next.t("shopSettings.shopOptionsSettingsFailed")} ${error}`, "error" + `${i18next.t("admin.alerts.shopOptionsSettingsFailed")} ${error}`, "error" ); } } diff --git a/imports/plugins/core/dashboard/server/i18n/ar.json b/imports/plugins/core/dashboard/server/i18n/ar.json index ceb5939aba2..d0028e0ec46 100644 --- a/imports/plugins/core/dashboard/server/i18n/ar.json +++ b/imports/plugins/core/dashboard/server/i18n/ar.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "إعدادات" }, "settings": { - "shopSettingsLabel": "متجر" + "shopSettingsLabel": "متجر", + "import": "إستيراد", + "general": { + "label": "عنوان" + }, + "address": { + "label": "العناوين" + }, + "options": { + "label": "خيارات" + }, + "openexchangerates": { + "refreshPeriod": "تحديث" + } + }, + "alerts": { + "shopGeneralSettingsSaved": ".تم حفظ الإعدادات العامة للمتجر", + "shopGeneralSettingsFailed": ". فشل تحديث الإعدادات العامة للمتجر", + "shopAddressSettingsSaved": "تم حفظ عناوين إعدادات المتجر", + "shopAddressSettingsFailed": ".فشل تحديث إعدادات عناوين التسوق", + "shopExternalServicesSettingsSaved": ".متجر إعدادات الخدمات الخارجية محفوظة", + "shopExternalServicesSettingsFailed": " فشل تحديث شراء الخدمات الخارجية.", + "shopOptionsSettingsSaved": ".خيارات الشراء محفوظة", + "shopOptionsSettingsFailed": "فشل تحديث خيارات الشراء" } } } diff --git a/imports/plugins/core/dashboard/server/i18n/bg.json b/imports/plugins/core/dashboard/server/i18n/bg.json index 49e1be1e9b6..d3d77daea23 100644 --- a/imports/plugins/core/dashboard/server/i18n/bg.json +++ b/imports/plugins/core/dashboard/server/i18n/bg.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Настройки" }, "settings": { - "shopSettingsLabel": "Магазин" + "shopSettingsLabel": "Магазин", + "import": "внос", + "general": { + "label": "Общ" + }, + "address": { + "label": "Адрес 2" + }, + "options": { + "label": "Настроики" + }, + "openexchangerates": { + "refreshPeriod": "Обновяване" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Магазин общи настройки, запаметени.", + "shopGeneralSettingsFailed": "Магазин актуализация на общите настройки провали.", + "shopAddressSettingsSaved": "настройки Shop адрес спасени.", + "shopAddressSettingsFailed": "Магазин актуализация адрес настройки провали.", + "shopExternalServicesSettingsSaved": "Магазин настройки външни услуги, запаметени.", + "shopExternalServicesSettingsFailed": "Магазин актуализация на настройките външни услуги се провали.", + "shopOptionsSettingsSaved": "запаметени опции магазин.", + "shopOptionsSettingsFailed": "опции магазин актуализация неуспешно." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/cs.json b/imports/plugins/core/dashboard/server/i18n/cs.json index 9aa3a7d5765..4ca429503f7 100644 --- a/imports/plugins/core/dashboard/server/i18n/cs.json +++ b/imports/plugins/core/dashboard/server/i18n/cs.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Nastavení" }, "settings": { - "shopSettingsLabel": "Prodejna" + "shopSettingsLabel": "Prodejna", + "import": "Import", + "general": { + "label": "Obecný" + }, + "address": { + "label": "Adresa" + }, + "options": { + "label": "Možnosti" + }, + "openexchangerates": { + "refreshPeriod": "Obnovit" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Obchod obecné uložené nastavení.", + "shopGeneralSettingsFailed": "Obchod aktualizace obecná nastavení se nezdařila.", + "shopAddressSettingsSaved": "Nastavení Shop adresa uložena.", + "shopAddressSettingsFailed": "Obchod aktualizace nastavení adresy se nezdařilo.", + "shopExternalServicesSettingsSaved": "Shopu nastavení externích služeb uložených.", + "shopExternalServicesSettingsFailed": "Obchod aktualizaci nastavení externí služby se nezdařilo.", + "shopOptionsSettingsSaved": "Možnosti Shop uložen.", + "shopOptionsSettingsFailed": "Aktualizace možnosti Shop nezdařila." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/de.json b/imports/plugins/core/dashboard/server/i18n/de.json index 669f5d0c80f..ce48bde397f 100644 --- a/imports/plugins/core/dashboard/server/i18n/de.json +++ b/imports/plugins/core/dashboard/server/i18n/de.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Einstellungen" }, "settings": { - "shopSettingsLabel": "Geschäft" + "shopSettingsLabel": "Geschäft", + "import": "Importieren", + "general": { + "label": "Allgemein" + }, + "address": { + "label": "Adresse 2" + }, + "options": { + "label": "Optionen" + }, + "openexchangerates": { + "refreshPeriod": "Erfrischen" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Die allgemeinen Einstellungen des Geschäfts wurden gespeichert.", + "shopGeneralSettingsFailed": "Die Aktualisierung der allgemeinen Geschäfts-Einstellungen ist fehlgeschlagen. ", + "shopAddressSettingsSaved": "Die Adresseinstellungen des Geschäfts wurden gespeichert. ", + "shopAddressSettingsFailed": "Die Aktualisierung der Geschäfts-Adresse ist fehlgeschlagen.", + "shopExternalServicesSettingsSaved": "Die Einstellungen der externen Dienste des Geschäfts wurden gespeichert.", + "shopExternalServicesSettingsFailed": "Die Aktualisierung der externen Dienst-Einstellungen des Geschäfts ist fehlgeschlagen. ", + "shopOptionsSettingsSaved": "Die Geschäfts-Optionen wurden gespeichert.", + "shopOptionsSettingsFailed": "Die Aktualisierung der Shop-Optionen ist fehlgeschlagen." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/el.json b/imports/plugins/core/dashboard/server/i18n/el.json index e66ee492a00..3155a09dffb 100644 --- a/imports/plugins/core/dashboard/server/i18n/el.json +++ b/imports/plugins/core/dashboard/server/i18n/el.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Ρυθμίσεις" }, "settings": { - "shopSettingsLabel": "Κατάστημα" + "shopSettingsLabel": "Κατάστημα", + "import": "Εισαγωγή", + "general": { + "label": "Γενικός" + }, + "address": { + "label": "Διεύθυνση 2" + }, + "options": { + "label": "επιλογές" + }, + "openexchangerates": { + "refreshPeriod": "Φρεσκάρω" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Κατάστημα γενικές ρυθμίσεις αποθηκεύονται.", + "shopGeneralSettingsFailed": "Κατάστημα ενημέρωση γενικές ρυθμίσεις απέτυχε.", + "shopAddressSettingsSaved": "ρυθμίσεις της διεύθυνσης Shop σωθεί.", + "shopAddressSettingsFailed": "Κατάστημα ενημέρωση ρυθμίσεις της διεύθυνσης απέτυχε.", + "shopExternalServicesSettingsSaved": "Κατάστημα εξωτερικές ρυθμίσεις υπηρεσίες σωθεί.", + "shopExternalServicesSettingsFailed": "Κατάστημα ενημέρωση ρυθμίσεις εξωτερικές υπηρεσίες απέτυχε.", + "shopOptionsSettingsSaved": "επιλογές Shop σωθεί.", + "shopOptionsSettingsFailed": "ενημέρωση επιλογές Shop απέτυχε." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/en.json b/imports/plugins/core/dashboard/server/i18n/en.json index 56fb932e560..b1ee60e8d2a 100644 --- a/imports/plugins/core/dashboard/server/i18n/en.json +++ b/imports/plugins/core/dashboard/server/i18n/en.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Settings" }, "settings": { - "shopSettingsLabel": "Shop" + "shopSettingsLabel": "Shop", + "import": "Import", + "general": { + "label": "General" + }, + "address": { + "label": "Address" + }, + "options": { + "label": "Options" + }, + "openexchangerates": { + "refreshPeriod": "Refresh" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Shop general settings saved.", + "shopGeneralSettingsFailed": "Shop general settings update failed.", + "shopAddressSettingsSaved": "Shop address settings saved.", + "shopAddressSettingsFailed": "Shop address settings update failed.", + "shopExternalServicesSettingsSaved": "Shop external services settings saved.", + "shopExternalServicesSettingsFailed": "Shop external services settings update failed.", + "shopOptionsSettingsSaved": "Shop options saved.", + "shopOptionsSettingsFailed": "Shop options update failed." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/es.json b/imports/plugins/core/dashboard/server/i18n/es.json index 7bcf90c8351..172315bf8f7 100644 --- a/imports/plugins/core/dashboard/server/i18n/es.json +++ b/imports/plugins/core/dashboard/server/i18n/es.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Ajustes" }, "settings": { - "shopSettingsLabel": "tienda" + "shopSettingsLabel": "tienda", + "import": "Importar", + "general": { + "label": "General" + }, + "address": { + "label": "Dirección" + }, + "options": { + "label": "Opciones" + }, + "openexchangerates": { + "refreshPeriod": "Actualizar" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Opciones de generales de tienda guardadas.", + "shopGeneralSettingsFailed": "Actualización de las opciones generales de la tienda fallida.", + "shopAddressSettingsSaved": "Configuración de dirección de la tienda guardada.", + "shopAddressSettingsFailed": "Actualización de opciones de dirección de tienda fallida.", + "shopExternalServicesSettingsSaved": "Opciones de servicios externos de la tienda guardados.", + "shopExternalServicesSettingsFailed": "Actualización de opciones de servicios externos de la tienda fallida.", + "shopOptionsSettingsSaved": "Opciones de la tienda guardadas.", + "shopOptionsSettingsFailed": "Actualización de opciones de tienda fallida." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/fr.json b/imports/plugins/core/dashboard/server/i18n/fr.json index fd3a90caf26..60e31c7065b 100644 --- a/imports/plugins/core/dashboard/server/i18n/fr.json +++ b/imports/plugins/core/dashboard/server/i18n/fr.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Paramètres" }, "settings": { - "shopSettingsLabel": "Boutique" + "shopSettingsLabel": "Boutique", + "import": "Importer", + "general": { + "label": "Général" + }, + "address": { + "label": "Adresse" + }, + "options": { + "label": "Options" + }, + "openexchangerates": { + "refreshPeriod": "Rafraîchir" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Paramètres généraux du magasin enregistrés.", + "shopGeneralSettingsFailed": "Echec de la mise à jour des paramètres généraux du magasin.", + "shopAddressSettingsSaved": "Les paramètres de l'adresse du magasin sont enregistrés.", + "shopAddressSettingsFailed": "Echec de la mise à jour des paramètres de l'adresse du magasin.", + "shopExternalServicesSettingsSaved": "Paramètres des services externes du magasin enregistrés.", + "shopExternalServicesSettingsFailed": "Echec de la mise à jour des paramètres des services externes du magasin.", + "shopOptionsSettingsSaved": "Options du magasin enregistrées.", + "shopOptionsSettingsFailed": "Echec de la mise à jour des options du magasin." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/he.json b/imports/plugins/core/dashboard/server/i18n/he.json index 8bbeb404e07..19c577de8be 100644 --- a/imports/plugins/core/dashboard/server/i18n/he.json +++ b/imports/plugins/core/dashboard/server/i18n/he.json @@ -1,5 +1,32 @@ [{ "i18n": "he", "ns": "reaction-dashboard", - "translation": { } + "translation": { + "reaction-dashboard": { + "admin": { + "settings": { + "import": "ייבוא", + "general": { + "label": "כללי" + }, + "address": { + "label": "כתובת 2" + }, + "options": { + "label": "אפשרויות" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "הגדרות החנות הכלליות נשמרו.", + "shopGeneralSettingsFailed": "עדכון הגדרות כלליות לחנות נכשל.", + "shopAddressSettingsSaved": "הגדרות כתובת החנות נשמרו.", + "shopAddressSettingsFailed": "עדכון הגדרות כתובת החנות נכשל.", + "shopExternalServicesSettingsSaved": "הגדרות שירותי חנות חיצוניים נשמרו.", + "shopExternalServicesSettingsFailed": "עדכון הגדרות שירותי חנות חיצוניים נכשל.", + "shopOptionsSettingsSaved": "אפשרויות החנות נשמרו.", + "shopOptionsSettingsFailed": "עדכון אפשרויות חנות נכשל." + } + } + } + } }] diff --git a/imports/plugins/core/dashboard/server/i18n/hr.json b/imports/plugins/core/dashboard/server/i18n/hr.json index 27f3478ac4a..5a5f4af93e8 100644 --- a/imports/plugins/core/dashboard/server/i18n/hr.json +++ b/imports/plugins/core/dashboard/server/i18n/hr.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Postavke" }, "settings": { - "shopSettingsLabel": "Dućan" + "shopSettingsLabel": "Dućan", + "import": "Uvoz", + "general": { + "label": "General" + }, + "address": { + "label": "Adresa 2" + }, + "options": { + "label": "Opcije" + }, + "openexchangerates": { + "refreshPeriod": "Osvježiti" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Trgovina opće postavke spremljene.", + "shopGeneralSettingsFailed": "Trgovina opće postavke ažuriranje nije uspjelo.", + "shopAddressSettingsSaved": "Postavke Shop adresa spremljena.", + "shopAddressSettingsFailed": "Trgovina postavke adresa ažuriranje nije uspjelo.", + "shopExternalServicesSettingsSaved": "Trgovina vanjske postavke usluge spremljene.", + "shopExternalServicesSettingsFailed": "Trgovina ažuriranje postavki vanjskih usluga nije uspio.", + "shopOptionsSettingsSaved": "Opcije Shop spasio.", + "shopOptionsSettingsFailed": "Opcije Shop ažuriranje nije uspjelo." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/hu.json b/imports/plugins/core/dashboard/server/i18n/hu.json index 57d831ac776..ea33798b184 100644 --- a/imports/plugins/core/dashboard/server/i18n/hu.json +++ b/imports/plugins/core/dashboard/server/i18n/hu.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Beállítások" }, "settings": { - "shopSettingsLabel": "Üzlet" + "shopSettingsLabel": "Üzlet", + "import": "import", + "general": { + "label": "Tábornok" + }, + "address": { + "label": "Cím 2" + }, + "options": { + "label": "Lehetőségek" + }, + "openexchangerates": { + "refreshPeriod": "Frissítés" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Shop általános beállítások mentve.", + "shopGeneralSettingsFailed": "N általános beállítások frissítése nem sikerült.", + "shopAddressSettingsSaved": "Shop cím beállítások mentve.", + "shopAddressSettingsFailed": "Shop címbeállításokat sikertelen volt.", + "shopExternalServicesSettingsSaved": "Shop külső szolgáltatások elmentett beállításokat.", + "shopExternalServicesSettingsFailed": "Shop külső szolgáltatások beállításainak frissítése sikertelen.", + "shopOptionsSettingsSaved": "Shop lehetőségek mentve.", + "shopOptionsSettingsFailed": "Shop lehetőségek sikertelen volt." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/it.json b/imports/plugins/core/dashboard/server/i18n/it.json index 22617f34de1..41cdb53e032 100644 --- a/imports/plugins/core/dashboard/server/i18n/it.json +++ b/imports/plugins/core/dashboard/server/i18n/it.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Impostazioni" }, "settings": { - "shopSettingsLabel": "Negozio" + "shopSettingsLabel": "Negozio", + "import": "Importazione", + "general": { + "label": "Generico" + }, + "address": { + "label": "Indirizzo" + }, + "options": { + "label": "Opzioni" + }, + "openexchangerates": { + "refreshPeriod": "Rinfrescare" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Negozio impostazioni generali salvate.", + "shopGeneralSettingsFailed": "Negozio aggiornamento impostazioni generali non è riuscito.", + "shopAddressSettingsSaved": "impostazioni di indirizzo del negozio salvate.", + "shopAddressSettingsFailed": "Negozio aggiornamento impostazioni dell'indirizzo non è riuscito.", + "shopExternalServicesSettingsSaved": "Negozio impostazioni dei servizi esterni salvate.", + "shopExternalServicesSettingsFailed": "Negozio aggiornamento impostazioni dei servizi esterni non è riuscita.", + "shopOptionsSettingsSaved": "opzioni negozio salvate.", + "shopOptionsSettingsFailed": "aggiornamento opzioni negozio non è riuscito." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/my.json b/imports/plugins/core/dashboard/server/i18n/my.json index 9a4dabd2f9e..e016f1dc94f 100644 --- a/imports/plugins/core/dashboard/server/i18n/my.json +++ b/imports/plugins/core/dashboard/server/i18n/my.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Settings များ" }, "settings": { - "shopSettingsLabel": "ဆိုင်" + "shopSettingsLabel": "ဆိုင်", + "import": "တင်သွင်း", + "general": { + "label": "ယေဘုယျ" + }, + "address": { + "label": "လိပ်စာ" + }, + "options": { + "label": "Options ကို" + }, + "openexchangerates": { + "refreshPeriod": "အားဖြည့်" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "ကယ်တင်ခြင်းသို့ရောက်သောယေဘုယျ setting များကိုစျေးဝယ်။", + "shopGeneralSettingsFailed": "update ကိုပျက်ကွက်ယေဘုယျ setting များကိုစျေးဝယ်။", + "shopAddressSettingsSaved": "ဆိုင်လိပ်စာ settings ကိုကယ်လွှတ်တော်မူ၏။", + "shopAddressSettingsFailed": "ဆိုင်လိပ်စာ setting များကို update ကိုပျက်ကွက်ခဲ့သည်။", + "shopExternalServicesSettingsSaved": "setting များကိုကယ်တင်ခြင်းသို့ရောက်ရ၏ပြင်ပဝန်ဆောင်မှုများကိုစျေးဝယ်။", + "shopExternalServicesSettingsFailed": "update ကိုပျက်ကွက်ပြင်ပဝန်ဆောင်မှုများကို setting များကိုစျေးဝယ်။", + "shopOptionsSettingsSaved": "ဆိုင်ရွေးချယ်စရာကယ်တင်ခြင်းသို့ရောက်ရ၏။", + "shopOptionsSettingsFailed": "ဆိုင်ရွေးချယ်စရာ update ကိုပျက်ကွက်ခဲ့သည်။" } } } diff --git a/imports/plugins/core/dashboard/server/i18n/nb.json b/imports/plugins/core/dashboard/server/i18n/nb.json index 2d7fdb5df5f..cb3cbd38cb5 100644 --- a/imports/plugins/core/dashboard/server/i18n/nb.json +++ b/imports/plugins/core/dashboard/server/i18n/nb.json @@ -1,5 +1,18 @@ [{ "i18n": "nb", "ns": "reaction-dashboard", - "translation": { } + "translation": { + "reaction-dashboard": { + "admin": { + "settings": { + "address": { + "label": "Adresselinje2" + }, + "options": { + "label": "Innstillinger" + } + } + } + } + } }] diff --git a/imports/plugins/core/dashboard/server/i18n/nl.json b/imports/plugins/core/dashboard/server/i18n/nl.json index cd8133dcfa1..b4ad57018c2 100644 --- a/imports/plugins/core/dashboard/server/i18n/nl.json +++ b/imports/plugins/core/dashboard/server/i18n/nl.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Instellingen" }, "settings": { - "shopSettingsLabel": "Winkel" + "shopSettingsLabel": "Winkel", + "import": "Import", + "general": { + "label": "Algemeen" + }, + "address": { + "label": "Addresregel 2" + }, + "options": { + "label": "opties" + }, + "openexchangerates": { + "refreshPeriod": "Vernieuwen" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Shop algemene instellingen opgeslagen.", + "shopGeneralSettingsFailed": "Shop-update algemene instellingen is mislukt.", + "shopAddressSettingsSaved": "Shop-adres instellingen opgeslagen.", + "shopAddressSettingsFailed": "Shop-update-adres instellingen is mislukt.", + "shopExternalServicesSettingsSaved": "Shop buitendiensten instellingen opgeslagen.", + "shopExternalServicesSettingsFailed": "Shop-update buitendiensten instellingen is mislukt.", + "shopOptionsSettingsSaved": "Shop opties opgeslagen.", + "shopOptionsSettingsFailed": "Shop opties update is mislukt." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/pl.json b/imports/plugins/core/dashboard/server/i18n/pl.json index 81dc8865999..07300a7b985 100644 --- a/imports/plugins/core/dashboard/server/i18n/pl.json +++ b/imports/plugins/core/dashboard/server/i18n/pl.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Ustawienia" }, "settings": { - "shopSettingsLabel": "Sklep" + "shopSettingsLabel": "Sklep", + "import": "Import", + "general": { + "label": "Generał" + }, + "address": { + "label": "Adres" + }, + "options": { + "label": "Opcje" + }, + "openexchangerates": { + "refreshPeriod": "Odśwież" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Sklep ogólne ustawienia zapisane.", + "shopGeneralSettingsFailed": "Sklep ustawienia ogólne aktualizacja nie powiodła się.", + "shopAddressSettingsSaved": "Ustawienia adresu Shop zapisane.", + "shopAddressSettingsFailed": "Sklep ustawienia adresu aktualizacja nie powiodła się.", + "shopExternalServicesSettingsSaved": "Sklep ustawienia usługi zewnętrzne zapisane.", + "shopExternalServicesSettingsFailed": "Sklep z ustawieniami usługi zewnętrzne aktualizacji nie powiodło się.", + "shopOptionsSettingsSaved": "Opcje sklepowe zapisane.", + "shopOptionsSettingsFailed": "Opcje sklepowe aktualizacja nie powiodła się." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/pt.json b/imports/plugins/core/dashboard/server/i18n/pt.json index 5df58e72d28..0d0c6bebe53 100644 --- a/imports/plugins/core/dashboard/server/i18n/pt.json +++ b/imports/plugins/core/dashboard/server/i18n/pt.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Definições" }, "settings": { - "shopSettingsLabel": "Loja" + "shopSettingsLabel": "Loja", + "import": "Importar", + "general": { + "label": "Geral" + }, + "address": { + "label": "Endereço" + }, + "options": { + "label": "Opções" + }, + "openexchangerates": { + "refreshPeriod": "Atualizar" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Definições gerais da loja guardadas.", + "shopGeneralSettingsFailed": "Falha ao atualizar as definições gerais da loja.", + "shopAddressSettingsSaved": "Definições do endereço da loja guardadas.", + "shopAddressSettingsFailed": "Falha ao atualizar as definições do endereço da loja.", + "shopExternalServicesSettingsSaved": "Definições dos serviços externos da loja guardadas.", + "shopExternalServicesSettingsFailed": "Falha ao atualizar as definições dos serviços externos da loja.", + "shopOptionsSettingsSaved": "Opções da loja guardadas.", + "shopOptionsSettingsFailed": "Falha ao atualizar as opções da loja." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/ro.json b/imports/plugins/core/dashboard/server/i18n/ro.json index b2297c91ad0..e280836e668 100644 --- a/imports/plugins/core/dashboard/server/i18n/ro.json +++ b/imports/plugins/core/dashboard/server/i18n/ro.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Setări" }, "settings": { - "shopSettingsLabel": "Magazin" + "shopSettingsLabel": "Magazin", + "import": "Import", + "general": { + "label": "General" + }, + "address": { + "label": "continuare Adresă" + }, + "options": { + "label": "Opțiuni" + }, + "openexchangerates": { + "refreshPeriod": "Reîmprospăta" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Setările generale ale magazinului au fost salvate.", + "shopGeneralSettingsFailed": "Actualizarea setărilor generale ale magazinului a eșuat.", + "shopAddressSettingsSaved": "Setările adresei magazinului au fost salvate.", + "shopAddressSettingsFailed": "Actualizarea setării adresei magazinului eșuat.", + "shopExternalServicesSettingsSaved": "Setările serviciilor externe ale magazinului au fost salvate.", + "shopExternalServicesSettingsFailed": "Setările serviciilor externe ale magazinului au eșuat.", + "shopOptionsSettingsSaved": "Opțiunile magazinului au fost salvate.", + "shopOptionsSettingsFailed": "Actualizarea opțiunilor magazinului au eșuat." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/ru.json b/imports/plugins/core/dashboard/server/i18n/ru.json index 163476e6b3b..f114cf725ae 100644 --- a/imports/plugins/core/dashboard/server/i18n/ru.json +++ b/imports/plugins/core/dashboard/server/i18n/ru.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Настройки" }, "settings": { - "shopSettingsLabel": "Магазин" + "shopSettingsLabel": "Магазин", + "import": "Импорт", + "general": { + "label": "Основные" + }, + "address": { + "label": "Адрес (доп.)" + }, + "options": { + "label": "Настройки" + }, + "openexchangerates": { + "refreshPeriod": "Обновление" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Настройки магазина обновлены.", + "shopGeneralSettingsFailed": "Не удалось изменить основные настройки магазина. ", + "shopAddressSettingsSaved": "Адрес магазина изменён.", + "shopAddressSettingsFailed": "Не удалось изменить адрес магазина. ", + "shopExternalServicesSettingsSaved": "Настройки внешних сервисов обновлены.", + "shopExternalServicesSettingsFailed": "Не удалось изменить настройки внешних сервисов. ", + "shopOptionsSettingsSaved": "Настройка магазина обновлена.", + "shopOptionsSettingsFailed": "Не удалось изменить настройку. " } } } diff --git a/imports/plugins/core/dashboard/server/i18n/sl.json b/imports/plugins/core/dashboard/server/i18n/sl.json index e61b196cd7e..caf43ab549e 100644 --- a/imports/plugins/core/dashboard/server/i18n/sl.json +++ b/imports/plugins/core/dashboard/server/i18n/sl.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Nastavitve" }, "settings": { - "shopSettingsLabel": "trgovina" + "shopSettingsLabel": "trgovina", + "import": "Uvoz", + "general": { + "label": "Splošno" + }, + "address": { + "label": "naslov" + }, + "options": { + "label": "Opcije" + }, + "openexchangerates": { + "refreshPeriod": "Osveži" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Shop splošne nastavitve shranjene.", + "shopGeneralSettingsFailed": "Trgovina splošne nastavitve posodobitev ni uspela.", + "shopAddressSettingsSaved": "Nastavitve Shop naslov shranjene.", + "shopAddressSettingsFailed": "Trgovina nastavitve naslov posodobitev ni uspela.", + "shopExternalServicesSettingsSaved": "Shop zunanje nastavitve storitev shranjene.", + "shopExternalServicesSettingsFailed": "Shop posodobitev nastavitev zunanjih storitev ni uspelo.", + "shopOptionsSettingsSaved": "Možnosti Trgovina shranjene.", + "shopOptionsSettingsFailed": "Možnosti Shop posodobitev ni uspela." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/sv.json b/imports/plugins/core/dashboard/server/i18n/sv.json index 2fd98217643..7cb19b8204d 100644 --- a/imports/plugins/core/dashboard/server/i18n/sv.json +++ b/imports/plugins/core/dashboard/server/i18n/sv.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Inställningar" }, "settings": { - "shopSettingsLabel": "Handla" + "shopSettingsLabel": "Handla", + "import": "Import", + "general": { + "label": "Allmänt" + }, + "address": { + "label": "Adress" + }, + "options": { + "label": "Val" + }, + "openexchangerates": { + "refreshPeriod": "Uppdatera" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Handla allmänna inställningar sparas.", + "shopGeneralSettingsFailed": "Shop allmänna inställningar uppdatering misslyckades.", + "shopAddressSettingsSaved": "Shop adressinställningar sparas.", + "shopAddressSettingsFailed": "Shop adressinställningar uppdatering misslyckades.", + "shopExternalServicesSettingsSaved": "Handla inställningar externa tjänster som sparats.", + "shopExternalServicesSettingsFailed": "Handla inställningar externa tjänster uppdatering misslyckades.", + "shopOptionsSettingsSaved": "Shop alternativ sparas.", + "shopOptionsSettingsFailed": "Shop alternativ uppdatering misslyckades." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/tr.json b/imports/plugins/core/dashboard/server/i18n/tr.json index bac8f299380..37612a49fba 100644 --- a/imports/plugins/core/dashboard/server/i18n/tr.json +++ b/imports/plugins/core/dashboard/server/i18n/tr.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Ayarlar" }, "settings": { - "shopSettingsLabel": "Dükkan" + "shopSettingsLabel": "Dükkan", + "import": "Ithalat", + "general": { + "label": "Genel" + }, + "address": { + "label": "Adres 2" + }, + "options": { + "label": "Seçenekler" + }, + "openexchangerates": { + "refreshPeriod": "Yenile" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Kaydedilen genel ayarları alışveriş.", + "shopGeneralSettingsFailed": "Mağaza genel ayarlar güncelleme başarısız oldu.", + "shopAddressSettingsSaved": "Mağaza adres ayarları kaydedildi.", + "shopAddressSettingsFailed": "Mağaza adres ayarları güncellemesi başarısız oldu.", + "shopExternalServicesSettingsSaved": "Kaydedilen dış hizmetler ayarlarını alışveriş.", + "shopExternalServicesSettingsFailed": "dış hizmetler ayarları güncelleştirme alışveriş başarısız oldu.", + "shopOptionsSettingsSaved": "Mağaza seçenekleri kaydedildi.", + "shopOptionsSettingsFailed": "Mağaza seçenekleri güncelleme başarısız oldu." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/vi.json b/imports/plugins/core/dashboard/server/i18n/vi.json index 822f55b478f..08da2b902d0 100644 --- a/imports/plugins/core/dashboard/server/i18n/vi.json +++ b/imports/plugins/core/dashboard/server/i18n/vi.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "Cài đặt" }, "settings": { - "shopSettingsLabel": "cửa tiệm" + "shopSettingsLabel": "cửa tiệm", + "import": "nhập", + "general": { + "label": "Chung" + }, + "address": { + "label": "Địa chỉ nhà" + }, + "options": { + "label": "Tùy chọn" + }, + "openexchangerates": { + "refreshPeriod": "Làm tươi" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "Mua sắm thiết lập chung lưu.", + "shopGeneralSettingsFailed": "Cửa hàng thiết lập chung cập nhật thất bại.", + "shopAddressSettingsSaved": "thiết lập địa chỉ cửa hàng lưu.", + "shopAddressSettingsFailed": "Cửa hàng thiết lập địa chỉ cập nhật thất bại.", + "shopExternalServicesSettingsSaved": "Mua sắm các thiết lập dịch vụ bên ngoài lưu.", + "shopExternalServicesSettingsFailed": "Mua sắm các thiết lập dịch vụ bên ngoài cập nhật thất bại.", + "shopOptionsSettingsSaved": "Cửa hàng tùy chọn lưu.", + "shopOptionsSettingsFailed": "Cửa hàng tùy chọn cập nhật thất bại." } } } diff --git a/imports/plugins/core/dashboard/server/i18n/zh.json b/imports/plugins/core/dashboard/server/i18n/zh.json index 8be9d0f7fa0..a91d7197877 100644 --- a/imports/plugins/core/dashboard/server/i18n/zh.json +++ b/imports/plugins/core/dashboard/server/i18n/zh.json @@ -12,7 +12,30 @@ "packageGroupSettingsLabel": "设置" }, "settings": { - "shopSettingsLabel": "店" + "shopSettingsLabel": "店", + "import": "导入", + "general": { + "label": "通用" + }, + "address": { + "label": "地址" + }, + "options": { + "label": "选项" + }, + "openexchangerates": { + "refreshPeriod": "刷新" + } + }, + "alerts": { + "shopGeneralSettingsSaved": "商店常规设置已保存。", + "shopGeneralSettingsFailed": "商店常规设置更新失败。", + "shopAddressSettingsSaved": "商店地址设置已保存。", + "shopAddressSettingsFailed": "商店地址设置更新失败。", + "shopExternalServicesSettingsSaved": "商店外部服务设置已保存。", + "shopExternalServicesSettingsFailed": "商店外部服务设置更新失败。", + "shopOptionsSettingsSaved": "商店选项已保存。", + "shopOptionsSettingsFailed": "商店选项更新失败。" } } } diff --git a/imports/plugins/core/email/client/components/emailConfig.js b/imports/plugins/core/email/client/components/emailConfig.js index 0d73f4db0c7..f4644eee2c1 100644 --- a/imports/plugins/core/email/client/components/emailConfig.js +++ b/imports/plugins/core/email/client/components/emailConfig.js @@ -43,24 +43,24 @@ class EmailConfig extends Component {
- Status: {status ? + : {status ? : }
- Service: {service || } + : {service || }
- Host: {host || } + : {host || }
- Port: {port || } + : {port || }
- User: {user || } + : {user || }
- Password:   + :   {password ? {showPassword ? password : "********"} diff --git a/imports/plugins/core/email/client/components/emailSettings.js b/imports/plugins/core/email/client/components/emailSettings.js index 6b022b2a461..233d2af5560 100644 --- a/imports/plugins/core/email/client/components/emailSettings.js +++ b/imports/plugins/core/email/client/components/emailSettings.js @@ -52,7 +52,7 @@ class EmailSettings extends Component { label="Service" i18nKeyLabel="admin.settings.providerName" placeholder="Select a Service" - i18nKeyPlaceholder="mail.settings.selectService" + i18nKeyPlaceholder="admin.settings.selectService" name="service" onChange={this.handleSelect} options={emailProviders} @@ -62,7 +62,7 @@ class EmailSettings extends Component {
{ "|" } - ); - } -} - -export default CartDrawer; diff --git a/imports/plugins/core/layout/client/components/content.js b/imports/plugins/core/layout/client/components/content.js deleted file mode 100644 index e7f5380d5e2..00000000000 --- a/imports/plugins/core/layout/client/components/content.js +++ /dev/null @@ -1,18 +0,0 @@ -import React, { Component, PropTypes } from "react"; -import Blaze from "meteor/gadicc:blaze-react-component"; - -class Content extends Component { - static propTypes = { - template: PropTypes.string - } - - render() { - return ( -
- -
- ); - } -} - -export default Content; diff --git a/imports/plugins/core/layout/client/components/coreLayout.js b/imports/plugins/core/layout/client/components/coreLayout.js index 2e0183bc06a..b6dd00292bb 100644 --- a/imports/plugins/core/layout/client/components/coreLayout.js +++ b/imports/plugins/core/layout/client/components/coreLayout.js @@ -1,10 +1,8 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; import classnames from "classnames"; -import Header from "./header"; -import CartDrawer from "./cartDrawer"; -import { Content } from "./"; - +import Blaze from "meteor/gadicc:blaze-react-component"; +import { Template } from "meteor/templating"; class CoreLayout extends Component { static propTypes = { @@ -14,6 +12,7 @@ class CoreLayout extends Component { } render() { + const { layoutHeader, layoutFooter, template } = this.props.structure || {}; const pageClassName = classnames({ "page": true, "show-settings": this.props.actionViewIsOpen @@ -21,9 +20,21 @@ class CoreLayout extends Component { return (
-
- - + { Template[layoutHeader] && + + } + + + + { Template[template] && +
+ +
+ } + + { Template[layoutFooter] && + + }
); } diff --git a/imports/plugins/core/layout/client/components/header.js b/imports/plugins/core/layout/client/components/header.js deleted file mode 100644 index e403c295ced..00000000000 --- a/imports/plugins/core/layout/client/components/header.js +++ /dev/null @@ -1,20 +0,0 @@ -import React, { Component, PropTypes } from "react"; -import Blaze from "meteor/gadicc:blaze-react-component"; - -class Header extends Component { - static propTypes = { - template: PropTypes.string - } - - render() { - if (this.props.template) { - return ( - - ); - } - - return null; - } -} - -export default Header; diff --git a/imports/plugins/core/layout/client/components/index.js b/imports/plugins/core/layout/client/components/index.js index 4034d62ff06..422c76c1bfc 100644 --- a/imports/plugins/core/layout/client/components/index.js +++ b/imports/plugins/core/layout/client/components/index.js @@ -1,6 +1,7 @@ export { default as CoreLayout } from "./coreLayout"; export { default as QuickMemu } from "./quickMenu"; export { default as Header } from "./header"; +export { default as Footer } from "./footer"; export { default as CartDrawer } from "./cartDrawer"; export { default as Content } from "./content"; export { default as PrintLayout } from "./printLayout"; diff --git a/imports/plugins/core/layout/client/templates/layout/alerts/alerts.js b/imports/plugins/core/layout/client/templates/layout/alerts/alerts.js index 6ee6766af14..c4bc8636b31 100644 --- a/imports/plugins/core/layout/client/templates/layout/alerts/alerts.js +++ b/imports/plugins/core/layout/client/templates/layout/alerts/alerts.js @@ -1,3 +1,6 @@ +import { Meteor } from "meteor/meteor"; +import Alerts from "./inlineAlerts"; + /** * inlineAlert helpers */ diff --git a/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts.js b/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts.js index f24ab78a4d2..eddf2f17556 100644 --- a/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts.js +++ b/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts.js @@ -4,7 +4,7 @@ import { Mongo } from "meteor/mongo"; /* * Forked and modifed from https://github.com/asktomsk/bootstrap-alerts/ */ -Alerts = { +const Alerts = { /* Default options. Can be overridden for application @@ -144,4 +144,5 @@ Alerts = { collection_: new Mongo.Collection(null) }; +window.Alerts = Alerts; export default Alerts; diff --git a/imports/plugins/core/layout/client/templates/layout/alerts/reactionAlerts.js b/imports/plugins/core/layout/client/templates/layout/alerts/reactionAlerts.js index 4dc16711ebb..069b8b9ee90 100644 --- a/imports/plugins/core/layout/client/templates/layout/alerts/reactionAlerts.js +++ b/imports/plugins/core/layout/client/templates/layout/alerts/reactionAlerts.js @@ -1,7 +1,8 @@ import _ from "lodash"; -import { Meteor } from "meteor/meteor"; import swal from "sweetalert2"; +import { Meteor } from "meteor/meteor"; import "sweetalert2/dist/sweetalert2.css"; +import Alerts from "./inlineAlerts"; // Extends Bootstaps alerts and add more alert types Meteor.startup(function () { diff --git a/imports/plugins/core/orders/client/__tests__/components/__snapshots__/orderSummary.spec.js.snap b/imports/plugins/core/orders/client/__tests__/components/__snapshots__/orderSummary.spec.js.snap new file mode 100644 index 00000000000..a56608cdb63 --- /dev/null +++ b/imports/plugins/core/orders/client/__tests__/components/__snapshots__/orderSummary.spec.js.snap @@ -0,0 +1,211 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`OrderSummary snapshot test 1`] = ` +
+
+ +
+
+
+
+
+ +
+
+ + Order ID + +
+ +
+
+
+ + Created + +
+ a few seconds ago + | +
+
+
+ + Processor + +
+
+
+ + Payment + +
+ ( + ) +
+
+
+ + Transaction + +
+
+
+ + Carrier + +
+ - +
+
+
+ + Tracking + +
+
+
+ + Labels + + + + Print Customs + + +
+
+
+
+
+ + Ship to + +
+ + Phone: + +
+
+
+ +
+ +
+ + , + , + + +
+
+`; diff --git a/imports/plugins/core/orders/client/__tests__/components/orderSummary.spec.js b/imports/plugins/core/orders/client/__tests__/components/orderSummary.spec.js new file mode 100644 index 00000000000..794adbbf25b --- /dev/null +++ b/imports/plugins/core/orders/client/__tests__/components/orderSummary.spec.js @@ -0,0 +1,57 @@ +jest.mock("/imports/plugins/core/ui/client/components", () => { + return { + Badge() { return null; }, + ClickToCopy() { return null; } + }; +}); + +import React from "react"; +import OrderSummary from "../../components/orderSummary"; +import { shallow } from "enzyme"; +import shallowToJSON from "enzyme-to-json"; + +/** + * Order Summary is a display only component + * It receives props and displays them accordingly + */ + +afterEach(() => { + jest.clearAllMocks(); +}); + +/** + * Snapshots make sure your UI does not change unexpectedly + */ + +test("OrderSummary snapshot test", () => { + // Initializing all the props passed into order summary component + const dateFormat = jest.fn(); + const tracking = jest.fn(); + const shipmentStatus = jest.fn(()=>({})); + const printableLabels = jest.fn(()=>({})); + const profileShippingAddress = {}; + const order = { + shipping: [{ shipmentMethod: {} }], + workflow: { + status: "new" + }, + billing: [ + { paymentMethod: {}, + invoice: {} + } + ] + }; + + const component = shallow( + + ); + const tree = shallowToJSON(component); + expect(tree).toMatchSnapshot(); +}); diff --git a/imports/plugins/core/orders/client/components/invoiceActions.js b/imports/plugins/core/orders/client/components/invoiceActions.js new file mode 100644 index 00000000000..ce6dc2300cf --- /dev/null +++ b/imports/plugins/core/orders/client/components/invoiceActions.js @@ -0,0 +1,89 @@ +import React, { Component, PropTypes } from "react"; +import { formatPriceString } from "/client/api"; +import { IconButton, NumericInput, Translation } from "/imports/plugins/core/ui/client/components"; + +class InvoiceActions extends Component { + + static propTypes = { + adjustedTotal: PropTypes.number, + handleActionViewBack: PropTypes.func, + invoice: PropTypes.object, + isAdjusted: PropTypes.func + } + + renderCapturedTotal() { + const { invoice } = this.props; + + return ( +
+ + + + +
+ {formatPriceString(invoice.total)} +
+
+ ); + } + + renderAdjustedTotal() { + const { adjustedTotal } = this.props; + + return ( +
+ + + + +
+ {formatPriceString(adjustedTotal)} +
+
+ ); + } + renderRefundForm() { + const { adjustedTotal } = this.props; + + return ( +
+ + + + +
+ + + + + + -> + +
+
+ ); + } + + render() { + const { isAdjusted } = this.props; + + return ( +
+ {this.renderCapturedTotal()} + {isAdjusted() && this.renderAdjustedTotal()} + {/* {this.renderRefundForm()} */} +
+ ); + } +} + +export default InvoiceActions; diff --git a/imports/plugins/core/orders/client/components/orderSummary.js b/imports/plugins/core/orders/client/components/orderSummary.js index 18453b6e149..12f0e82b4e5 100644 --- a/imports/plugins/core/orders/client/components/orderSummary.js +++ b/imports/plugins/core/orders/client/components/orderSummary.js @@ -1,4 +1,6 @@ import React, { Component, PropTypes } from "react"; +import moment from "moment"; +import { Badge, ClickToCopy } from "/imports/plugins/core/ui/client/components"; class OrderSummary extends Component { static propTypes = { @@ -10,28 +12,73 @@ class OrderSummary extends Component { tracking: PropTypes.func } + badgeStatus() { + const orderStatus = this.props.order.workflow.status; + + if (orderStatus === "new") { + return "info"; + } else if (orderStatus === "coreOrderWorkflow/processing") { + return "success"; + } else if (orderStatus === "coreOrderWorkflow/canceled") { + return "danger"; + } else if (orderStatus === "coreOrderWorkflow/completed") { + return "primary"; + } + + return "default"; + } + + orderLink() { + const orderId = this.props.order._id; + return orderId; + } + + truncateId() { + const orderId = this.props.order._id; + const shortId = orderId.slice(-5); + + return shortId; + } + render() { - const { dateFormat, tracking, order, shipmentStatus, profileShippingAddress, printableLabels } = this.props; + const { dateFormat, tracking, order, profileShippingAddress, printableLabels } = this.props; return (
- {profileShippingAddress.fullName} , {profileShippingAddress.country} -
- ID {order._id} + {profileShippingAddress.fullName} +
+ {order.email}
- {shipmentStatus().label} + +
+ +
+ Order ID +
+ +
Created
- {dateFormat(order.createdAt, "MM/D/YYYY")} + {moment(order.createdAt).fromNow()} | {dateFormat(order.createdAt, "MM/D/YYYY")}
diff --git a/imports/plugins/core/orders/client/components/ordersList.js b/imports/plugins/core/orders/client/components/ordersList.js new file mode 100644 index 00000000000..3827893d5a3 --- /dev/null +++ b/imports/plugins/core/orders/client/components/ordersList.js @@ -0,0 +1,184 @@ +import React, { Component, PropTypes } from "react"; +import classnames from "classnames/dedupe"; +import Avatar from "react-avatar"; +import moment from "moment"; +import { formatPriceString } from "/client/api"; +import { Badge, ClickToCopy, Icon, Translation } from "@reactioncommerce/reaction-ui"; +import ProductImage from "./productImage"; + +class OrdersList extends Component { + + static propTypes = { + displayMedia: PropTypes.func, + handleClick: PropTypes.func, + orders: PropTypes.array + } + + /** + * Fullfilment Badge + * @param {Object} order object containing info for order and coreOrderWorkflow + * @return {string} A string containing the type of Badge + */ + fulfillmentBadgeStatus(order) { + const orderStatus = order.workflow.status; + + if (orderStatus === "new") { + return "info"; + } else if (orderStatus === "coreOrderWorkflow/processing") { + return "success"; + } else if (orderStatus === "coreOrderWorkflow/canceled") { + return "danger"; + } else if (orderStatus === "coreOrderWorkflow/completed") { + return "primary"; + } + + return "default"; + } + + /** + * Shipping Badge + * TODO: any logic here, we don't have shipping status changes at the moment + * @param {Object} order object containing info for order and coreOrderWorkflow + * @return {string} A string containing the type of Badge + */ + shippingBadgeStatus() { + return "basic"; + } + + renderOrderButton(order) { + const classes = classnames({ + "rui": true, + "btn": true, + "btn-success": order.workflow.status === "new" + }); + + return ( + + ); + } + + renderOrderInfo(order) { + const { displayMedia } = this.props; + + return ( +
+
+ + Date: + {moment(order.createdAt).fromNow()} | {moment(order.createdAt).format("MM/D/YYYY")} + + + + Order ID: + + + + + Total: {formatPriceString(order.billing[0].invoice.total)} + +
+ +
+ {order.items.map((item, i) => { + return ( +
+
+ +
+
+ ); + })} +
+
+ ); + } + + renderShipmentInfo(order) { + const emailAddress = order.email || ; + return ( +
+
+ + {order.shipping[0].address.fullName} | {emailAddress} +
+
+ + +
+
+ ); + } + + + renderOrderCard(order) { + const { handleClick } = this.props; + + return ( +
+
handleClick(order, false)}> + {this.renderShipmentInfo(order)} + {this.renderOrderInfo(order)} +
+
handleClick(order)}> + {this.renderOrderButton(order)} +
+
+ ); + } + + + render() { + const { orders } = this.props; + + if (orders.length) { + return ( +
+ {orders.map((order, i) => { + return ( +
+ {this.renderOrderCard(order)} +
+ ); + })} +
+ ); + } + + return ( +
+
+ + +
+
+ ); + } +} + +export default OrdersList; diff --git a/imports/plugins/core/orders/client/components/productImage.js b/imports/plugins/core/orders/client/components/productImage.js new file mode 100644 index 00000000000..c530f39caf5 --- /dev/null +++ b/imports/plugins/core/orders/client/components/productImage.js @@ -0,0 +1,60 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Badge } from "/imports/plugins/core/ui/client/components"; + + +class ProductImage extends Component { + static propTypes = { + badge: PropTypes.bool, + displayMedia: PropTypes.func, + item: PropTypes.object, + size: PropTypes.string + } + + renderBadge() { + const { badge, item } = this.props; + + if (badge === true) { + return ( + + ); + } + return false; + } + + renderMedia() { + const { displayMedia, item, size } = this.props; + let mediaUrl; + + if (displayMedia(item)) { + mediaUrl = displayMedia(item).url(); + } else { + mediaUrl = "/resources/placeholder.gif"; + } + + return ( +
+ {item.title} + {this.renderBadge()} +
+ ); + } + + render() { + return ( +
+ {this.renderMedia()} +
+ ); + } +} + +export default ProductImage; diff --git a/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js b/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js new file mode 100644 index 00000000000..9a6e24936c8 --- /dev/null +++ b/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js @@ -0,0 +1,51 @@ +import React, { Component, PropTypes } from "react"; +import { composeWithTracker } from "/lib/api/compose"; +import InvoiceActions from "../components/invoiceActions"; +import { Loading } from "/imports/plugins/core/ui/client/components"; + +class InvoiceActionsContainer extends Component { + + static propTypes = { + adjustedTotal: PropTypes.number, + invoice: PropTypes.object, + paymentCaptured: PropTypes.bool + } + + constructor(props) { + super(props); + this.isAdjusted = this.isAdjusted.bind(this); + } + + isAdjusted = () => { + const { adjustedTotal, invoice } = this.props; + + if (invoice.total === adjustedTotal) { + return false; + } + return true; + } + + render() { + const { paymentCaptured, adjustedTotal, invoice } = this.props; + return ( +
+ +
+ ); + } +} + +const composer = (props, onData) => { + onData(null, { + paymentCaptured: props.paymentCaptured, + adjustedTotal: props.adjustedTotal, + invoice: props.invoice + }); +}; + +export default composeWithTracker(composer, Loading)(InvoiceActionsContainer); diff --git a/imports/plugins/core/orders/client/containers/orderSummaryContainer.js b/imports/plugins/core/orders/client/containers/orderSummaryContainer.js index 539240a8e4c..fad8ced9149 100644 --- a/imports/plugins/core/orders/client/containers/orderSummaryContainer.js +++ b/imports/plugins/core/orders/client/containers/orderSummaryContainer.js @@ -4,6 +4,7 @@ import _ from "lodash"; import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "/lib/api/compose"; import { Orders } from "/lib/collections"; +import { Card, CardHeader, CardBody, CardGroup, Loading } from "/imports/plugins/core/ui/client/components"; import { i18next } from "/client/api"; import OrderSummary from "../components/orderSummary"; @@ -103,15 +104,26 @@ class OrderSummaryContainer extends Component { render() { return ( -
- -
+ + + + + + + + ); } } @@ -142,4 +154,4 @@ const composer = (props, onData) => { } }; -export default composeWithTracker(composer, null)(OrderSummaryContainer); +export default composeWithTracker(composer, Loading)(OrderSummaryContainer); diff --git a/imports/plugins/core/orders/client/containers/ordersListContainer.js b/imports/plugins/core/orders/client/containers/ordersListContainer.js new file mode 100644 index 00000000000..060892e5cf8 --- /dev/null +++ b/imports/plugins/core/orders/client/containers/ordersListContainer.js @@ -0,0 +1,101 @@ +import React, { Component, PropTypes } from "react"; +import { Meteor } from "meteor/meteor"; +import { composeWithTracker } from "/lib/api/compose"; +import { Media } from "/lib/collections"; +import { Reaction } from "/client/api"; +import { Loading } from "/imports/plugins/core/ui/client/components"; +import OrdersList from "../components/ordersList.js"; +import { + PACKAGE_NAME, + ORDER_LIST_FILTERS_PREFERENCE_NAME, + ORDER_LIST_SELECTED_ORDER_PREFERENCE_NAME +} from "../../lib/constants"; + + +class OrdersListContainer extends Component { + static propTypes = { + invoice: PropTypes.object, + orders: PropTypes.array, + uniqueItems: PropTypes.array + } + + constructor(props) { + super(props); + + this.handleClick = this.handleClick.bind(this); + this.handleDisplayMedia = this.handleDisplayMedia.bind(this); + } + + handleClick = (order, startWorkflow = true) => { + Reaction.setActionViewDetail({ + label: "Order Details", + i18nKeyLabel: "orderWorkflow.orderDetails", + data: { + order: order + }, + props: { + size: "large" + }, + template: "coreOrderWorkflow" + }); + + if (startWorkflow === true) { + Meteor.call("workflow/pushOrderWorkflow", "coreOrderWorkflow", "processing", order); + Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_FILTERS_PREFERENCE_NAME, "processing"); + Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_SELECTED_ORDER_PREFERENCE_NAME, order._id); + } + } + + /** + * Media - find media based on a product/variant + * @param {Object} item object containing a product and variant id + * @return {Object|false} An object contianing the media or false + */ + handleDisplayMedia = (item) => { + const variantId = item.variants._id; + const productId = item.productId; + + const variantImage = Media.findOne({ + "metadata.variantId": variantId, + "metadata.productId": productId + }); + + if (variantImage) { + return variantImage; + } + + const defaultImage = Media.findOne({ + "metadata.productId": productId, + "metadata.priority": 0 + }); + + if (defaultImage) { + return defaultImage; + } + return false; + } + + render() { + const { orders } = this.props; + + return ( + + ); + } +} + +const composer = (props, onData) => { + const subscription = Meteor.subscribe("Media"); + if (subscription.ready()) { + onData(null, { + uniqueItems: props.items, + invoice: props.invoice + }); + } +}; + +export default composeWithTracker(composer, Loading)(OrdersListContainer); diff --git a/imports/plugins/core/orders/client/index.js b/imports/plugins/core/orders/client/index.js index 751646472ba..f222067f292 100644 --- a/imports/plugins/core/orders/client/index.js +++ b/imports/plugins/core/orders/client/index.js @@ -1,7 +1,5 @@ import { registerComponent } from "/imports/plugins/core/layout/lib/components"; -import "./templates/details/detail.html"; -import "./templates/details/detail.js"; import "./templates/list/items.html"; import "./templates/list/items.js"; @@ -17,10 +15,7 @@ import "./templates/orderPage/details.js"; import "./templates/orderPage/orderPage.html"; import "./templates/orderPage/orderPage.js"; -import "./templates/social/orderSocial.html"; -import "./templates/workflow/orderCompleted.html"; -import "./templates/workflow/orderSummary.html"; import "./templates/workflow/shippingInvoice.html"; import "./templates/workflow/shippingInvoice.js"; import "./templates/workflow/shippingSummary.html"; diff --git a/imports/plugins/core/orders/client/templates/details/detail.html b/imports/plugins/core/orders/client/templates/details/detail.html deleted file mode 100644 index cbabc087182..00000000000 --- a/imports/plugins/core/orders/client/templates/details/detail.html +++ /dev/null @@ -1,29 +0,0 @@ - diff --git a/imports/plugins/core/orders/client/templates/details/detail.js b/imports/plugins/core/orders/client/templates/details/detail.js deleted file mode 100644 index 939d03fcdd2..00000000000 --- a/imports/plugins/core/orders/client/templates/details/detail.js +++ /dev/null @@ -1,35 +0,0 @@ -import moment from "moment"; -import { Accounts } from "/lib/collections"; -import { Template } from "meteor/templating"; - -/** - * orderDetail helpers - * - * order state tracking, user profile helpers - * - * @returns {undefined} user profile details on orders - */ -Template.orderDetail.onCreated(function () { - this.subscribe("UserProfile", this.userId); -}); - -Template.orderDetail.helpers({ - userProfile: function () { - const instance = Template.instance(); - if (instance.subscriptionsReady()) { - if (typeof this.userId === "string") { - const userProfile = Accounts.findOne(this.userId); - if (!userProfile) { - return {}; - } - return userProfile.profile; - } - } - }, - orderAge: function () { - return moment(this.createdAt).fromNow(); - }, - shipmentTracking: function () { - return this.shipping.shipmentMethod.tracking; - } -}); diff --git a/imports/plugins/core/orders/client/templates/orders.html b/imports/plugins/core/orders/client/templates/orders.html index 243ce48a690..e291cef0cb1 100644 --- a/imports/plugins/core/orders/client/templates/orders.html +++ b/imports/plugins/core/orders/client/templates/orders.html @@ -1,126 +1,13 @@ - - - - - - - - diff --git a/imports/plugins/core/orders/client/templates/orders.js b/imports/plugins/core/orders/client/templates/orders.js index cb6978cf417..7417411c121 100644 --- a/imports/plugins/core/orders/client/templates/orders.js +++ b/imports/plugins/core/orders/client/templates/orders.js @@ -1,10 +1,9 @@ import _ from "lodash"; -import accounting from "accounting-js"; -import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; -import { Reaction, i18next } from "/client/api"; +import { Reaction } from "/client/api"; import { Orders, Shops } from "/lib/collections"; import OrdersActionContainer from "../containers/ordersActionContainer"; +import OrdersListContainer from "../containers/ordersListContainer"; import { PACKAGE_NAME, ORDER_LIST_FILTERS_PREFERENCE_NAME, @@ -135,6 +134,18 @@ Template.orders.helpers({ } }; }, + OrdersListComponent() { + const orderFilter = Reaction.getUserPreferences(PACKAGE_NAME, ORDER_LIST_FILTERS_PREFERENCE_NAME, DEFAULT_FILTER_NAME); + return { + component: OrdersListContainer, + limit: Template.instance().orderLimits.get(orderFilter), + orders: Template.instance().state.get("orders") || false, + onActionClick(filter) { + Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_FILTERS_PREFERENCE_NAME, filter.name); + Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_SELECTED_ORDER_PREFERENCE_NAME, null); + } + }; + }, itemProps(order) { return { order, @@ -192,175 +203,3 @@ Template.orders.events({ instance.orderLimits.set(filter, limit); } }); - -Template.ordersListItem.helpers({ - order() { - return Template.currentData().order; - }, - activeClassname(orderId) { - // const Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_FILTERS_PREFERENCE_NAME, filter.name) - const selectedOrderId = Reaction.getUserPreferences(PACKAGE_NAME, ORDER_LIST_SELECTED_ORDER_PREFERENCE_NAME); - - if (selectedOrderId === orderId) { - return "active"; - } - return ""; - }, - - orderIsNew(order) { - return order.workflow.status === "new"; - } -}); - -Template.ordersListItem.events({ - "click [data-event-action=selectOrder]": function (event) { - event.preventDefault(); - const instance = Template.instance(); - - // Set selected order in user preference - Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_SELECTED_ORDER_PREFERENCE_NAME, instance.data.order._id); - - // Show the action view - detail view - Reaction.setActionViewDetail({ - label: "Order Details", - i18nKeyLabel: "orderWorkflow.orderDetails", - data: { - order: instance.data.order - }, - props: { - size: "large" - }, - template: "coreOrderWorkflow" - }); - }, - "click [data-event-action=startProcessingOrder]": function (event) { - event.preventDefault(); - const instance = Template.instance(); - const isActionViewOpen = Reaction.isActionViewOpen(); - const { order } = instance.data; - - - if (order.workflow.status === "new") { - Meteor.call("workflow/pushOrderWorkflow", "coreOrderWorkflow", "processing", order); - - // send notification to order owner - const userId = order.userId; - const type = "orderAccepted"; - const prefix = Reaction.getShopPrefix(); - const url = `${prefix}/notifications`; - const sms = true; - Meteor.call("notification/send", userId, type, url, sms); - } - - Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_FILTERS_PREFERENCE_NAME, "processing"); - - // toggle detail views - if (isActionViewOpen === false) { - Reaction.showActionView({ - label: "Order Details", - i18nKeyLabel: "orderWorkflow.orderDetails", - data: { order }, - props: { - size: "large" - }, - template: "coreOrderWorkflow" - }); - } - } -}); - -/** - * orderStatusDetail - * - * order state tracking - * - * @returns orderStatusDetails - */ - -Template.orderStatusDetail.helpers({ - // helper to format currency - formatAmount(value) { - let amount = value || ""; - if (typeof value === "number") { - amount = accounting.toFixed(value, 2); - } - return amount; - }, - // order age helper - orderAge: function () { - return moment(this.createdAt).fromNow(); - }, - - shipmentMethod: function () { - return this.shipping[0].shipmentMethod; - }, - - shipmentTracking: function () { - if (this.shipping[0].tracking) { - return this.shipping[0].tracking; - } - return ""; - }, - - shipmentStatus() { - const self = this; - const shipment = this.shipping[0]; - - // check first if it was delivered - if (shipment.delivered) { - return { - delivered: true, - shipped: true, - status: "success", - label: i18next.t("orderShipping.delivered") - }; - } - - const shipped = _.every(shipment.items, (shipmentItem) => { - for (const fullItem of self.items) { - if (fullItem._id === shipmentItem._id) { - if (fullItem.workflow) { - if (_.isArray(fullItem.workflow.workflow)) { - return _.includes(fullItem.workflow.workflow, "coreOrderItemWorkflow/completed"); - } - } - } - } - }); - - const canceled = _.every(shipment.items, (shipmentItem) => { - for (const fullItem of self.items) { - if (fullItem._id === shipmentItem._id) { - if (fullItem.workflow) { - return fullItem.workflow.status === "coreOrderItemWorkflow/canceled"; - } - } - } - }); - - if (shipped) { - return { - delivered: false, - shipped: true, - status: "success", - label: i18next.t("orderShipping.shipped") - }; - } - - if (canceled) { - return { - delivered: false, - shipped: false, - status: "danger", - label: i18next.t("order.canceledLabel") - }; - } - - return { - delivered: false, - shipped: false, - status: "info", - label: i18next.t("orderShipping.notShipped") - }; - } -}); diff --git a/imports/plugins/core/orders/client/templates/social/orderSocial.html b/imports/plugins/core/orders/client/templates/social/orderSocial.html deleted file mode 100644 index bb6132fa572..00000000000 --- a/imports/plugins/core/orders/client/templates/social/orderSocial.html +++ /dev/null @@ -1,43 +0,0 @@ - diff --git a/imports/plugins/core/orders/client/templates/workflow/orderCompleted.html b/imports/plugins/core/orders/client/templates/workflow/orderCompleted.html deleted file mode 100644 index 034ad6df3aa..00000000000 --- a/imports/plugins/core/orders/client/templates/workflow/orderCompleted.html +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/imports/plugins/core/orders/client/templates/workflow/orderSummary.html b/imports/plugins/core/orders/client/templates/workflow/orderSummary.html deleted file mode 100644 index 9e8d2ae860c..00000000000 --- a/imports/plugins/core/orders/client/templates/workflow/orderSummary.html +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.html b/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.html index b5cef63b0b1..78b1f9f3957 100644 --- a/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.html +++ b/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.html @@ -1,104 +1,118 @@ diff --git a/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js b/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js index aec08e4ac94..649dfa24b6c 100644 --- a/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js +++ b/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js @@ -10,6 +10,7 @@ import { Orders, Shops, Packages } from "/lib/collections"; import { ButtonSelect } from "../../../../ui/client/components/button"; import DiscountList from "/imports/plugins/core/discounts/client/components/list"; import InvoiceContainer from "../../containers/invoiceContainer.js"; +import InvoiceActionsContainer from "../../containers/invoiceActionsContainer.js"; import LineItemsContainer from "../../containers/lineItemsContainer.js"; import TotalActionsContainer from "../../containers/totalActionsContainer.js"; @@ -83,6 +84,9 @@ Template.coreOrderShippingInvoice.helpers({ InvoiceContainer() { return InvoiceContainer; }, + InvoiceActionsContainer() { + return InvoiceActionsContainer; + }, buttonSelectComponent() { return { component: ButtonSelect, @@ -91,9 +95,9 @@ Template.coreOrderShippingInvoice.helpers({ name: "Approve", i18nKeyLabel: "order.approveInvoice", active: true, - status: "info", + status: "success", eventAction: "approveInvoice", - bgColor: "bg-info", + bgColor: "bg-success", buttonType: "submit" }, { name: "Cancel", @@ -437,7 +441,7 @@ Template.coreOrderShippingInvoice.helpers({ const order = instance.state.get("order"); const status = orderCreditMethod(order).paymentMethod.status; - if (status === "approved" || status === "completed") { + if (status === "approved" || status === "completed" || status === "refunded") { return false; } return true; @@ -552,12 +556,12 @@ Template.coreOrderShippingInvoice.helpers({ provides: "paymentMethod", enabled: true }); - for (app of apps) { + for (const app of apps) { if (app.enabled === true) enabledPaymentsArr.push(app); } let discount = false; - for (enabled of enabledPaymentsArr) { + for (const enabled of enabledPaymentsArr) { if (enabled.packageName === "discount-codes") { discount = true; break; diff --git a/imports/plugins/core/orders/client/templates/workflow/shippingTracking.html b/imports/plugins/core/orders/client/templates/workflow/shippingTracking.html index 7cc2481d26b..2b0c3af65c5 100644 --- a/imports/plugins/core/orders/client/templates/workflow/shippingTracking.html +++ b/imports/plugins/core/orders/client/templates/workflow/shippingTracking.html @@ -1,67 +1,73 @@ diff --git a/imports/plugins/core/orders/client/templates/workflow/workflow.html b/imports/plugins/core/orders/client/templates/workflow/workflow.html index d2b149a2146..52781d7c1c5 100644 --- a/imports/plugins/core/orders/client/templates/workflow/workflow.html +++ b/imports/plugins/core/orders/client/templates/workflow/workflow.html @@ -1,41 +1,10 @@