diff --git a/.eslintrc b/.eslintrc index 088b394af73..e5213b61765 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,33 +3,44 @@ "env": { "browser": true, "node": true, - "es6": true + "es6": true, + "mocha": true + }, + "globals": { + "browser": true, + "Assets": true, // Meteor global + "Package": true, // Meteor global + "FS": true, // gridFS, + "Alerts": true, // this needs to get cleaned up, but ignoring for now + "jest": true, + "expect": true, + "test": true }, "parserOptions": { "ecmaVersion": 6, "sourceType": "module", + "ecmaFeatures": { + "arrowFunctions": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": false, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": false, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "spread": true, + "superInFunctions": true, + "templateStrings": true, + "jsx": true + }, "allowImportExportEverywhere": true }, "plugins": ["react"], - "ecmaFeatures": { - "arrowFunctions": true, - "blockBindings": true, - "classes": true, - "defaultParams": true, - "destructuring": true, - "forOf": true, - "generators": false, - "modules": true, - "objectLiteralComputedProperties": true, - "objectLiteralDuplicateProperties": false, - "objectLiteralShorthandMethods": true, - "objectLiteralShorthandProperties": true, - "spread": true, - "superInFunctions": true, - "templateStrings": true, - "jsx": true - }, - // NOTE: We're now using eslint-3 + // NOTE: We're now using eslint-4 "rules": { /** * Strict mode @@ -160,7 +171,8 @@ "no-self-compare": 2, // http://eslint.org/docs/rules/no-self-compare "no-sequences": 2, // http://eslint.org/docs/rules/no-sequences "no-throw-literal": 2, // http://eslint.org/docs/rules/no-throw-literal - "no-with": 2, // http://eslint.org/docs/rules/no-with + "no-with": 2, // http://eslint.org/docs/rules/no-with, + "no-undef": 2, "radix": 2, // http://eslint.org/docs/rules/radix "vars-on-top": 2, // http://eslint.org/docs/rules/vars-on-top "wrap-iife": [2, "any"], // http://eslint.org/docs/rules/wrap-iife diff --git a/.meteor/packages b/.meteor/packages index f6ced0af955..213943a56bc 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -30,7 +30,6 @@ reload@1.1.11 ejson@1.0.13 less@2.7.9 service-configuration@1.0.11 -amplify mdg:validated-method shell-server@0.2.3 dynamic-import diff --git a/.meteor/versions b/.meteor/versions index 2522fc7db32..671a440f2dd 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -16,7 +16,6 @@ aldeed:schema-index@1.1.1 aldeed:simple-schema@1.5.3 aldeed:template-extension@4.1.0 allow-deny@1.0.5 -amplify@1.0.0 audit-argument-checks@1.0.7 autoupdate@1.3.12 babel-compiler@6.19.3 diff --git a/Dockerfile b/Dockerfile index b757d25bd91..6cdaf78cbf8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM reactioncommerce/base:v2.0.0 +FROM reactioncommerce/base:v2.0.2 # Default environment variables ENV ROOT_URL "http://localhost" diff --git a/client/config/defaults.js b/client/config/defaults.js index e844b4c48a3..cc88e5b7f74 100644 --- a/client/config/defaults.js +++ b/client/config/defaults.js @@ -1,4 +1,5 @@ import { Session } from "meteor/session"; +import { AutoForm } from "meteor/aldeed:autoform"; /** * Misc. App. Configuration diff --git a/client/modules/accounts/components/auth/loginButtons.js b/client/modules/accounts/components/auth/loginButtons.js index 1b7b958d682..a349cb76b67 100644 --- a/client/modules/accounts/components/auth/loginButtons.js +++ b/client/modules/accounts/components/auth/loginButtons.js @@ -46,7 +46,7 @@ class LoginButtons extends Component {   - + )) } diff --git a/client/modules/accounts/components/auth/signIn.js b/client/modules/accounts/components/auth/signIn.js index 212fae21aaf..e8b0a3a7767 100644 --- a/client/modules/accounts/components/auth/signIn.js +++ b/client/modules/accounts/components/auth/signIn.js @@ -135,7 +135,7 @@ class SignIn extends Component { value={this.state.email} onChange={this.handleFieldChange} /> - {this.renderEmailErrors()} + {this.renderEmailErrors()}
@@ -149,7 +149,7 @@ class SignIn extends Component { value={this.state.password} onChange={this.handleFieldChange} /> - {this.renderPasswordErrors()} + {this.renderPasswordErrors()}
diff --git a/client/modules/accounts/components/auth/signUp.js b/client/modules/accounts/components/auth/signUp.js index bc73024e606..e0b5f868282 100644 --- a/client/modules/accounts/components/auth/signUp.js +++ b/client/modules/accounts/components/auth/signUp.js @@ -133,7 +133,7 @@ class SignUp extends Component { value={this.state.password} onChange={this.handleFieldChange} /> - {this.renderPasswordErrors()} + {this.renderPasswordErrors()}
@@ -170,14 +170,14 @@ class SignUp extends Component { return (
-

- -

-
+

+ +

+
- {this.renderForm(emailClasses, passwordClasses)} + {this.renderForm(emailClasses, passwordClasses)} -
+ ); } } diff --git a/client/modules/accounts/components/dropdown/mainDropdown.js b/client/modules/accounts/components/dropdown/mainDropdown.js index 6dbb66dca19..76191be9f24 100644 --- a/client/modules/accounts/components/dropdown/mainDropdown.js +++ b/client/modules/accounts/components/dropdown/mainDropdown.js @@ -104,14 +104,14 @@ class MainDropdown extends Component {
{this.props.currentUser ?
- + {this.renderUserIcons()} {this.renderAdminIcons()} diff --git a/client/modules/accounts/components/passwordReset/forgot.js b/client/modules/accounts/components/passwordReset/forgot.js index 187aa7321a2..9408df2a939 100644 --- a/client/modules/accounts/components/passwordReset/forgot.js +++ b/client/modules/accounts/components/passwordReset/forgot.js @@ -129,7 +129,7 @@ class Forgot extends Component { data-event-category="accounts" onClick={this.props.onSignInClick} > - +
diff --git a/client/modules/accounts/components/passwordReset/updatePasswordOverlay.js b/client/modules/accounts/components/passwordReset/updatePasswordOverlay.js index 04f63ed2a9e..13b281c1e09 100644 --- a/client/modules/accounts/components/passwordReset/updatePasswordOverlay.js +++ b/client/modules/accounts/components/passwordReset/updatePasswordOverlay.js @@ -64,13 +64,13 @@ class UpdatePasswordOverlay extends Component { return ( {this.props.onError(this.props.messages.errors && this.props.messages.errors.password) && - this.props.messages.errors.password.map((error, i) => ( - - )) + this.props.messages.errors.password.map((error, i) => ( + + )) } ); @@ -80,7 +80,7 @@ class UpdatePasswordOverlay extends Component { if (this.props.isDisabled === true) { return (
- +
); } @@ -100,9 +100,9 @@ class UpdatePasswordOverlay extends Component { renderSpinnerOnLoad() { return ( -
-
-
+
+
+
); } @@ -114,17 +114,17 @@ class UpdatePasswordOverlay extends Component { const { showSpinner } = this.state; return ( -
+
{this.props.isOpen === true && -
-
-
-
- {showSpinner ? this.renderSpinnerOnLoad() : +
+
+
+
+ {showSpinner ? this.renderSpinnerOnLoad() :

- +

@@ -134,15 +134,15 @@ class UpdatePasswordOverlay extends Component { {this.renderFormMessages()}
- + {this.renderPasswordErrors()}
@@ -167,10 +167,10 @@ class UpdatePasswordOverlay extends Component {
- } -
+ }
-
} +
+
}
); } diff --git a/client/modules/accounts/containers/auth/authContainer.js b/client/modules/accounts/containers/auth/authContainer.js index d81aecd8850..7de73268c0e 100644 --- a/client/modules/accounts/containers/auth/authContainer.js +++ b/client/modules/accounts/containers/auth/authContainer.js @@ -2,6 +2,7 @@ import _ from "lodash"; import React, { Component } from "react"; import PropTypes from "prop-types"; import { Meteor } from "meteor/meteor"; +import { Accounts } from "meteor/accounts-base"; import { Router } from "/client/api"; import { composeWithTracker } from "/lib/api/compose"; import { SignIn, SignUp, LoginButtons } from "../../components"; @@ -202,7 +203,7 @@ class AuthContainer extends Component { onSocialClick={this.handleSocialLogin} capitalizeName={this.capitalizeName} /> - {this.renderAuthView()} + {this.renderAuthView()}
); } diff --git a/client/modules/accounts/containers/auth/loginContainer.js b/client/modules/accounts/containers/auth/loginContainer.js index 19de8c65745..37ecbd3fbdb 100644 --- a/client/modules/accounts/containers/auth/loginContainer.js +++ b/client/modules/accounts/containers/auth/loginContainer.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; +import { Random } from "meteor/random"; import { composeWithTracker } from "/lib/api/compose"; import AuthContainer from "./authContainer"; import { ForgotContainer } from "../passwordReset"; @@ -70,7 +71,6 @@ class LoginContainer extends Component { ); } } - } function composer(props, onData) { diff --git a/client/modules/accounts/containers/dropdown/mainDropdownContainer.js b/client/modules/accounts/containers/dropdown/mainDropdownContainer.js index 3cf99528e39..258f0e79837 100644 --- a/client/modules/accounts/containers/dropdown/mainDropdownContainer.js +++ b/client/modules/accounts/containers/dropdown/mainDropdownContainer.js @@ -2,7 +2,9 @@ import React, { Component } from "react"; import { Meteor } from "meteor/meteor"; import { Accounts } from "meteor/accounts-base"; import { Roles } from "meteor/alanning:roles"; -import { Reaction } from "/client/api"; +import { Session } from "meteor/session"; +import { Gravatar } from "meteor/jparker:gravatar"; +import { Reaction, Logger } from "/client/api"; import { i18nextDep, i18next } from "/client/api"; import { composeWithTracker } from "/lib/api/compose"; import * as Collections from "/lib/collections"; diff --git a/client/modules/accounts/containers/passwordReset/passwordOverlayContainer.js b/client/modules/accounts/containers/passwordReset/passwordOverlayContainer.js index 7eccf4ec55e..494e65767d5 100644 --- a/client/modules/accounts/containers/passwordReset/passwordOverlayContainer.js +++ b/client/modules/accounts/containers/passwordReset/passwordOverlayContainer.js @@ -2,6 +2,7 @@ import _ from "lodash"; import React, { Component } from "react"; import PropTypes from "prop-types"; import { Accounts } from "meteor/accounts-base"; +import { Random } from "meteor/random"; import { composeWithTracker } from "/lib/api/compose"; import { UpdatePasswordOverlay } from "/client/modules/accounts/components"; import { MessagesContainer } from "/client/modules/accounts/containers/helpers"; diff --git a/client/modules/accounts/helpers/templates.js b/client/modules/accounts/helpers/templates.js index 47cbb995484..4b2a34bf073 100644 --- a/client/modules/accounts/helpers/templates.js +++ b/client/modules/accounts/helpers/templates.js @@ -1,7 +1,10 @@ -import { Reaction, i18next, i18nextDep } from "/client/api"; -import * as Collections from "/lib/collections"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { Accounts } from "meteor/accounts-base"; +import { Roles } from "meteor/alanning:roles"; +import { Gravatar } from "meteor/jparker:gravatar"; +import { Reaction, i18next, i18nextDep } from "/client/api"; +import * as Collections from "/lib/collections"; Template.registerHelper("getGravatar", function (currentUser, size) { const options = { diff --git a/client/modules/accounts/helpers/util.js b/client/modules/accounts/helpers/util.js index 264ac5b7f9e..fb47aab4fa5 100644 --- a/client/modules/accounts/helpers/util.js +++ b/client/modules/accounts/helpers/util.js @@ -1,4 +1,6 @@ import _ from "lodash"; +import { Accounts } from "meteor/accounts-base"; +import { ServiceConfiguration } from "meteor/service-configuration"; function capitalize(str) { const finalString = str === null ? "" : String(str); @@ -33,7 +35,6 @@ providers.Twitter.fields = function () { }; export class ServiceConfigHelper { - availableServices() { const services = Package["accounts-oauth"] ? Accounts.oauth.serviceNames() : []; services.sort(); diff --git a/client/modules/accounts/templates/addressBook/add/add.js b/client/modules/accounts/templates/addressBook/add/add.js index 8d59624264a..83c8b98eab2 100644 --- a/client/modules/accounts/templates/addressBook/add/add.js +++ b/client/modules/accounts/templates/addressBook/add/add.js @@ -1,33 +1,57 @@ import { $ } from "meteor/jquery"; import { Session } from "meteor/session"; import { Meteor } from "meteor/meteor"; +import { HTTP } from "meteor/http"; +import { ReactiveVar } from "meteor/reactive-var"; +import { AutoForm } from "meteor/aldeed:autoform"; import { Template } from "meteor/templating"; -import { i18next } from "/client/api"; +import { Reaction, i18next } from "/client/api"; import * as Collections from "/lib/collections"; +Template.addressBookAdd.onCreated(function () { + this.currentCountry = new ReactiveVar(null); + // hit Reaction's GeoIP server and try to determine the user's country + HTTP.get("https://geo.getreaction.io/json/", (err, res) => { + if (!err) { + this.currentCountry.set(res.data.country_code); + } + }); +}); + Template.addressBookAdd.helpers({ - thisAddress: function () { + thisAddress() { const thisAddress = {}; - // admin should receive his account + + // admin should receive their account const account = Collections.Accounts.findOne({ userId: Meteor.userId() }); - if (account) { - if (account.profile) { - if (account.profile.name) { - thisAddress.fullName = account.profile.name; - } - // if this will be the first address we set defaults here and not display - // them inside form - if (account.profile.addressBook) { - if (account.profile.addressBook.length === 0) { - thisAddress.isShippingDefault = true; - thisAddress.isBillingDefault = true; - } + + if (account && account.profile) { + if (account.profile.name) { + thisAddress.fullName = account.profile.name; + } + // if this will be the first address we set defaults here and not display + // them inside form + if (account.profile.addressBook) { + if (account.profile.addressBook.length === 0) { + thisAddress.isShippingDefault = true; + thisAddress.isBillingDefault = true; } } } + const shop = Collections.Shops.findOne(Reaction.getShopId()); + + // Set default country code based on shop's shipping address + if (shop && Array.isArray(shop.addressBook) && shop.addressBook.length > 0) { + const defaultAddress = shop.addressBook.find(address => address.isShippingDefault); + const defaultCountryCode = defaultAddress.country; + if (defaultCountryCode) { + thisAddress.country = defaultCountryCode; + } + } + if (Session.get("address")) { thisAddress.postal = Session.get("address").zipcode; thisAddress.country = Session.get("address").countryCode; @@ -35,6 +59,9 @@ Template.addressBookAdd.helpers({ thisAddress.region = Session.get("address").state; } + // update the reactive country code from the GeoIP lookup (if found) + thisAddress.country = Template.instance().currentCountry.get() || thisAddress.country; + return thisAddress; }, diff --git a/client/modules/accounts/templates/addressBook/edit/edit.js b/client/modules/accounts/templates/addressBook/edit/edit.js index 0b6950d1cf1..aa38f2cab3c 100644 --- a/client/modules/accounts/templates/addressBook/edit/edit.js +++ b/client/modules/accounts/templates/addressBook/edit/edit.js @@ -1,6 +1,8 @@ import { $ } from "meteor/jquery"; import { Meteor } from "meteor/meteor"; import { Session } from "meteor/session"; +import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; import { i18next } from "/client/api"; diff --git a/client/modules/accounts/templates/addressBook/form/form.js b/client/modules/accounts/templates/addressBook/form/form.js index edf8c414e0b..adb8fa88368 100644 --- a/client/modules/accounts/templates/addressBook/form/form.js +++ b/client/modules/accounts/templates/addressBook/form/form.js @@ -1,6 +1,7 @@ import { Session } from "meteor/session"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; import { Countries } from "/client/collections"; import * as Collections from "/lib/collections"; diff --git a/client/modules/accounts/templates/dashboard/dashboard.js b/client/modules/accounts/templates/dashboard/dashboard.js index d4dcb9f9fa0..aedb6543d6c 100644 --- a/client/modules/accounts/templates/dashboard/dashboard.js +++ b/client/modules/accounts/templates/dashboard/dashboard.js @@ -1,6 +1,8 @@ import _ from "lodash"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { Roles } from "meteor/alanning:roles"; +import { ServiceConfiguration } from "meteor/service-configuration"; import { Reaction, i18next } from "/client/api"; import * as Collections from "/lib/collections"; import { ServiceConfigHelper } from "../../helpers/util"; @@ -17,7 +19,6 @@ Template.accountsDashboard.onCreated(function () { Template.accountsDashboard.helpers({ /** * isShopMember - * @param {Object} member member object * @return {Boolean} True if the memnber is an administrator */ isShopMember() { @@ -26,7 +27,6 @@ Template.accountsDashboard.helpers({ /** * isShopGuest - * @param {Object} member member object * @return {Boolean} True if the member is a guest */ isShopGuest() { diff --git a/client/modules/accounts/templates/dropdown/dropdown.js b/client/modules/accounts/templates/dropdown/dropdown.js index 2b0085fccbf..3c621630346 100644 --- a/client/modules/accounts/templates/dropdown/dropdown.js +++ b/client/modules/accounts/templates/dropdown/dropdown.js @@ -3,6 +3,7 @@ import { Tags } from "/lib/collections"; import { Session } from "meteor/session"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { Roles } from "meteor/alanning:roles"; Template.loginDropdown.events({ diff --git a/client/modules/accounts/templates/dropdown/helpers/templates.js b/client/modules/accounts/templates/dropdown/helpers/templates.js index ca4edf48957..fdf7673e1b9 100644 --- a/client/modules/accounts/templates/dropdown/helpers/templates.js +++ b/client/modules/accounts/templates/dropdown/helpers/templates.js @@ -1,7 +1,10 @@ -import { Reaction, i18next, i18nextDep } from "/client/api"; -import * as Collections from "/lib/collections"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { Accounts } from "meteor/accounts-base"; +import { Roles } from "meteor/alanning:roles"; +import { Gravatar } from "meteor/jparker:gravatar"; +import { Reaction, i18next, i18nextDep } from "/client/api"; +import * as Collections from "/lib/collections"; Template.registerHelper("getGravatar", function (currentUser, size) { const options = { diff --git a/client/modules/accounts/templates/dropdown/helpers/util.js b/client/modules/accounts/templates/dropdown/helpers/util.js index 264ac5b7f9e..fb47aab4fa5 100644 --- a/client/modules/accounts/templates/dropdown/helpers/util.js +++ b/client/modules/accounts/templates/dropdown/helpers/util.js @@ -1,4 +1,6 @@ import _ from "lodash"; +import { Accounts } from "meteor/accounts-base"; +import { ServiceConfiguration } from "meteor/service-configuration"; function capitalize(str) { const finalString = str === null ? "" : String(str); @@ -33,7 +35,6 @@ providers.Twitter.fields = function () { }; export class ServiceConfigHelper { - availableServices() { const services = Package["accounts-oauth"] ? Accounts.oauth.serviceNames() : []; services.sort(); diff --git a/client/modules/accounts/templates/members/member.js b/client/modules/accounts/templates/members/member.js index 48441f7ab70..d0033cbe81c 100644 --- a/client/modules/accounts/templates/members/member.js +++ b/client/modules/accounts/templates/members/member.js @@ -3,6 +3,8 @@ import { Reaction } from "/client/api"; import { Packages, Shops } from "/lib/collections"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; +import { Roles } from "meteor/alanning:roles"; const getPermissionMap = (permissions) => { const permissionMap = {}; @@ -44,7 +46,7 @@ Template.memberSettings.helpers({ }, hasPermissionChecked: function (permission, userId) { if (userId && Roles.userIsInRole(userId, permission, this.shopId || Roles.userIsInRole(userId, permission, - Roles.GLOBAL_GROUP))) { + Roles.GLOBAL_GROUP))) { return "checked"; } }, diff --git a/client/modules/accounts/templates/members/memberForm.js b/client/modules/accounts/templates/members/memberForm.js index 4ff8a802238..c60e5e2b262 100644 --- a/client/modules/accounts/templates/members/memberForm.js +++ b/client/modules/accounts/templates/members/memberForm.js @@ -1,6 +1,7 @@ import { Reaction, i18next } from "/client/api"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; /** @@ -26,7 +27,7 @@ Template.memberForm.events({ message = error; } else { message = `${i18next.t("accountsUI.error.errorSendingEmail") - } ${error}`; + } ${error}`; } Alerts.inline(message, "error", { diff --git a/client/modules/accounts/templates/profile/profile.js b/client/modules/accounts/templates/profile/profile.js index be8cd0dde87..952ab68b4a1 100644 --- a/client/modules/accounts/templates/profile/profile.js +++ b/client/modules/accounts/templates/profile/profile.js @@ -1,6 +1,7 @@ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; -import { Reaction } from "/lib/api"; +import { ReactiveVar } from "meteor/reactive-var"; +import { Reaction } from "/client/api"; import * as Collections from "/lib/collections"; /** diff --git a/client/modules/accounts/templates/updatePassword/updatePassword.js b/client/modules/accounts/templates/updatePassword/updatePassword.js index 401e780b2d3..ed11720a8e5 100644 --- a/client/modules/accounts/templates/updatePassword/updatePassword.js +++ b/client/modules/accounts/templates/updatePassword/updatePassword.js @@ -1,5 +1,10 @@ import { Accounts } from "meteor/accounts-base"; import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; +import { $ } from "meteor/jquery"; +import { Random } from "meteor/random"; +import { Blaze } from "meteor/blaze"; +import { ReactiveVar } from "meteor/reactive-var"; import { i18next } from "/client/api"; import { LoginFormSharedHelpers } from "/client/modules/accounts/helpers"; import { UpdatePasswordOverlayContainer } from "/client/modules/accounts/containers"; diff --git a/client/modules/accounts/templates/verify/verifyAccount.js b/client/modules/accounts/templates/verify/verifyAccount.js index 33f13798f61..145e352f724 100644 --- a/client/modules/accounts/templates/verify/verifyAccount.js +++ b/client/modules/accounts/templates/verify/verifyAccount.js @@ -1,13 +1,14 @@ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { ReactiveVar } from "meteor/reactive-var"; import { Reaction } from "/client/api"; Template.verifyAccount.onCreated(() => { const template = Template.instance(); template.verified = ReactiveVar(false); const email = Reaction.Router.getQueryParam("email"); - Meteor.call("accounts/verifyAccount", email, (err, result) => { - if (err) { + Meteor.call("accounts/verifyAccount", email, (error, result) => { + if (error) { throw new Meteor.Error("Account Verification error", error); } return template.verified.set(result); diff --git a/client/modules/core/accounts.js b/client/modules/core/accounts.js index 7d679c1537f..7a69515ea31 100644 --- a/client/modules/core/accounts.js +++ b/client/modules/core/accounts.js @@ -1,6 +1,7 @@ +import store from "amplify-store"; import { Accounts } from "meteor/accounts-base"; import { Session } from "meteor/session"; -// import { amplify } from "meteor/amplify"; +import { Random } from "meteor/random"; /* * registerLoginHandler @@ -17,9 +18,9 @@ Accounts.loginWithAnonymous = function (anonymous, callback) { // another way: `accounts` package uses `setTimeout` for monitoring connection // Accounts.callLoginMethod will be called after clearing cache. We could // latch on this computations by running extra check here. - if (typeof amplify.store("Reaction.session") !== "string") { + if (typeof store("Reaction.session") !== "string") { const newSession = Random.id(); - amplify.store("Reaction.session", newSession); + store("Reaction.session", newSession); Session.set("sessionId", newSession); } Accounts.callLoginMethod({ diff --git a/client/modules/core/helpers/apps.js b/client/modules/core/helpers/apps.js index 07b1ab4f77d..72ab1829b47 100644 --- a/client/modules/core/helpers/apps.js +++ b/client/modules/core/helpers/apps.js @@ -1,7 +1,10 @@ import _ from "lodash"; +import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; +import { Roles } from "meteor/alanning:roles"; import { Reaction } from "/client/api"; import { Packages } from "/lib/collections"; -import { Template } from "meteor/templating"; + /** * diff --git a/client/modules/core/helpers/globals.js b/client/modules/core/helpers/globals.js index 7652326a9e4..6e87c0dfacb 100644 --- a/client/modules/core/helpers/globals.js +++ b/client/modules/core/helpers/globals.js @@ -1,3 +1,4 @@ +import _ from "lodash"; import { Session } from "meteor/session"; import { Meteor } from "meteor/meteor"; import { Roles } from "meteor/alanning:roles"; @@ -71,7 +72,7 @@ export function getGuestLoginState() { return true; } } else if (Session.equals("guestCheckoutFlow", true) && _.pluck(Meteor.user() - .emails, "address")) { + .emails, "address")) { return true; } return false; diff --git a/client/modules/core/helpers/templates.js b/client/modules/core/helpers/templates.js index 5b49e0d4528..3c53c435003 100644 --- a/client/modules/core/helpers/templates.js +++ b/client/modules/core/helpers/templates.js @@ -1,20 +1,18 @@ +import _ from "lodash"; import * as tz from "moment-timezone"; import moment from "moment"; import "moment/min/locales.min.js"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { Accounts } from "meteor/accounts-base"; +import { Spacebars } from "meteor/spacebars"; +import { Roles } from "meteor/alanning:roles"; import { i18next } from "/client/api"; import { Reaction } from "../"; import * as Collections from "/lib/collections"; import * as Schemas from "/lib/collections/schemas"; import { toCamelCase } from "/lib/api"; -/* - * - * Reaction Spacebars helpers - * See: http://docs.meteor.com/#/full/template_registerhelper - * - */ Template.registerHelper("Collections", function () { return Collections; @@ -29,22 +27,22 @@ Template.registerHelper("Schemas", function () { * @summary overrides Meteor Package.blaze currentUser method * @return {[Boolean]} returns true/null if user has registered */ -if (Package.blaze) { - Package.blaze.Blaze.Template.registerHelper("currentUser", function () { - if (typeof Reaction === "object") { - const shopId = Reaction.getShopId(); - const user = Accounts.user(); - if (!shopId || typeof user !== "object") return null; - // shoppers should always be guests - const isGuest = Roles.userIsInRole(user, "guest", shopId); - // but if a user has never logged in then they are anonymous - const isAnonymous = Roles.userIsInRole(user, "anonymous", shopId); - - return isGuest && !isAnonymous ? user : null; - } - return null; - }); -} + +Template.registerHelper("currentUser", function () { + if (typeof Reaction === "object") { + const shopId = Reaction.getShopId(); + const user = Accounts.user(); + if (!shopId || typeof user !== "object") return null; + // shoppers should always be guests + const isGuest = Roles.userIsInRole(user, "guest", shopId); + // but if a user has never logged in then they are anonymous + const isAnonymous = Roles.userIsInRole(user, "anonymous", shopId); + + return isGuest && !isAnonymous ? user : null; + } + return null; +}); + /** * registerHelper monthOptions diff --git a/client/modules/core/helpers/utils.js b/client/modules/core/helpers/utils.js index 3329ee37b0b..447f54258e6 100644 --- a/client/modules/core/helpers/utils.js +++ b/client/modules/core/helpers/utils.js @@ -1,3 +1,4 @@ +/* global slugify */ // client slugify only works when import minified version. import "transliteration/lib/browser/transliteration.js"; diff --git a/client/modules/core/main.js b/client/modules/core/main.js index 603111b10c1..98ecd302099 100644 --- a/client/modules/core/main.js +++ b/client/modules/core/main.js @@ -5,6 +5,7 @@ import { check } from "meteor/check"; import { Tracker } from "meteor/tracker"; import { ReactiveVar } from "meteor/reactive-var"; import { ReactiveDict } from "meteor/reactive-dict"; +import { Roles } from "meteor/alanning:roles"; import Logger from "/client/modules/logger"; import { Countries } from "/client/collections"; import { localeDep } from "/client/modules/i18n"; diff --git a/client/modules/core/startup.js b/client/modules/core/startup.js index 48bc5d95390..5558ad21ea0 100644 --- a/client/modules/core/startup.js +++ b/client/modules/core/startup.js @@ -1,6 +1,12 @@ +import store from "amplify-store"; import { Meteor } from "meteor/meteor"; import { Tracker } from "meteor/tracker"; -import Reaction from "./main"; +import { Accounts } from "meteor/accounts-base"; + +import { Reaction, Logger } from "/client/api"; + + +const cookieName = "_RcFallbackLoginToken"; /** * Startup Reaction @@ -12,17 +18,66 @@ Meteor.startup(function () { // initialize anonymous guest users return Tracker.autorun(function () { const userId = Meteor.userId(); + + if (userId && !isLocalStorageAvailable() && !readCookie(cookieName)) { + Logger.debug("No local storage available. About to set up fallback login " + + "mechanism with cookie login token."); + Meteor.call("accounts/createFallbackLoginToken", (err, token) => { + if (!err && token) { + window.onbeforeunload = () => createSessionCookie(cookieName, token); + return; + } + // Can't set login cookie. Fail silently. + Logger.error("Setting up fallback login mechanism failed!"); + }); + } + // TODO: maybe `visibilityState` will be better here let loggingIn; let sessionId; Tracker.nonreactive(function () { loggingIn = Accounts.loggingIn(); - sessionId = amplify.store("Reaction.session"); + sessionId = store("Reaction.session"); }); + if (!userId) { if (!loggingIn || typeof sessionId !== "string") { - Accounts.loginWithAnonymous(); + if (!isLocalStorageAvailable() && readCookie(cookieName)) { + // If re-login through local storage fails, RC falls back + // to cookie-based login. E.g. Applies for Safari browser in + // incognito mode. + Accounts.loginWithToken(readCookie(cookieName)); + } else { + Accounts.loginWithAnonymous(); + } } } }); }); + +function isLocalStorageAvailable() { + try { + localStorage.testKey = "testValue"; + } catch (e) { + return false; + } + delete localStorage.testKey; + return true; +} + +function readCookie(name) { + const nameEq = name + "="; + const ca = document.cookie.split(";"); + for (let i = 0; i < ca.length; i++) { + let c = ca[i]; + while (c.charAt(0) === " ") c = c.substring(1, c.length); + if (c.indexOf(nameEq) === 0) { + return c.substring(nameEq.length, c.length); + } + } + return null; +} + +function createSessionCookie(name, value) { + document.cookie = name + "=" + value + "; path=/"; +} diff --git a/client/modules/core/subscriptions.js b/client/modules/core/subscriptions.js index a1157913bf4..824d3318a3a 100644 --- a/client/modules/core/subscriptions.js +++ b/client/modules/core/subscriptions.js @@ -1,3 +1,4 @@ +import store from "amplify-store"; import { Meteor } from "meteor/meteor"; import { Random } from "meteor/random"; import { Session } from "meteor/session"; @@ -49,17 +50,17 @@ Tracker.autorun(function () { // we are trying to track both amplify and Session.get here, but the problem // is - we can't track amplify. It just not tracked. So, to track amplify we // are using dirty hack inside Accounts.loginWithAnonymous method. - const sessionId = amplify.store("Reaction.session"); + const sessionId = store("Reaction.session"); let newSession; Tracker.nonreactive(() => { newSession = Random.id(); }); if (typeof sessionId !== "string") { - amplify.store("Reaction.session", newSession); + store("Reaction.session", newSession); Session.set("sessionId", newSession); } if (typeof Session.get("sessionId") !== "string") { - Session.set("sessionId", amplify.store("Reaction.session")); + Session.set("sessionId", store("Reaction.session")); } Subscriptions.Sessions = Meteor.subscribe("Sessions", Session.get("sessionId")); }); diff --git a/client/modules/i18n/helpers.js b/client/modules/i18n/helpers.js index 61761b6beb2..66c656bbaff 100644 --- a/client/modules/i18n/helpers.js +++ b/client/modules/i18n/helpers.js @@ -1,4 +1,5 @@ import { Template } from "meteor/templating"; +import { check, Match } from "meteor/check"; import { Reaction, Logger, i18next } from "/client/api"; import { Shops } from "/lib/collections"; import { localeDep, i18nextDep } from "./main"; diff --git a/client/modules/i18n/main.js b/client/modules/i18n/main.js index 5745638e4f1..3b52276b6fd 100644 --- a/client/modules/i18n/main.js +++ b/client/modules/i18n/main.js @@ -40,7 +40,7 @@ export function getLabelsFor(schema, name) { for (const fieldName of schema._schemaKeys) { const i18nKey = name.charAt(0).toLowerCase() + name.slice(1) + "." + fieldName - .split(".$").join(""); + .split(".$").join(""); // translate autoform label const t = i18next.t(i18nKey); if (new RegExp("string").test(t) !== true && t !== i18nKey) { diff --git a/client/modules/i18n/startup.js b/client/modules/i18n/startup.js index 8d07570ffb7..16a8409878e 100644 --- a/client/modules/i18n/startup.js +++ b/client/modules/i18n/startup.js @@ -4,6 +4,7 @@ import i18nextLocalStorageCache from "i18next-localstorage-cache"; import i18nextSprintfPostProcessor from "i18next-sprintf-postprocessor"; import i18nextJquery from "jquery-i18next"; import { Meteor } from "meteor/meteor"; +import { Template } from "meteor/templating"; import { $ } from "meteor/jquery"; import { Tracker } from "meteor/tracker"; import { Reaction } from "/client/api"; diff --git a/client/modules/i18n/templates/header/components/i18n.js b/client/modules/i18n/templates/header/components/i18n.js index fa38ce62a1d..e8bc14e6e18 100644 --- a/client/modules/i18n/templates/header/components/i18n.js +++ b/client/modules/i18n/templates/header/components/i18n.js @@ -34,27 +34,27 @@ class LanguageDropDown extends Component {
{this.props.languages.length > 1 &&
- + + + + {this.props.languages.map((language) => ( - - {this.props.languages.map((language) => ( - - ))} - + ))} +
}
diff --git a/client/modules/i18n/templates/header/containers/i18nContainer.js b/client/modules/i18n/templates/header/containers/i18nContainer.js index 1ad62ab85fc..ac4e31c812a 100644 --- a/client/modules/i18n/templates/header/containers/i18nContainer.js +++ b/client/modules/i18n/templates/header/containers/i18nContainer.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import { Reaction } from "/client/api"; +import { Meteor } from "meteor/meteor"; import { Shops } from "/lib/collections"; import { composeWithTracker } from "/lib/api/compose"; import Language from "../components/i18n"; diff --git a/client/modules/router/helpers.js b/client/modules/router/helpers.js index 88deb0b1c21..168cdc91b4c 100644 --- a/client/modules/router/helpers.js +++ b/client/modules/router/helpers.js @@ -1,3 +1,5 @@ +import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; import Router from "./main"; // diff --git a/imports/plugins/core/catalog/client/templates/settings.js b/imports/plugins/core/catalog/client/templates/settings.js index fb29d5f0ce0..8bc225a1254 100644 --- a/imports/plugins/core/catalog/client/templates/settings.js +++ b/imports/plugins/core/catalog/client/templates/settings.js @@ -1,3 +1,6 @@ +import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; + Template.catalogSettings.helpers({ checked(enabled) { if (enabled === true) { diff --git a/imports/plugins/core/checkout/client/components/cartDrawer.js b/imports/plugins/core/checkout/client/components/cartDrawer.js index 4383649e920..3edbf03a8c5 100644 --- a/imports/plugins/core/checkout/client/components/cartDrawer.js +++ b/imports/plugins/core/checkout/client/components/cartDrawer.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from "react"; +import React from "react"; +import PropTypes from "prop-types"; import CartSubTotals from "../container/cartSubTotalContainer"; import CartItems from "./cartItems"; @@ -30,7 +31,7 @@ const cartDrawer = ({ productItems, pdpPath, handleRemoveItem, handleCheckout, h
Checkout now - +
); diff --git a/imports/plugins/core/checkout/client/components/emptyCartDrawer.js b/imports/plugins/core/checkout/client/components/emptyCartDrawer.js index dd96037fb91..a0e87fa4425 100644 --- a/imports/plugins/core/checkout/client/components/emptyCartDrawer.js +++ b/imports/plugins/core/checkout/client/components/emptyCartDrawer.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from "react"; +import React from "react"; +import PropTypes from "prop-types"; import { Button, Translation } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/checkout/client/container/cartDrawerContainer.js b/imports/plugins/core/checkout/client/container/cartDrawerContainer.js index a89f4a3d3ca..3ebc9754e5e 100644 --- a/imports/plugins/core/checkout/client/container/cartDrawerContainer.js +++ b/imports/plugins/core/checkout/client/container/cartDrawerContainer.js @@ -1,4 +1,6 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { $ } from "meteor/jquery"; import { Session } from "meteor/session"; import { Meteor } from "meteor/meteor"; import { Cart, Media } from "/lib/collections"; diff --git a/imports/plugins/core/checkout/client/container/cartSubTotalContainer.js b/imports/plugins/core/checkout/client/container/cartSubTotalContainer.js index 2684d064487..8e694cf207f 100644 --- a/imports/plugins/core/checkout/client/container/cartSubTotalContainer.js +++ b/imports/plugins/core/checkout/client/container/cartSubTotalContainer.js @@ -12,7 +12,6 @@ class CartSubTotalContainer extends Component { /> ); } - } function composer(props, onData) { diff --git a/imports/plugins/core/checkout/client/container/emptyCartContainer.js b/imports/plugins/core/checkout/client/container/emptyCartContainer.js index 7173aef9802..1bfb59bb719 100644 --- a/imports/plugins/core/checkout/client/container/emptyCartContainer.js +++ b/imports/plugins/core/checkout/client/container/emptyCartContainer.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import { $ } from "meteor/jquery"; import { Reaction } from "/client/api"; import EmptyCartDrawer from "../components/emptyCartDrawer"; diff --git a/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js b/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js index 733b188e1d2..2fffad7bc97 100644 --- a/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js +++ b/imports/plugins/core/checkout/client/templates/cartDrawer/cartDrawer.js @@ -1,3 +1,4 @@ +import { $ } from "meteor/jquery"; import { Cart } from "/lib/collections"; import { Session } from "meteor/session"; import { Template } from "meteor/templating"; diff --git a/imports/plugins/core/checkout/client/templates/cartIcon/cartIcon.js b/imports/plugins/core/checkout/client/templates/cartIcon/cartIcon.js index 7655b8d4e8f..c77646421ba 100644 --- a/imports/plugins/core/checkout/client/templates/cartIcon/cartIcon.js +++ b/imports/plugins/core/checkout/client/templates/cartIcon/cartIcon.js @@ -1,3 +1,4 @@ +import { $ } from "meteor/jquery"; import { Reaction } from "/client/api"; import { Cart } from "/lib/collections"; import { Template } from "meteor/templating"; diff --git a/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js b/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js index 6050ebc386c..ae994452463 100644 --- a/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js +++ b/imports/plugins/core/checkout/client/templates/cartPanel/component/cartPanel.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Button } from "/imports/plugins/core/ui/client/components"; class CartPanel extends Component { diff --git a/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js b/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js index 098183e7237..5e4d16001b3 100644 --- a/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js +++ b/imports/plugins/core/checkout/client/templates/cartPanel/container/cartPanelContainer.js @@ -1,4 +1,6 @@ import React, { Component } from "react"; +import { $ } from "meteor/jquery"; +import { Session } from "meteor/session"; import { Reaction } from "/client/api"; import CartPanel from "../component/cartPanel"; diff --git a/imports/plugins/core/checkout/client/templates/checkout/checkout.js b/imports/plugins/core/checkout/client/templates/checkout/checkout.js index ce0f6fdf085..3129a7fe98c 100644 --- a/imports/plugins/core/checkout/client/templates/checkout/checkout.js +++ b/imports/plugins/core/checkout/client/templates/checkout/checkout.js @@ -23,7 +23,7 @@ Template.cartCheckout.onCreated(function () { if (Reaction.Subscriptions.Cart.ready()) { const cart = Cart.findOne(); if (cart && cart.workflow && cart.workflow.status === "new") { - // if user logged in as normal user, we must pass it through the first stage + // if user logged in as normal user, we must pass it through the first stage Meteor.call("workflow/pushCartWorkflow", "coreCartWorkflow", "checkoutLogin", cart._id); } } diff --git a/imports/plugins/core/checkout/client/templates/checkout/completed/completed.js b/imports/plugins/core/checkout/client/templates/checkout/completed/completed.js index 1a699ee4e7d..17367084869 100644 --- a/imports/plugins/core/checkout/client/templates/checkout/completed/completed.js +++ b/imports/plugins/core/checkout/client/templates/checkout/completed/completed.js @@ -1,8 +1,10 @@ import { Meteor } from "meteor/meteor"; import { Session } from "meteor/session"; +import { Template } from "meteor/templating"; +import { check } from "meteor/check"; import { Reaction, i18next } from "/client/api"; import { Orders } from "/lib/collections"; -import { Template } from "meteor/templating"; + /** * cartCompleted helpers diff --git a/imports/plugins/core/checkout/client/templates/checkout/login/login.js b/imports/plugins/core/checkout/client/templates/checkout/login/login.js index 66110c2d46d..fa0a84761f6 100644 --- a/imports/plugins/core/checkout/client/templates/checkout/login/login.js +++ b/imports/plugins/core/checkout/client/templates/checkout/login/login.js @@ -1,7 +1,9 @@ -import { Reaction } from "/client/api"; -import { Cart } from "/lib/collections"; import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { Roles } from "meteor/alanning:roles"; +import { Reaction } from "/client/api"; +import { Cart } from "/lib/collections"; + /** * checkoutLoginCompleted diff --git a/imports/plugins/core/checkout/server/methods/workflow.js b/imports/plugins/core/checkout/server/methods/workflow.js index 05baa945b57..45c695613a2 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 { Roles } from "meteor/alanning:roles"; import { check, Match } from "meteor/check"; import { Cart, Orders, Packages, Groups } from "/lib/collections"; import { Logger, Reaction } from "/server/api"; @@ -181,7 +182,7 @@ Meteor.methods({ templateProcessedinWorkflow === false) { Logger.debug("######## Condition Three #########: complete workflow " + currentWorkflowStatus + " updates and move to: ", - nextWorkflowStep.template); + nextWorkflowStep.template); return Cart.update(currentCart._id, { $set: { "workflow.status": nextWorkflowStep.template diff --git a/imports/plugins/core/dashboard/client/components/actionView.js b/imports/plugins/core/dashboard/client/components/actionView.js index 136f4603446..60fbaf7ba4a 100644 --- a/imports/plugins/core/dashboard/client/components/actionView.js +++ b/imports/plugins/core/dashboard/client/components/actionView.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import Blaze from "meteor/gadicc:blaze-react-component"; import { Admin } from "/imports/plugins/core/ui/client/providers"; @@ -367,7 +368,7 @@ class ActionView extends Component {
- {this.renderControlComponent()} + {this.renderControlComponent()}
@@ -411,8 +412,8 @@ class ActionView extends Component {
- {/* this.renderControlComponent() */} - {this.renderDetailComponent()} + {/* this.renderControlComponent() */} + {this.renderDetailComponent()}
diff --git a/imports/plugins/core/dashboard/client/components/packageList.js b/imports/plugins/core/dashboard/client/components/packageList.js index d52f002e413..c06cc9ee62f 100644 --- a/imports/plugins/core/dashboard/client/components/packageList.js +++ b/imports/plugins/core/dashboard/client/components/packageList.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { map } from "lodash"; import { Card, CardHeader, CardBody, CardGroup, ListItem } from "/imports/plugins/core/ui/client/components"; import { getComponent } from "/imports/plugins/core/layout/lib/components"; diff --git a/imports/plugins/core/dashboard/client/components/shortcutBar.js b/imports/plugins/core/dashboard/client/components/shortcutBar.js index 45261eac4fd..64ca5e2e5f3 100644 --- a/imports/plugins/core/dashboard/client/components/shortcutBar.js +++ b/imports/plugins/core/dashboard/client/components/shortcutBar.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { map } from "lodash"; import { FlatButton, Icon } from "/imports/plugins/core/ui/client/components"; import { isEqual } from "lodash"; diff --git a/imports/plugins/core/dashboard/client/components/toolbar.js b/imports/plugins/core/dashboard/client/components/toolbar.js index b6a4a12ce86..3d306bba231 100644 --- a/imports/plugins/core/dashboard/client/components/toolbar.js +++ b/imports/plugins/core/dashboard/client/components/toolbar.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Blaze from "meteor/gadicc:blaze-react-component"; import { DropDownMenu, diff --git a/imports/plugins/core/dashboard/client/containers/actionViewContainer.js b/imports/plugins/core/dashboard/client/containers/actionViewContainer.js index ae40e7d5a4a..607a31d523a 100644 --- a/imports/plugins/core/dashboard/client/containers/actionViewContainer.js +++ b/imports/plugins/core/dashboard/client/containers/actionViewContainer.js @@ -1,5 +1,6 @@ import React from "react"; import { StyleRoot } from "radium"; +import _ from "lodash"; import { composeWithTracker } from "/lib/api/compose"; import { Reaction } from "/client/api"; import { TranslationProvider, AdminContextProvider } from "/imports/plugins/core/ui/client/providers"; diff --git a/imports/plugins/core/dashboard/client/containers/packageListContainer.js b/imports/plugins/core/dashboard/client/containers/packageListContainer.js index 4909e4ff3d7..ffe4975484d 100644 --- a/imports/plugins/core/dashboard/client/containers/packageListContainer.js +++ b/imports/plugins/core/dashboard/client/containers/packageListContainer.js @@ -1,4 +1,7 @@ import React from "react"; +import { Meteor } from "meteor/meteor"; +import { Template } from "meteor/templating"; +import { Roles } from "meteor/alanning:roles"; import { composeWithTracker } from "/lib/api/compose"; import { Reaction } from "/client/api"; import { Loading } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/dashboard/client/containers/toolbarContainer.js b/imports/plugins/core/dashboard/client/containers/toolbarContainer.js index e7590d2079a..7e3010a5f0c 100644 --- a/imports/plugins/core/dashboard/client/containers/toolbarContainer.js +++ b/imports/plugins/core/dashboard/client/containers/toolbarContainer.js @@ -1,5 +1,6 @@ import React from "react"; import { Meteor } from "meteor/meteor"; +import { Session } from "meteor/session"; import { composeWithTracker } from "/lib/api/compose"; import { Reaction, i18next } from "/client/api"; import { Tags, Shops } from "/lib/collections"; diff --git a/imports/plugins/core/dashboard/client/templates/dashboard.js b/imports/plugins/core/dashboard/client/templates/dashboard.js index 8aea218727f..58ca4bd0040 100644 --- a/imports/plugins/core/dashboard/client/templates/dashboard.js +++ b/imports/plugins/core/dashboard/client/templates/dashboard.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import { Reaction } from "/client/api"; import { translateRegistry } from "/lib/api"; diff --git a/imports/plugins/core/dashboard/client/templates/import/import.js b/imports/plugins/core/dashboard/client/templates/import/import.js index f37ce9e9b42..e5c4bf38207 100644 --- a/imports/plugins/core/dashboard/client/templates/import/import.js +++ b/imports/plugins/core/dashboard/client/templates/import/import.js @@ -1,3 +1,5 @@ +import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; import { Reaction } from "/client/api"; import { Media, Products } from "/lib/collections"; diff --git a/imports/plugins/core/dashboard/client/templates/packages/grid/grid.js b/imports/plugins/core/dashboard/client/templates/packages/grid/grid.js index 911b3d27d66..7e08d37bc03 100644 --- a/imports/plugins/core/dashboard/client/templates/packages/grid/grid.js +++ b/imports/plugins/core/dashboard/client/templates/packages/grid/grid.js @@ -1,4 +1,6 @@ import _ from "lodash"; +import { Template } from "meteor/templating"; +import { ReactiveDict } from "meteor/reactive-dict"; import { Meteor } from "meteor/meteor"; import { Reaction, i18next } from "/client/api"; diff --git a/imports/plugins/core/dashboard/client/templates/packages/grid/package.js b/imports/plugins/core/dashboard/client/templates/packages/grid/package.js index af016aaaeee..8b1475eb0e7 100644 --- a/imports/plugins/core/dashboard/client/templates/packages/grid/package.js +++ b/imports/plugins/core/dashboard/client/templates/packages/grid/package.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import { Reaction } from "/client/api"; /* eslint no-loop-func: 0 */ diff --git a/imports/plugins/core/dashboard/client/templates/packages/packages.js b/imports/plugins/core/dashboard/client/templates/packages/packages.js index 15fc8a9e184..934d4850ce4 100644 --- a/imports/plugins/core/dashboard/client/templates/packages/packages.js +++ b/imports/plugins/core/dashboard/client/templates/packages/packages.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import { PackageList } from "../../components"; import { PackageListContainer } from "../../containers"; diff --git a/imports/plugins/core/dashboard/client/templates/settings/settings.js b/imports/plugins/core/dashboard/client/templates/settings/settings.js index 8e57e560695..fb2e14f4ccf 100644 --- a/imports/plugins/core/dashboard/client/templates/settings/settings.js +++ b/imports/plugins/core/dashboard/client/templates/settings/settings.js @@ -1,4 +1,5 @@ import _ from "lodash"; +import { Template } from "meteor/templating"; import { Reaction } from "/client/api"; import { Packages } from "/lib/collections"; 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 196cdde1b42..fb597a5f1bf 100644 --- a/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js +++ b/imports/plugins/core/dashboard/client/templates/shop/settings/settings.js @@ -1,4 +1,7 @@ import _ from "lodash"; +import { Meteor } from "meteor/meteor"; +import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; import { Reaction, i18next } from "/client/api"; import { Media, Packages, Shops } from "/lib/collections"; diff --git a/imports/plugins/core/discounts/client/components/form.js b/imports/plugins/core/discounts/client/components/form.js index 82f9e38664d..8f9b5e09fa3 100644 --- a/imports/plugins/core/discounts/client/components/form.js +++ b/imports/plugins/core/discounts/client/components/form.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import debounce from "lodash/debounce"; import { Meteor } from "meteor/meteor"; import { Translation } from "/imports/plugins/core/ui/client/components"; @@ -22,9 +23,9 @@ export default class DiscountForm extends Component { if (typeof result === "object") { this.setState({ validationMessage: result }); } else if (result !== 1) { - // if validationMessage isn't an object with i18n - // we will display an elliptical that's not - // actually done here though, just bit of foolery + // if validationMessage isn't an object with i18n + // we will display an elliptical that's not + // actually done here though, just bit of foolery this.timerId = Meteor.setTimeout(function () { this.setState({ validationMessage: "..." }); }.bind(this), 2000); diff --git a/imports/plugins/core/discounts/client/components/list.js b/imports/plugins/core/discounts/client/components/list.js index d7ebb319d30..5b4b830bad5 100644 --- a/imports/plugins/core/discounts/client/components/list.js +++ b/imports/plugins/core/discounts/client/components/list.js @@ -1,4 +1,6 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Meteor } from "meteor/meteor"; import { Translation, IconButton } from "/imports/plugins/core/ui/client/components"; import DiscountForm from "./form"; import { composeWithTracker } from "/lib/api/compose"; diff --git a/imports/plugins/core/discounts/server/hooks/cart.js b/imports/plugins/core/discounts/server/hooks/cart.js index c4cfa203d80..91517ccc2d7 100644 --- a/imports/plugins/core/discounts/server/hooks/cart.js +++ b/imports/plugins/core/discounts/server/hooks/cart.js @@ -1,4 +1,5 @@ import { indexOf } from "lodash"; +import { Meteor } from "meteor/meteor"; import { Cart } from "/lib/collections"; /** diff --git a/imports/plugins/core/email/client/actions/logs.js b/imports/plugins/core/email/client/actions/logs.js index f387e3eee90..0e47f19ea54 100644 --- a/imports/plugins/core/email/client/actions/logs.js +++ b/imports/plugins/core/email/client/actions/logs.js @@ -1,3 +1,4 @@ +import { Meteor } from "meteor/meteor"; import { i18next } from "/client/api"; export default { diff --git a/imports/plugins/core/email/client/actions/settings.js b/imports/plugins/core/email/client/actions/settings.js index 7b9a380c73d..d95e0f7c6a6 100644 --- a/imports/plugins/core/email/client/actions/settings.js +++ b/imports/plugins/core/email/client/actions/settings.js @@ -1,3 +1,4 @@ +import { Meteor } from "meteor/meteor"; import Alert from "sweetalert2"; import { i18next } from "/client/api"; diff --git a/imports/plugins/core/email/client/components/emailConfig.js b/imports/plugins/core/email/client/components/emailConfig.js index f4644eee2c1..b6bb2999caf 100644 --- a/imports/plugins/core/email/client/components/emailConfig.js +++ b/imports/plugins/core/email/client/components/emailConfig.js @@ -1,5 +1,5 @@ -import React, { Component, PropTypes } from "react"; -import "./emailConfig.css"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Card, CardHeader, CardBody, CardGroup, Icon, Translation } from "/imports/plugins/core/ui/client/components"; import EmailSettings from "../containers/emailSettings"; @@ -44,7 +44,7 @@ class EmailConfig extends Component {
: {status ? - + : }
@@ -67,7 +67,7 @@ class EmailConfig extends Component { {showPassword ? - Hide + Hide : Show} diff --git a/imports/plugins/core/email/client/components/emailLogs.js b/imports/plugins/core/email/client/components/emailLogs.js index 9defc2ee9b4..0476c7ac7ac 100644 --- a/imports/plugins/core/email/client/components/emailLogs.js +++ b/imports/plugins/core/email/client/components/emailLogs.js @@ -1,16 +1,14 @@ -import React, { Component, PropTypes } from "react"; -import { Card, CardHeader, CardBody, CardGroup, Loading } from "/imports/plugins/core/ui/client/components"; -import MeteorGriddle from "/imports/plugins/core/ui-grid/client/griddle"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Card, CardHeader, CardBody, CardGroup, Loading, SortableTable } from "/imports/plugins/core/ui/client/components"; import EmailTableColumn from "./emailTableColumn"; import { Jobs } from "/lib/collections"; import { i18next } from "/client/api"; -import "./emailConfig.css"; class EmailLogs extends Component { renderEmailsTable() { const filteredFields = ["data.to", "updated", "data.subject", "status"]; - const filteredFieldsColumns = ["data.to", "updated", "data.subject", "status"]; const noDataMessage = i18next.t("admin.logs.noEmails"); // helper adds a class to every grid row @@ -23,25 +21,39 @@ class EmailLogs extends Component { // add i18n handling to headers const customColumnMetadata = []; filteredFields.forEach(function (field) { + let colWidth = undefined; + let colStyle = undefined; + let colClassName = undefined; + + if (field === "status") { + colWidth = 70; + colStyle = { textAlign: "center" }; + colClassName = "email-log-status"; + } + + // https://react-table.js.org/#/story/cell-renderers-custom-components const columnMeta = { - columnName: field, - displayName: i18next.t(`admin.logs.headers.${field}`), - customComponent: EmailTableColumn + accessor: field, + Header: i18next.t(`admin.logs.headers.${field}`), + Cell: row => ( + + ), + className: colClassName, + width: colWidth, + style: colStyle }; customColumnMetadata.push(columnMeta); }); return ( - - +
} {isSaving ? - + : Save} diff --git a/imports/plugins/core/email/client/components/emailTableColumn.js b/imports/plugins/core/email/client/components/emailTableColumn.js index fe8decab88c..5f2ffb0233e 100644 --- a/imports/plugins/core/email/client/components/emailTableColumn.js +++ b/imports/plugins/core/email/client/components/emailTableColumn.js @@ -1,21 +1,21 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Meteor } from "meteor/meteor"; import moment from "moment"; import { Icon } from "/imports/plugins/core/ui/client/components"; import { i18next } from "/client/api"; class EmailTableColumn extends Component { static propTypes = { - data: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.instanceOf(Date) - ]), - metadata: PropTypes.object, - rowData: PropTypes.object + data: PropTypes.object, + row: PropTypes.object } handleAction = () => { - const emailId = this.props.rowData._id; - const emailAddress = this.props.rowData.data.to; + const { row } = this.props; + + const emailId = row.original._id; + const emailAddress = row.original.data.to; Meteor.call("emails/retryFailed", emailId, (err) => { if (err) { @@ -26,33 +26,38 @@ class EmailTableColumn extends Component { } render() { - const renderColumn = this.props.metadata.columnName; + const { row } = this.props; + + const renderColumn = row.column.id; if (renderColumn === "status") { - if (this.props.data === "completed") { + if (row.value === "completed") { return ( - + + + + ); } return ( - + - + ); } if (renderColumn === "updated") { - const createdDate = moment(this.props.data).format("LLL"); + const createdDate = moment(row.value).format("LLL"); return ( {createdDate} ); } return ( - {this.props.data} + {row.value} ); } } diff --git a/imports/plugins/core/email/client/containers/emailConfig.js b/imports/plugins/core/email/client/containers/emailConfig.js index 30ab6673dff..39b371eb24f 100644 --- a/imports/plugins/core/email/client/containers/emailConfig.js +++ b/imports/plugins/core/email/client/containers/emailConfig.js @@ -1,3 +1,5 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { useDeps } from "react-simple-di"; import getServiceConfig from "nodemailer-wellknown"; import { Meteor } from "meteor/meteor"; @@ -7,6 +9,53 @@ import actions from "../actions"; import EmailConfig from "../components/emailConfig"; import { composeWithTracker, merge } from "/lib/api/compose"; +class EmailConfigContainer extends Component { + constructor(props) { + super(props); + + this.state = { + status: null, + error: null + }; + } + + componentWillMount() { + const { settings } = this.props; + const { service, host, port, user, password } = settings; + + if (service && host && port && user && password) { + Meteor.call("email/verifySettings", (error) => { + if (error) { + this.setState({ status: "error" }); + } + this.setState({ status: "valid" }); + }); + } else { + this.setState({ status: "error" }); + } + } + + render() { + const { status } = this.state; + return ( + + ); + } +} + +EmailConfigContainer.propTypes = { + settings: PropTypes.shape({ + host: PropTypes.string, + password: PropTypes.string, + port: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string + ]), + service: PropTypes.string, + user: PropTypes.string + }) +}; + const composer = ({}, onData) => { if (Meteor.subscribe("Packages", Reaction.getShopId()).ready()) { const shopSettings = Reaction.getShopSettings(); @@ -19,20 +68,7 @@ const composer = ({}, onData) => { settings.host = config.host || "localhost"; settings.port = config.port; } - - const { service, host, port, user, password } = settings; - - // if all settings exist, check if they work - if (service && host && port && user && password) { - Meteor.call("email/verifySettings", (error) => { - if (error) { - return onData(null, { settings, status: "error", error: error.reason }); - } - return onData(null, { settings, status: "valid", error: null }); - }); - } else { - onData(null, { settings, status: "error", error: null }); - } + return onData(null, { settings }); } }; @@ -43,4 +79,4 @@ const depsMapper = () => ({ export default merge( composeWithTracker(composer, Loading), useDeps(depsMapper) -)(EmailConfig); +)(EmailConfigContainer); diff --git a/imports/plugins/core/email/client/templates/email.js b/imports/plugins/core/email/client/templates/email.js index a766b3595aa..fa6fcb8b865 100644 --- a/imports/plugins/core/email/client/templates/email.js +++ b/imports/plugins/core/email/client/templates/email.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import EmailLogs from "../containers/emailLogs"; import EmailConfig from "../containers/emailConfig"; diff --git a/imports/plugins/core/i18n/client/components/localizationSettings.js b/imports/plugins/core/i18n/client/components/localizationSettings.js index 9cad856d937..5f98e821ff1 100644 --- a/imports/plugins/core/i18n/client/components/localizationSettings.js +++ b/imports/plugins/core/i18n/client/components/localizationSettings.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { CardGroup, CardToolbar, diff --git a/imports/plugins/core/layout/client/components/quickMenu.js b/imports/plugins/core/layout/client/components/quickMenu.js index cfe434f921f..f670598083a 100644 --- a/imports/plugins/core/layout/client/components/quickMenu.js +++ b/imports/plugins/core/layout/client/components/quickMenu.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Button } from "/imports/plugins/core/ui/client/components"; class QuickMenu extends Component { diff --git a/imports/plugins/core/layout/client/containers/adminContainer.js b/imports/plugins/core/layout/client/containers/adminContainer.js index fe77759c626..cdbda232c21 100644 --- a/imports/plugins/core/layout/client/containers/adminContainer.js +++ b/imports/plugins/core/layout/client/containers/adminContainer.js @@ -1,3 +1,4 @@ +import _ from "lodash"; import { composeWithTracker } from "/lib/api/compose"; import { Reaction } from "/client/api"; diff --git a/imports/plugins/core/layout/client/containers/quickMenuContainer.js b/imports/plugins/core/layout/client/containers/quickMenuContainer.js index 92c51ae7331..cd186fb96d7 100644 --- a/imports/plugins/core/layout/client/containers/quickMenuContainer.js +++ b/imports/plugins/core/layout/client/containers/quickMenuContainer.js @@ -1,4 +1,5 @@ -import React, { Component } from "component"; +import React, { Component } from "react"; +import _ from "lodash"; import { composeWithTracker } from "/lib/api/compose"; import { QuickMenu } from "../components"; import { Reaction } from "/client/api"; diff --git a/imports/plugins/core/layout/client/templates/layout/admin/admin.js b/imports/plugins/core/layout/client/templates/layout/admin/admin.js index 674b4729988..e9c77d5310b 100644 --- a/imports/plugins/core/layout/client/templates/layout/admin/admin.js +++ b/imports/plugins/core/layout/client/templates/layout/admin/admin.js @@ -1,6 +1,8 @@ +import _ from "lodash"; import Drop from "tether-drop"; import { Meteor } from "meteor/meteor"; import { Blaze } from "meteor/blaze"; +import { $ } from "meteor/jquery"; import { Template } from "meteor/templating"; import { Reaction, i18next } from "/client/api"; import { Packages } from "/lib/collections"; 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 c4bc8636b31..97afa63d485 100644 --- a/imports/plugins/core/layout/client/templates/layout/alerts/alerts.js +++ b/imports/plugins/core/layout/client/templates/layout/alerts/alerts.js @@ -1,4 +1,6 @@ import { Meteor } from "meteor/meteor"; +import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; import Alerts from "./inlineAlerts"; /** 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 eddf2f17556..24390c780b0 100644 --- a/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts.js +++ b/imports/plugins/core/layout/client/templates/layout/alerts/inlineAlerts.js @@ -1,3 +1,4 @@ +import _ from "lodash"; import { i18next } from "/client/api"; import { Mongo } from "meteor/mongo"; 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 069b8b9ee90..eb677caa0ce 100644 --- a/imports/plugins/core/layout/client/templates/layout/alerts/reactionAlerts.js +++ b/imports/plugins/core/layout/client/templates/layout/alerts/reactionAlerts.js @@ -1,3 +1,4 @@ +/* global sAlert */ import _ from "lodash"; import swal from "sweetalert2"; import { Meteor } from "meteor/meteor"; diff --git a/imports/plugins/core/layout/client/templates/layout/header/header.js b/imports/plugins/core/layout/client/templates/layout/header/header.js index 5f107b7983b..25c14747219 100644 --- a/imports/plugins/core/layout/client/templates/layout/header/header.js +++ b/imports/plugins/core/layout/client/templates/layout/header/header.js @@ -1,5 +1,5 @@ -import { Reaction } from "/client/api"; -import { Tags } from "/lib/collections"; +import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; /** * layoutHeader events @@ -16,10 +16,6 @@ Template.layoutHeader.events({ }); Template.layoutHeader.helpers({ - TagNav() { - return ReactionUI.TagNav.Components.TagNav; - }, - coreNavProps() { const instance = Template.instance(); return { @@ -27,27 +23,5 @@ Template.layoutHeader.helpers({ instance.toggleMenuCallback(); } }; - }, - - tagNavProps() { - const instance = Template.instance(); - - const tags = Tags.find({ - isTopLevel: true - }, { - sort: { - position: 1 - } - }).fetch(); - - return { - name: "coreHeaderNavigation", - editable: Reaction.hasAdminAccess(), - tags: tags, - onToggleMenu(callback) { - // Register the callback - instance.toggleMenuCallback = callback; - } - }; } }); diff --git a/imports/plugins/core/layout/client/templates/theme/theme.js b/imports/plugins/core/layout/client/templates/theme/theme.js index 91590969e91..5e5a2e6f32b 100644 --- a/imports/plugins/core/layout/client/templates/theme/theme.js +++ b/imports/plugins/core/layout/client/templates/theme/theme.js @@ -1,5 +1,7 @@ import { Meteor } from "meteor/meteor"; import { Tracker } from "meteor/tracker"; +import { Session } from "meteor/session"; +import { $ } from "meteor/jquery"; import { Reaction, Router } from "/client/api"; import { Packages, Shops } from "/lib/collections"; diff --git a/imports/plugins/core/layout/lib/blazeLayout.js b/imports/plugins/core/layout/lib/blazeLayout.js index 97fe4217964..628afd94cc4 100644 --- a/imports/plugins/core/layout/lib/blazeLayout.js +++ b/imports/plugins/core/layout/lib/blazeLayout.js @@ -1,4 +1,5 @@ import ReactDOM from "react-dom"; +import _ from "lodash"; import { Blaze } from "meteor/blaze"; import { ReactiveVar } from "meteor/reactive-var"; import { Template } from "meteor/templating"; diff --git a/imports/plugins/core/layout/lib/layouts.js b/imports/plugins/core/layout/lib/layouts.js index 0ee053a9db9..f3446789ec1 100644 --- a/imports/plugins/core/layout/lib/layouts.js +++ b/imports/plugins/core/layout/lib/layouts.js @@ -1,4 +1,5 @@ import { Import } from "/server/api/core/import"; +import { Shops } from "/lib/collections"; export function registerLayout(layout) { Shops.find().forEach((shop) => { diff --git a/imports/plugins/core/layout/lib/reactionLayout.js b/imports/plugins/core/layout/lib/reactionLayout.js index 27affa2486c..c5b9a6b938f 100644 --- a/imports/plugins/core/layout/lib/reactionLayout.js +++ b/imports/plugins/core/layout/lib/reactionLayout.js @@ -1,5 +1,7 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Radium from "radium"; +import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "/lib/api/compose"; import { Reaction } from "/client/api"; import classnames from "classnames"; @@ -8,7 +10,6 @@ import { Templates } from "/lib/collections"; import { Loading } from "/imports/plugins/core/ui/client/components"; class ReactionLayout extends Component { - get layout() { return this.props.layout; } @@ -88,9 +89,9 @@ class ReactionLayout extends Component { render() { return ( -
- {this.renderLayout(this.layout)} -
+
+ {this.renderLayout(this.layout)} +
); } } diff --git a/imports/plugins/core/layout/server/methods/index.js b/imports/plugins/core/layout/server/methods/index.js index efe67079c23..e8b832b972c 100644 --- a/imports/plugins/core/layout/server/methods/index.js +++ b/imports/plugins/core/layout/server/methods/index.js @@ -1,3 +1,4 @@ +import { Meteor } from "meteor/meteor"; import { getTemplateByName } from "./templates"; export function registerMethods() { diff --git a/imports/plugins/core/layout/server/publications/templates.js b/imports/plugins/core/layout/server/publications/templates.js index ae0c4134d73..cf3a30e25b5 100644 --- a/imports/plugins/core/layout/server/publications/templates.js +++ b/imports/plugins/core/layout/server/publications/templates.js @@ -1,5 +1,7 @@ -import { Reaction } from "/server/api"; import { Meteor } from "meteor/meteor"; +import { check, Match } from "meteor/check"; +import { Counts } from "meteor/tmeasday:publish-counts"; +import { Reaction } from "/server/api"; import { Templates } from "/lib/collections"; Meteor.publish("Templates", function (query, options) { diff --git a/imports/plugins/core/logging/server/methods.js b/imports/plugins/core/logging/server/methods.js index 2f4e894fe32..afa9a93f47e 100644 --- a/imports/plugins/core/logging/server/methods.js +++ b/imports/plugins/core/logging/server/methods.js @@ -1,4 +1,6 @@ import { Meteor } from "meteor/meteor"; +import { Roles } from "meteor/alanning:roles"; +import { check } from "meteor/check"; import { Logs } from "/lib/collections"; import { Reaction } from "/server/api"; diff --git a/imports/plugins/core/orders/client/components/invoice.js b/imports/plugins/core/orders/client/components/invoice.js index 83918a30faf..c29116cbfbe 100644 --- a/imports/plugins/core/orders/client/components/invoice.js +++ b/imports/plugins/core/orders/client/components/invoice.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { formatPriceString } from "/client/api"; import { Translation } from "/imports/plugins/core/ui/client/components"; import DiscountList from "/imports/plugins/core/discounts/client/components/list"; @@ -26,11 +27,11 @@ class Invoice extends Component { {isOpen &&

- +
} diff --git a/imports/plugins/core/orders/client/components/invoiceActions.js b/imports/plugins/core/orders/client/components/invoiceActions.js index ce6dc2300cf..1b135a7e3dc 100644 --- a/imports/plugins/core/orders/client/components/invoiceActions.js +++ b/imports/plugins/core/orders/client/components/invoiceActions.js @@ -1,9 +1,9 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; 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, @@ -53,12 +53,12 @@ class InvoiceActions extends Component {
- +
- {uniqueItem.title}
{uniqueItem.variants.title} + {uniqueItem.title}
{uniqueItem.variants.title}
- {quantity || uniqueItem.quantity} + {quantity || uniqueItem.quantity}
@@ -52,8 +52,8 @@ class LineItems extends Component {
+ - ); } @@ -95,7 +95,7 @@ class LineItems extends Component { {this.calculateTotal(uniqueItem.variants.price, uniqueItem.shipping.rate, uniqueItem.taxDetail.tax)} : - + {this.calculateTotal(uniqueItem.variants.price, uniqueItem.shipping.rate, 0)} } @@ -139,7 +139,7 @@ class LineItems extends Component { )} - + ); })} diff --git a/imports/plugins/core/orders/client/components/orderActions.js b/imports/plugins/core/orders/client/components/orderActions.js index 77d6140607e..07cd88b24a6 100644 --- a/imports/plugins/core/orders/client/components/orderActions.js +++ b/imports/plugins/core/orders/client/components/orderActions.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Radium from "radium"; import { TabList, TabItem } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/orders/client/components/orderSummary.js b/imports/plugins/core/orders/client/components/orderSummary.js index 12f0e82b4e5..ee8b301182f 100644 --- a/imports/plugins/core/orders/client/components/orderSummary.js +++ b/imports/plugins/core/orders/client/components/orderSummary.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import moment from "moment"; import { Badge, ClickToCopy } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/orders/client/components/ordersList.js b/imports/plugins/core/orders/client/components/ordersList.js index 3827893d5a3..15892eb0fbd 100644 --- a/imports/plugins/core/orders/client/components/ordersList.js +++ b/imports/plugins/core/orders/client/components/ordersList.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames/dedupe"; import Avatar from "react-avatar"; import moment from "moment"; @@ -7,7 +8,6 @@ import { Badge, ClickToCopy, Icon, Translation } from "@reactioncommerce/reactio import ProductImage from "./productImage"; class OrdersList extends Component { - static propTypes = { displayMedia: PropTypes.func, handleClick: PropTypes.func, @@ -38,7 +38,6 @@ class OrdersList extends Component { /** * 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() { @@ -46,14 +45,17 @@ class OrdersList extends Component { } renderOrderButton(order) { + const startWorkflow = order.workflow.status === "new"; const classes = classnames({ "rui": true, "btn": true, - "btn-success": order.workflow.status === "new" + "btn-success": startWorkflow }); return ( - + ); } @@ -70,12 +72,12 @@ class OrdersList extends Component { Order ID: - + @@ -115,7 +117,7 @@ class OrdersList extends Component { size={30} className="rui-order-avatar" /> - {order.shipping[0].address.fullName} | {emailAddress} + {order.shipping[0].address.fullName} | {emailAddress}
- {this.renderBadge()} + {this.renderBadge()}
); } diff --git a/imports/plugins/core/orders/client/components/totalActions.js b/imports/plugins/core/orders/client/components/totalActions.js index 1430414b633..72c15ccee27 100644 --- a/imports/plugins/core/orders/client/components/totalActions.js +++ b/imports/plugins/core/orders/client/components/totalActions.js @@ -1,8 +1,8 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { formatPriceString } from "/client/api"; class TotalActions extends Component { - static propTypes = { adjustedTotal: PropTypes.number, invoice: PropTypes.object, diff --git a/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js b/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js index 9a6e24936c8..69ca603504d 100644 --- a/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js +++ b/imports/plugins/core/orders/client/containers/invoiceActionsContainer.js @@ -1,10 +1,10 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; 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, diff --git a/imports/plugins/core/orders/client/containers/invoiceContainer.js b/imports/plugins/core/orders/client/containers/invoiceContainer.js index 0f449c30adb..97866f4aea1 100644 --- a/imports/plugins/core/orders/client/containers/invoiceContainer.js +++ b/imports/plugins/core/orders/client/containers/invoiceContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import moment from "moment"; import { composeWithTracker } from "/lib/api/compose"; import { Loading } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/orders/client/containers/lineItemsContainer.js b/imports/plugins/core/orders/client/containers/lineItemsContainer.js index 1af86d3cb91..18178ce7a49 100644 --- a/imports/plugins/core/orders/client/containers/lineItemsContainer.js +++ b/imports/plugins/core/orders/client/containers/lineItemsContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "/lib/api/compose"; import { Media } from "/lib/collections"; diff --git a/imports/plugins/core/orders/client/containers/orderSummaryContainer.js b/imports/plugins/core/orders/client/containers/orderSummaryContainer.js index fad8ced9149..f61b133e4c4 100644 --- a/imports/plugins/core/orders/client/containers/orderSummaryContainer.js +++ b/imports/plugins/core/orders/client/containers/orderSummaryContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import moment from "moment"; import _ from "lodash"; import { Meteor } from "meteor/meteor"; @@ -113,7 +114,7 @@ class OrderSummaryContainer extends Component { i18nKeyTitle="admin.orderWorkflow.summary.cardTitle" title="Summary" /> - + { + handleClick = (order, startWorkflow = false) => { Reaction.setActionViewDetail({ label: "Order Details", i18nKeyLabel: "orderWorkflow.orderDetails", @@ -42,8 +43,9 @@ class OrdersListContainer extends Component { 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); } + + Reaction.setUserPreferences(PACKAGE_NAME, ORDER_LIST_SELECTED_ORDER_PREFERENCE_NAME, order._id); } /** @@ -79,11 +81,11 @@ class OrdersListContainer extends Component { const { orders } = this.props; return ( - + ); } } diff --git a/imports/plugins/core/orders/client/containers/totalActionsContainer.js b/imports/plugins/core/orders/client/containers/totalActionsContainer.js index a32c8f316c4..6d4bfc15337 100644 --- a/imports/plugins/core/orders/client/containers/totalActionsContainer.js +++ b/imports/plugins/core/orders/client/containers/totalActionsContainer.js @@ -1,10 +1,10 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { composeWithTracker } from "/lib/api/compose"; import TotalActions from "../components/totalActions"; import { Loading } from "/imports/plugins/core/ui/client/components"; class TotalActionsContaner extends Component { - static propTypes = { adjustedTotal: PropTypes.number, invoice: PropTypes.object, diff --git a/imports/plugins/core/orders/client/templates/list/items.js b/imports/plugins/core/orders/client/templates/list/items.js index 154adc8f9b7..ecc075632e2 100644 --- a/imports/plugins/core/orders/client/templates/list/items.js +++ b/imports/plugins/core/orders/client/templates/list/items.js @@ -1,4 +1,5 @@ import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; import { Media } from "/lib/collections"; /** diff --git a/imports/plugins/core/orders/client/templates/orders.js b/imports/plugins/core/orders/client/templates/orders.js index 7417411c121..067c3e47c3a 100644 --- a/imports/plugins/core/orders/client/templates/orders.js +++ b/imports/plugins/core/orders/client/templates/orders.js @@ -1,5 +1,7 @@ import _ from "lodash"; import { Template } from "meteor/templating"; +import { ReactiveDict } from "meteor/reactive-dict"; +import { Counts } from "meteor/tmeasday:publish-counts"; import { Reaction } from "/client/api"; import { Orders, Shops } from "/lib/collections"; import OrdersActionContainer from "../containers/ordersActionContainer"; diff --git a/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js b/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js index 8993d916ba6..f83e9186c26 100644 --- a/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js +++ b/imports/plugins/core/orders/client/templates/workflow/shippingInvoice.js @@ -4,6 +4,7 @@ import { Meteor } from "meteor/meteor"; import $ from "jquery"; import { Template } from "meteor/templating"; import { ReactiveVar } from "meteor/reactive-var"; +import { ReactiveDict } from "meteor/reactive-dict"; import { i18next, Logger, formatNumber, Reaction } from "/client/api"; import { NumericInput } from "/imports/plugins/core/ui/client/components"; import { Orders, Shops, Packages } from "/lib/collections"; @@ -544,7 +545,7 @@ Template.coreOrderShippingInvoice.helpers({ shipment() { const instance = Template.instance(); const order = instance.state.get("order"); - + const currentData = Template.currentData(); const shipment = _.filter(order.shipping, { _id: currentData.fulfillment._id })[0]; return shipment; diff --git a/imports/plugins/core/orders/client/templates/workflow/shippingTracking.js b/imports/plugins/core/orders/client/templates/workflow/shippingTracking.js index d688335393b..03ef216c075 100644 --- a/imports/plugins/core/orders/client/templates/workflow/shippingTracking.js +++ b/imports/plugins/core/orders/client/templates/workflow/shippingTracking.js @@ -1,6 +1,7 @@ import _ from "lodash"; import { Meteor } from "meteor/meteor"; import { Tracker } from "meteor/tracker"; +import { ReactiveVar } from "meteor/reactive-var"; import { Template } from "meteor/templating"; import { i18next, Reaction } from "/client/api"; import { Orders } from "/lib/collections"; diff --git a/imports/plugins/core/orders/server/startup.js b/imports/plugins/core/orders/server/startup.js index 2bf9c2b2ca0..efbaae87891 100644 --- a/imports/plugins/core/orders/server/startup.js +++ b/imports/plugins/core/orders/server/startup.js @@ -1,3 +1,4 @@ +import { Meteor } from "meteor/meteor"; import { AnalyticsEvents, Orders } from "/lib/collections"; diff --git a/imports/plugins/core/payments/client/settings/settings.js b/imports/plugins/core/payments/client/settings/settings.js index 52bbd1ad13d..ab4f71e1eb9 100644 --- a/imports/plugins/core/payments/client/settings/settings.js +++ b/imports/plugins/core/payments/client/settings/settings.js @@ -1,4 +1,7 @@ +import _ from "lodash"; +import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; import { Reaction, i18next } from "/client/api"; import { Shops } from "/lib/collections"; diff --git a/imports/plugins/core/revisions/client/components/publishControls.js b/imports/plugins/core/revisions/client/components/publishControls.js index 9a73cfe8800..ad04faf3e12 100644 --- a/imports/plugins/core/revisions/client/components/publishControls.js +++ b/imports/plugins/core/revisions/client/components/publishControls.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Button, FlatButton, diff --git a/imports/plugins/core/revisions/client/components/settings.js b/imports/plugins/core/revisions/client/components/settings.js index 25174a1c536..9b6f7c4a11a 100644 --- a/imports/plugins/core/revisions/client/components/settings.js +++ b/imports/plugins/core/revisions/client/components/settings.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Translation } from "/imports/plugins/core/ui/client/components"; @@ -23,7 +24,7 @@ class RevisionControlSettings extends Component { defaultValue="Revision controls is disabled" i18nKey="revisions.isDisabled" /> - ); + ); } return ( diff --git a/imports/plugins/core/revisions/client/components/simpleDiff.js b/imports/plugins/core/revisions/client/components/simpleDiff.js index 5507312559d..bb44814414d 100644 --- a/imports/plugins/core/revisions/client/components/simpleDiff.js +++ b/imports/plugins/core/revisions/client/components/simpleDiff.js @@ -1,7 +1,7 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; class SimpleDiff extends Component { - renderDiff() { const diff = this.props.diff; diff --git a/imports/plugins/core/revisions/client/containers/publishContainer.js b/imports/plugins/core/revisions/client/containers/publishContainer.js index 2b103968eca..9e6345e44ca 100644 --- a/imports/plugins/core/revisions/client/containers/publishContainer.js +++ b/imports/plugins/core/revisions/client/containers/publishContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { composeWithTracker } from "/lib/api/compose"; import PublishControls from "../components/publishControls"; import { Revisions } from "/lib/collections"; diff --git a/imports/plugins/core/revisions/client/containers/settingsContainer.js b/imports/plugins/core/revisions/client/containers/settingsContainer.js index e3b7c453a61..26de206ecb0 100644 --- a/imports/plugins/core/revisions/client/containers/settingsContainer.js +++ b/imports/plugins/core/revisions/client/containers/settingsContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { composeWithTracker } from "/lib/api/compose"; import SettingsComponent from "../components/settings"; import { Packages } from "/lib/collections"; @@ -33,11 +34,9 @@ class RevisionSettingsContainer extends Component { /** * Publish container is a stateless container component connected to Meteor data source. - * @param {Object} props Component props * @return {PropTypes.node} react node */ render() { - // console.log(this.props.packageInfo); return (
diff --git a/imports/plugins/core/revisions/client/templates/settings.js b/imports/plugins/core/revisions/client/templates/settings.js index 04aa9c0d671..b12d8df528c 100644 --- a/imports/plugins/core/revisions/client/templates/settings.js +++ b/imports/plugins/core/revisions/client/templates/settings.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import SearchContainer from "../containers/settingsContainer.js"; Template.revisionControlSettings.helpers({ diff --git a/imports/plugins/core/revisions/server/hooks.js b/imports/plugins/core/revisions/server/hooks.js index 134fa54c83e..f6ca50d652f 100644 --- a/imports/plugins/core/revisions/server/hooks.js +++ b/imports/plugins/core/revisions/server/hooks.js @@ -1,5 +1,6 @@ import _ from "lodash"; import { diff } from "deep-diff"; +import { Meteor } from "meteor/meteor"; import { Products, Revisions, Tags, Media } from "/lib/collections"; import { Logger } from "/server/api"; import { RevisionApi } from "../lib/api"; @@ -159,7 +160,7 @@ export const ProductRevision = { const options = this.getVariants(variant._id); if (options && options.length) { return options.reduce((sum, option) => - sum + option.inventoryQuantity || 0, 0); + sum + option.inventoryQuantity || 0, 0); } return variant.inventoryQuantity || 0; } @@ -514,7 +515,7 @@ Products.before.update(function (userId, product, fieldNames, modifier, options) // If the new handle is going to be empty, the handle becomes the sligified product title, or document id if title does not exist. if (_.isEmpty(newValue)) { - revisionModifier.$set["documentData.handle"] = hasExistingTitle ? getSlug(revisionTitle) : documentId; + revisionModifier.$set["documentData.handle"] = hasExistingTitle ? getSlug(revisionTitle) : productRevision.documentId; } } else { // Let everything else through diff --git a/imports/plugins/core/revisions/server/publications.js b/imports/plugins/core/revisions/server/publications.js index cb3456973dc..193bfb85419 100644 --- a/imports/plugins/core/revisions/server/publications.js +++ b/imports/plugins/core/revisions/server/publications.js @@ -1,4 +1,8 @@ +import { Meteor } from "meteor/meteor"; +import { check } from "meteor/check"; +import { Roles } from "meteor/alanning:roles"; import { Revisions } from "/lib/collections"; +import { Reaction } from "/server/api"; /** * products publication @@ -9,6 +13,7 @@ import { Revisions } from "/lib/collections"; Meteor.publish("ProductRevisions", function (productIds) { check(productIds, Array); + const shop = Reaction.getShopId(); // Authorized content curators fo the shop get special publication of the product // all all relevant revisions all is one package if (Roles.userIsInRole(this.userId, ["owner", "admin", "createProduct"], shop._id)) { diff --git a/imports/plugins/core/router/client/app.js b/imports/plugins/core/router/client/app.js index 620a676c3de..a1d48aa0b90 100644 --- a/imports/plugins/core/router/client/app.js +++ b/imports/plugins/core/router/client/app.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Reaction, Router } from "/client/api"; import { composeWithTracker } from "/lib/api/compose"; diff --git a/imports/plugins/core/router/client/browserRouter.js b/imports/plugins/core/router/client/browserRouter.js index 63d72b7a1ec..2aeddd22a1a 100644 --- a/imports/plugins/core/router/client/browserRouter.js +++ b/imports/plugins/core/router/client/browserRouter.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import ReactDOM from "react-dom"; import { matchPath } from "react-router"; import { Router as ReactRouter } from "react-router-dom"; diff --git a/imports/plugins/core/router/client/startup.js b/imports/plugins/core/router/client/startup.js index 4c5575d5467..6dddb4e67e6 100644 --- a/imports/plugins/core/router/client/startup.js +++ b/imports/plugins/core/router/client/startup.js @@ -1,5 +1,6 @@ import { Meteor } from "meteor/meteor"; import { Tracker } from "meteor/tracker"; +import { Accounts } from "meteor/accounts-base"; import { Reaction } from "/client/api"; import { initBrowserRouter } from "./browserRouter"; import { Router } from "../lib"; diff --git a/imports/plugins/core/router/lib/router.js b/imports/plugins/core/router/lib/router.js index a167f4dbac4..b59828debcd 100644 --- a/imports/plugins/core/router/lib/router.js +++ b/imports/plugins/core/router/lib/router.js @@ -8,6 +8,9 @@ import Immutable from "immutable"; import { uniqBy } from "lodash"; import { Meteor } from "meteor/meteor"; import Blaze from "meteor/gadicc:blaze-react-component"; +import { Template } from "meteor/templating"; +import { Session } from "meteor/session"; +import { Counts } from "meteor/tmeasday:publish-counts"; import { Tracker } from "meteor/tracker"; import { Packages, Shops } from "/lib/collections"; import { getComponent } from "/imports/plugins/core/layout/lib/components"; @@ -125,7 +128,6 @@ Router.pathFor = (path, options = {}) => { // return Router.path(path, params, query); const foundPath = Router.routes.find((pathObject) => { - // console.log(pathObject.options.name, path); if (pathObject.options.name === path) { return true; } @@ -443,7 +445,7 @@ Router.initPackageRoutes = (options) => { Tracker.autorun(shopSubWaitFor => { if (shopSub.ready()) { shopSubWaitFor.stop(); - // using tmeasday:publish-counts + // using tmeasday:publish-counts const shopCount = Counts.get("shops-count"); // Default layouts diff --git a/imports/plugins/core/shipping/client/templates/settings/shipping.js b/imports/plugins/core/shipping/client/templates/settings/shipping.js index c08cdd857b5..7be5b4009a0 100644 --- a/imports/plugins/core/shipping/client/templates/settings/shipping.js +++ b/imports/plugins/core/shipping/client/templates/settings/shipping.js @@ -1,4 +1,5 @@ import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; /* * Template shippinges Helpers */ diff --git a/imports/plugins/core/taxes/client/settings/custom.js b/imports/plugins/core/taxes/client/settings/custom.js index 04171ac4909..394ee52c449 100644 --- a/imports/plugins/core/taxes/client/settings/custom.js +++ b/imports/plugins/core/taxes/client/settings/custom.js @@ -1,4 +1,5 @@ import { Meteor } from "meteor/meteor"; +import { $ } from "meteor/jquery"; import { Template } from "meteor/templating"; import { ReactiveDict } from "meteor/reactive-dict"; import { AutoForm } from "meteor/aldeed:autoform"; @@ -7,8 +8,7 @@ import { Countries } from "/client/collections"; import { Taxes, TaxCodes } from "../../lib/collections"; import { i18next } from "/client/api"; import { Taxes as TaxSchema } from "../../lib/collections/schemas"; -import MeteorGriddle from "/imports/plugins/core/ui-grid/client/griddle"; -import { IconButton, Loading } from "/imports/plugins/core/ui/client/components"; +import { IconButton, Loading, SortableTable } from "/imports/plugins/core/ui/client/components"; /* eslint no-shadow: ["error", { "allow": ["options"] }] */ /* eslint no-unused-vars: ["error", { "argsIgnorePattern": "[oO]ptions" }] */ @@ -91,20 +91,19 @@ Template.customTaxRates.helpers({ const customColumnMetadata = []; filteredFields.forEach(function (field) { const columnMeta = { - columnName: field, - displayName: i18next.t(`admin.taxGrid.${field}`) + accessor: field, + Header: i18next.t(`admin.taxGrid.${field}`) }; customColumnMetadata.push(columnMeta); }); // return tax Grid return { - component: MeteorGriddle, + component: SortableTable, publication: "Taxes", collection: Taxes, matchingResultsCount: "taxes-count", showFilter: true, - useGriddleStyles: false, rowMetadata: customRowMetaData, filteredFields: filteredFields, columns: filteredFields, diff --git a/imports/plugins/core/taxes/client/settings/settings.js b/imports/plugins/core/taxes/client/settings/settings.js index 3db4b49faa6..2340c6ff630 100644 --- a/imports/plugins/core/taxes/client/settings/settings.js +++ b/imports/plugins/core/taxes/client/settings/settings.js @@ -1,3 +1,4 @@ +import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; import { TaxCodes } from "../../lib/collections"; import { i18next } from "/client/api"; diff --git a/imports/plugins/core/taxes/server/hooks/taxes.js b/imports/plugins/core/taxes/server/hooks/taxes.js index a49ccdaceb4..9b641856880 100644 --- a/imports/plugins/core/taxes/server/hooks/taxes.js +++ b/imports/plugins/core/taxes/server/hooks/taxes.js @@ -1,4 +1,5 @@ import { indexOf } from "lodash"; +import { Meteor } from "meteor/meteor"; import { Cart } from "/lib/collections"; /** diff --git a/imports/plugins/core/taxes/server/publications/taxes.js b/imports/plugins/core/taxes/server/publications/taxes.js index 43d24f63044..f774129eeb5 100644 --- a/imports/plugins/core/taxes/server/publications/taxes.js +++ b/imports/plugins/core/taxes/server/publications/taxes.js @@ -1,5 +1,6 @@ import { Meteor } from "meteor/meteor"; import { Match, check } from "meteor/check"; +import { Security } from "meteor/ongoworks:security"; import { Counts } from "meteor/tmeasday:publish-counts"; import { Taxes, TaxCodes } from "../../lib/collections"; import { Reaction } from "/server/api"; diff --git a/imports/plugins/core/templates/client/templates/settings.js b/imports/plugins/core/templates/client/templates/settings.js index 104cf67e9eb..7c14111937d 100644 --- a/imports/plugins/core/templates/client/templates/settings.js +++ b/imports/plugins/core/templates/client/templates/settings.js @@ -1,10 +1,10 @@ -import MeteorGriddle from "/imports/plugins/core/ui-grid/client/griddle"; -import { Loading } from "/imports/plugins/core/ui/client/components"; +import { $ } from "meteor/jquery"; import { Meteor } from "meteor/meteor"; import { AutoForm } from "meteor/aldeed:autoform"; import { Blaze } from "meteor/blaze"; import { ReactiveDict } from "meteor/reactive-dict"; import { Template } from "meteor/templating"; +import { Loading, SortableTable } from "/imports/plugins/core/ui/client/components"; import { EmailTemplates } from "../../lib/collections/schemas"; import { i18next } from "/client/api"; import { Templates } from "/lib/collections"; @@ -65,20 +65,19 @@ Template.templateSettings.helpers({ const customColumnMetadata = []; filteredFields.forEach(function (field) { const columnMeta = { - columnName: field, - displayName: i18next.t(`templateGrid.columns.${field}`) + accessor: field, // name of field + Header: i18next.t(`templateGrid.columns.${field}`) // name to display }; customColumnMetadata.push(columnMeta); }); // return template Grid return { - component: MeteorGriddle, + component: SortableTable, publication: "Templates", collection: Templates, matchingResultsCount: "templates-count", showFilter: true, - useGriddleStyles: false, rowMetadata: customRowMetaData, filteredFields: filteredFields, columns: filteredFields, @@ -134,13 +133,12 @@ Template.templateSettings.events({ }); }, "click .cancel, .template-grid-row .active": function () { - instance = Template.instance(); + const instance = Template.instance(); // remove active rows from grid instance.state.set({ isEditing: false, editingId: null }); - // ugly hack $(".template-grid-row").removeClass("active"); } }); diff --git a/imports/plugins/core/templates/register.js b/imports/plugins/core/templates/register.js index b36400094cc..34537564fcb 100644 --- a/imports/plugins/core/templates/register.js +++ b/imports/plugins/core/templates/register.js @@ -27,7 +27,12 @@ Reaction.registerPackage({ icon: "fa fa-columns", name: "templates/settings", provides: "settings", - template: "templateSettings" + template: "templateSettings", + meta: { + actionView: { + dashboardSize: "md" + } + } }, { label: "Email Templates", diff --git a/imports/plugins/core/templates/server/methods.js b/imports/plugins/core/templates/server/methods.js index 0da3cbbafd7..507dbe4c087 100644 --- a/imports/plugins/core/templates/server/methods.js +++ b/imports/plugins/core/templates/server/methods.js @@ -1,3 +1,5 @@ +import { Meteor } from "meteor/meteor"; +import { check } from "meteor/check"; import { Templates } from "/lib/collections"; export const methods = { diff --git a/imports/plugins/core/ui-grid/client/griddle.js b/imports/plugins/core/ui-grid/client/griddle.js deleted file mode 100644 index ccef8e0d832..00000000000 --- a/imports/plugins/core/ui-grid/client/griddle.js +++ /dev/null @@ -1,154 +0,0 @@ -/* -Forked from https://github.com/meteor-utilities/Meteor-Griddle - */ -import React from "react"; -import _ from "lodash"; -import Griddle from "griddle-react"; -import { Counts } from "meteor/tmeasday:publish-counts"; -import { ReactMeteorData } from "meteor/react-meteor-data"; - -/* eslint react/prop-types:0, react/jsx-sort-props:0, react/forbid-prop-types: 0, "react/prefer-es6-class": [1, "never"] */ - -const MeteorGriddle = React.createClass({ - propTypes: { - collection: React.PropTypes.object, // the collection to display - filteredFields: React.PropTypes.array, // an array of fields to search through when filtering - matchingResultsCount: React.PropTypes.string, // the name of the matching results counter - publication: React.PropTypes.string, // the publication that will provide the data - subsManager: React.PropTypes.object, // subsManager sub - transform: React.PropTypes.func // external function to filter result source - }, - mixins: [ReactMeteorData], - - getDefaultProps() { - return { useExternal: false, externalFilterDebounceWait: 300, externalResultsPerPage: 10, query: {} }; - }, - - getInitialState() { - return { - currentPage: 0, - maxPages: 0, - externalResultsPerPage: this.props.externalResultsPerPage, - externalSortColumn: this.props.externalSortColumn, - externalSortAscending: this.props.externalSortAscending, - query: {} - }; - }, - - componentWillMount() { - this.applyQuery = _.debounce((query) => { - this.setState({ query }); - }, this.props.externalFilterDebounceWait); - }, - - getMeteorData() { - // Get a count of the number of items matching the current filter. If no filter is set it will return the total number - // of items in the collection. - const matchingResults = Counts.get(this.props.matchingResultsCount); - - const options = {}; - let skip; - if (this.props.useExternal) { - options.limit = this.state.externalResultsPerPage; - if (!_.isEmpty(this.state.query) && !!matchingResults) { - // if necessary, limit the cursor to number of matching results to avoid displaying results from other publications - options.limit = _.min([options.limit, matchingResults]); - } - options.sort = { - [this.state.externalSortColumn]: (this.state.externalSortAscending - ? 1 - : -1) - }; - skip = this.state.currentPage * this.state.externalResultsPerPage; - } - - let pubHandle; - - if (this.props.subsManager) { - pubHandle = this.props.subsManager.subscribe(this.props.publication, this.state.query, _.extend({ - skip: skip - }, options)); - } else { - pubHandle = Meteor.subscribe(this.props.publication, this.state.query, _.extend({ - skip: skip - }, options)); - } - - // optional transform of collection for grid results - let results = this.props.collection.find(this.state.query, options).fetch(); - if (this.props.transform) { - results = this.props.transform(results); - } - - return { - loading: !pubHandle.ready(), - results: results, - matchingResults: matchingResults - }; - }, - - resetQuery() { - this.setState({ query: {} }); - }, - - // what page is currently viewed - setPage(index) { - this.setState({ currentPage: index }); - }, - - // this changes whether data is sorted in ascending or descending order - changeSort(sort, sortAscending) { - this.setState({ externalSortColumn: sort, externalSortAscending: sortAscending }); - }, - - setFilter(filter) { - if (filter) { - const filteredFields = this.props.filteredFields || this.props.columns; - const orArray = filteredFields.map((field) => { - const filterItem = {}; - filterItem[field] = { - $regex: filter, - $options: "i" - }; - return filterItem; - }); - this.applyQuery({ $or: orArray }); - } else { - this.resetQuery(); - } - }, - - // this method handles determining the page size - setPageSize(size) { - this.setState({ externalResultsPerPage: size }); - }, - - render() { - // figure out how many pages we have based on the number of total results matching the cursor - const maxPages = Math.ceil(this.data.matchingResults / this.state.externalResultsPerPage); - - // The Griddle externalIsLoading property is managed internally to line up with the subscription ready state, so we're - // removing this property if it's passed in. - const allProps = this.props; - delete allProps.externalIsLoading; - - return (); - } -}); - -export default MeteorGriddle; diff --git a/imports/plugins/core/ui-grid/client/index.js b/imports/plugins/core/ui-grid/client/index.js deleted file mode 100644 index 7d935878c0e..00000000000 --- a/imports/plugins/core/ui-grid/client/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./griddle.js"; diff --git a/imports/plugins/core/ui-grid/register.js b/imports/plugins/core/ui-grid/register.js deleted file mode 100644 index 617c821d08a..00000000000 --- a/imports/plugins/core/ui-grid/register.js +++ /dev/null @@ -1,7 +0,0 @@ -import { Reaction } from "/server/api"; - -Reaction.registerPackage({ - label: "UI Grid", - name: "reaction-ui-grid", - autoEnable: true -}); diff --git a/imports/plugins/core/ui-grid/server/i18n/en.json b/imports/plugins/core/ui-grid/server/i18n/en.json deleted file mode 100644 index 58bb3409984..00000000000 --- a/imports/plugins/core/ui-grid/server/i18n/en.json +++ /dev/null @@ -1,13 +0,0 @@ -[{ - "i18n": "en", - "ns": "reaction-ui-grid", - "translation": { - "reaction-ui-grid": { - "admin": { - "shortcut": {}, - "dashboard": {}, - "settings": {} - } - } - } -}] diff --git a/imports/plugins/core/ui-grid/server/i18n/index.js b/imports/plugins/core/ui-grid/server/i18n/index.js deleted file mode 100644 index 3f6a8d87fb9..00000000000 --- a/imports/plugins/core/ui-grid/server/i18n/index.js +++ /dev/null @@ -1,32 +0,0 @@ -import { loadTranslations } from "/server/startup/i18n"; - -// import ar from "./ar.json"; -// import bg from "./bg.json"; -// import de from "./de.json"; -// import el from "./el.json"; -import en from "./en.json"; -// import es from "./es.json"; -// import fr from "./fr.json"; -// import he from "./he.json"; -// import hr from "./hr.json"; -// import it from "./it.json"; -// import my from "./my.json"; -// import nb from "./nb.json"; -// import nl from "./nl.json"; -// import pl from "./pl.json"; -// import pt from "./pt.json"; -// import ro from "./ro.json"; -// import ru from "./ru.json"; -// import sl from "./sl.json"; -// import sv from "./sv.json"; -// import tr from "./tr.json"; -// import vi from "./vi.json"; -// import zh from "./zh.json"; - -// -// we want all the files in individual -// imports for easier handling by -// automated translation software -// -loadTranslations([en]); -// loadTranslations([ar, bg, de, el, en, es, fr, he, hr, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]); diff --git a/imports/plugins/core/ui-grid/server/index.js b/imports/plugins/core/ui-grid/server/index.js deleted file mode 100644 index 3979f964b5a..00000000000 --- a/imports/plugins/core/ui-grid/server/index.js +++ /dev/null @@ -1 +0,0 @@ -import "./i18n"; diff --git a/imports/plugins/core/ui-navbar/client/components/brand/brand.js b/imports/plugins/core/ui-navbar/client/components/brand/brand.js index 5a60c341046..a5ee2e6a0ef 100644 --- a/imports/plugins/core/ui-navbar/client/components/brand/brand.js +++ b/imports/plugins/core/ui-navbar/client/components/brand/brand.js @@ -1,3 +1,5 @@ +import _ from "lodash"; +import { Template } from "meteor/templating"; import { Reaction, Router } from "/client/api"; import { Media, Shops } from "/lib/collections"; diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js b/imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js index e47ac636700..586e4032336 100644 --- a/imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js +++ b/imports/plugins/core/ui-navbar/client/components/navbar/components/brand.js @@ -1,4 +1,5 @@ import React, { Component } from "react"; +import _ from "lodash"; import { Reaction } from "/client/api"; import { Media, Shops } from "/lib/collections"; diff --git a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js index 4c1a9f738d1..9b974fb2220 100644 --- a/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js +++ b/imports/plugins/core/ui-navbar/client/components/navbar/navbar.js @@ -1,3 +1,7 @@ +import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; +import { Blaze } from "meteor/blaze"; +import { ReactiveDict } from "meteor/reactive-dict"; import { FlatButton } from "/imports/plugins/core/ui/client/components"; import { NotificationContainer } from "/imports/plugins/included/notifications/client/containers"; import { Reaction } from "/client/api"; @@ -45,7 +49,6 @@ Template.CoreNavigationBar.helpers({ component: MainDropdown }; }, - navbar() { return { component: NavBarContainer diff --git a/imports/plugins/core/ui-tagnav/client/components/tagGroup.js b/imports/plugins/core/ui-tagnav/client/components/tagGroup.js index f1cd08cb4d5..5838304d7c2 100644 --- a/imports/plugins/core/ui-tagnav/client/components/tagGroup.js +++ b/imports/plugins/core/ui-tagnav/client/components/tagGroup.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; +import _ from "lodash"; import update from "react/lib/update"; import TagGroupBody from "./tagGroupBody"; import TagGroupHeader from "./tagGroupHeader"; diff --git a/imports/plugins/core/ui-tagnav/client/components/tagGroupBody.js b/imports/plugins/core/ui-tagnav/client/components/tagGroupBody.js index 83cc330ffc3..f69d64d3d27 100644 --- a/imports/plugins/core/ui-tagnav/client/components/tagGroupBody.js +++ b/imports/plugins/core/ui-tagnav/client/components/tagGroupBody.js @@ -1,4 +1,5 @@ import debounce from "lodash/debounce"; +import _ from "lodash"; import React, { Component } from "react"; import update from "react/lib/update"; import PropTypes from "prop-types"; diff --git a/imports/plugins/core/ui-tagnav/client/components/tagNav.js b/imports/plugins/core/ui-tagnav/client/components/tagNav.js index db0ba76e433..32e11a99a64 100644 --- a/imports/plugins/core/ui-tagnav/client/components/tagNav.js +++ b/imports/plugins/core/ui-tagnav/client/components/tagNav.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; +import _ from "lodash"; import { getTagIds } from "/lib/selectors/tags"; import { DragDropProvider } from "/imports/plugins/core/ui/client/providers"; import { Button, EditButton } from "/imports/plugins/core/ui/client/components"; @@ -91,7 +92,7 @@ class TagNav extends Component { {this.props.canEdit && this.renderEditButton()} -
+ ); } diff --git a/imports/plugins/core/ui-tagnav/client/containers/tagNavContainer.js b/imports/plugins/core/ui-tagnav/client/containers/tagNavContainer.js index f90fd0ab2fb..130ea8afd98 100644 --- a/imports/plugins/core/ui-tagnav/client/containers/tagNavContainer.js +++ b/imports/plugins/core/ui-tagnav/client/containers/tagNavContainer.js @@ -1,6 +1,8 @@ import debounce from "lodash/debounce"; +import _ from "lodash"; import update from "react/lib/update"; -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Reaction, Router } from "/client/api"; import { composeWithTracker } from "/lib/api/compose"; import { getTagIds } from "/lib/selectors/tags"; diff --git a/imports/plugins/core/ui-tagnav/client/helpers/tags.js b/imports/plugins/core/ui-tagnav/client/helpers/tags.js index 4885b13fb21..ec190810dbe 100644 --- a/imports/plugins/core/ui-tagnav/client/helpers/tags.js +++ b/imports/plugins/core/ui-tagnav/client/helpers/tags.js @@ -1,3 +1,4 @@ +import _ from "lodash"; import { Reaction, i18next } from "/client/api"; import { Tags } from "/lib/collections"; import { Meteor } from "meteor/meteor"; diff --git a/imports/plugins/core/ui/client/components/alerts/alert.js b/imports/plugins/core/ui/client/components/alerts/alert.js index 6c892981272..cab8b671d40 100644 --- a/imports/plugins/core/ui/client/components/alerts/alert.js +++ b/imports/plugins/core/ui/client/components/alerts/alert.js @@ -1,9 +1,9 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Translation } from "../translation"; class Alert extends Component { - componentDidMount() { if (this.props.alert) { const { diff --git a/imports/plugins/core/ui/client/components/alerts/alerts.js b/imports/plugins/core/ui/client/components/alerts/alerts.js index f569c48fb82..e0a57848bf6 100644 --- a/imports/plugins/core/ui/client/components/alerts/alerts.js +++ b/imports/plugins/core/ui/client/components/alerts/alerts.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Alert from "./alert"; class Alerts extends Component { diff --git a/imports/plugins/core/ui/client/components/button/buttonSelect.js b/imports/plugins/core/ui/client/components/button/buttonSelect.js index f062323dbd9..6aaa4abcf8f 100644 --- a/imports/plugins/core/ui/client/components/button/buttonSelect.js +++ b/imports/plugins/core/ui/client/components/button/buttonSelect.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import Button from "./button.jsx"; import { Translation } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/ui/client/components/button/handle.js b/imports/plugins/core/ui/client/components/button/handle.js index 8a219cf1aea..d7a7da3cbcc 100644 --- a/imports/plugins/core/ui/client/components/button/handle.js +++ b/imports/plugins/core/ui/client/components/button/handle.js @@ -1,4 +1,5 @@ -import React, { PropTypes } from "react"; +import React from "react"; +import PropTypes from "prop-types"; import { Icon } from "../icon"; /** diff --git a/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js b/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js index cf313fdc0a1..bf63fb46644 100644 --- a/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js +++ b/imports/plugins/core/ui/client/components/buttonGroup/buttonGroup.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; class ButtonGroup extends Component { diff --git a/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js b/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js index 19fe759a9ec..d6b34a2b6a4 100644 --- a/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js +++ b/imports/plugins/core/ui/client/components/buttonGroup/buttonToolbar.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; class ButtonToolbar extends Component { diff --git a/imports/plugins/core/ui/client/components/cards/card.js b/imports/plugins/core/ui/client/components/cards/card.js index d39fef1f35c..10d68956dec 100644 --- a/imports/plugins/core/ui/client/components/cards/card.js +++ b/imports/plugins/core/ui/client/components/cards/card.js @@ -1,8 +1,8 @@ -import React, { Children, Component, PropTypes } from "react"; +import React, { Children, Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; class Card extends Component { - constructor(props) { super(props); diff --git a/imports/plugins/core/ui/client/components/cards/cardBody.js b/imports/plugins/core/ui/client/components/cards/cardBody.js index 376a5d0ecca..1a08978cb2b 100644 --- a/imports/plugins/core/ui/client/components/cards/cardBody.js +++ b/imports/plugins/core/ui/client/components/cards/cardBody.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { VelocityTransitionGroup } from "velocity-react"; import Radium from "radium"; import classnames from "classnames"; diff --git a/imports/plugins/core/ui/client/components/cards/cardGroup.js b/imports/plugins/core/ui/client/components/cards/cardGroup.js index fb11a741637..298c7382fd9 100644 --- a/imports/plugins/core/ui/client/components/cards/cardGroup.js +++ b/imports/plugins/core/ui/client/components/cards/cardGroup.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; class CardGroup extends Component { render() { diff --git a/imports/plugins/core/ui/client/components/cards/cardHeader.js b/imports/plugins/core/ui/client/components/cards/cardHeader.js index adc89fd1a81..7a85e184c43 100644 --- a/imports/plugins/core/ui/client/components/cards/cardHeader.js +++ b/imports/plugins/core/ui/client/components/cards/cardHeader.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import CardTitle from "./cardTitle"; import IconButton from "../button/iconButton"; diff --git a/imports/plugins/core/ui/client/components/cards/cardTitle.js b/imports/plugins/core/ui/client/components/cards/cardTitle.js index ebadb7df00e..9dcff57aee8 100644 --- a/imports/plugins/core/ui/client/components/cards/cardTitle.js +++ b/imports/plugins/core/ui/client/components/cards/cardTitle.js @@ -1,8 +1,8 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Translation } from "../translation"; class CardTitle extends Component { - render() { const { element, ...props } = this.props; diff --git a/imports/plugins/core/ui/client/components/cards/cardToolbar.js b/imports/plugins/core/ui/client/components/cards/cardToolbar.js index 83e01431118..1b706b1c798 100644 --- a/imports/plugins/core/ui/client/components/cards/cardToolbar.js +++ b/imports/plugins/core/ui/client/components/cards/cardToolbar.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; class CardToobar extends Component { static propTypes = { diff --git a/imports/plugins/core/ui/client/components/cards/cards.js b/imports/plugins/core/ui/client/components/cards/cards.js index 1735eec059e..165fb6362b7 100644 --- a/imports/plugins/core/ui/client/components/cards/cards.js +++ b/imports/plugins/core/ui/client/components/cards/cards.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; /** * @typedef CardProps * @type Object diff --git a/imports/plugins/core/ui/client/components/cards/settingsCard.js b/imports/plugins/core/ui/client/components/cards/settingsCard.js index 820b5ebd0a1..43ad0866b87 100644 --- a/imports/plugins/core/ui/client/components/cards/settingsCard.js +++ b/imports/plugins/core/ui/client/components/cards/settingsCard.js @@ -3,7 +3,8 @@ * creation settings cards (panels) in the dashboard. */ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Blaze from "meteor/gadicc:blaze-react-component"; import { Reaction } from "/client/api"; import { composeWithTracker } from "/lib/api/compose"; diff --git a/imports/plugins/core/ui/client/components/checkbox/checkbox.js b/imports/plugins/core/ui/client/components/checkbox/checkbox.js index 72b8715a3c7..4541129e621 100644 --- a/imports/plugins/core/ui/client/components/checkbox/checkbox.js +++ b/imports/plugins/core/ui/client/components/checkbox/checkbox.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Translation } from "/imports/plugins/core/ui/client/components"; class Checkbox extends Component { diff --git a/imports/plugins/core/ui/client/components/divider/divider.js b/imports/plugins/core/ui/client/components/divider/divider.js index 68f0e2a5f47..3282868fa91 100644 --- a/imports/plugins/core/ui/client/components/divider/divider.js +++ b/imports/plugins/core/ui/client/components/divider/divider.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Translation } from "../"; diff --git a/imports/plugins/core/ui/client/components/forms/form.js b/imports/plugins/core/ui/client/components/forms/form.js index 896e8b31a19..fbae19daee7 100644 --- a/imports/plugins/core/ui/client/components/forms/form.js +++ b/imports/plugins/core/ui/client/components/forms/form.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { map, update, set, at, isEqual } from "lodash"; import classnames from "classnames"; import { Switch, Button, TextField, Select, FormActions } from "../"; diff --git a/imports/plugins/core/ui/client/components/forms/formActions.js b/imports/plugins/core/ui/client/components/forms/formActions.js index 560bb08f1c4..26ab34cfee9 100644 --- a/imports/plugins/core/ui/client/components/forms/formActions.js +++ b/imports/plugins/core/ui/client/components/forms/formActions.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; class FormActions extends Component { static propTypes = { diff --git a/imports/plugins/core/ui/client/components/icon/icon.jsx b/imports/plugins/core/ui/client/components/icon/icon.jsx index db20841ac05..d191ba111f5 100644 --- a/imports/plugins/core/ui/client/components/icon/icon.jsx +++ b/imports/plugins/core/ui/client/components/icon/icon.jsx @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames/dedupe"; class Icon extends Component { diff --git a/imports/plugins/core/ui/client/components/index.js b/imports/plugins/core/ui/client/components/index.js index 71f767c0a26..2c672847c9b 100644 --- a/imports/plugins/core/ui/client/components/index.js +++ b/imports/plugins/core/ui/client/components/index.js @@ -18,7 +18,7 @@ export { TagList, TagItem } from "./tags"; export * from "./cards"; export { MediaGallery, MediaItem } from "./media"; export { default as FlatButton } from "./button/flatButton"; -export { default as SortableTable } from "./table/table"; +export { SortableTable, SortableTableLegacy } from "./table"; export { Checkbox } from "./checkbox"; export { default as Loading } from "./loading/loading"; export * from "./forms"; diff --git a/imports/plugins/core/ui/client/components/items/item.js b/imports/plugins/core/ui/client/components/items/item.js index 3aa2efe6c13..d435196a137 100644 --- a/imports/plugins/core/ui/client/components/items/item.js +++ b/imports/plugins/core/ui/client/components/items/item.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from "prop-types"; class Item extends React.Component { render() { @@ -13,7 +14,7 @@ class Item extends React.Component { Item.displayName = "Item"; Item.propTypes = { - children: React.PropTypes.node + children: PropTypes.node }; export default Item; diff --git a/imports/plugins/core/ui/client/components/items/items.js b/imports/plugins/core/ui/client/components/items/items.js index 02fed25bbe2..cab3830f0d4 100644 --- a/imports/plugins/core/ui/client/components/items/items.js +++ b/imports/plugins/core/ui/client/components/items/items.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from "prop-types"; class Items extends React.Component { render() { @@ -13,7 +14,7 @@ class Items extends React.Component { Items.displayName = "Items"; Items.propTypes = { - children: React.PropTypes.node + children: PropTypes.node }; export default Items; diff --git a/imports/plugins/core/ui/client/components/list/list.js b/imports/plugins/core/ui/client/components/list/list.js index 2550c97017a..e927f7bf24e 100644 --- a/imports/plugins/core/ui/client/components/list/list.js +++ b/imports/plugins/core/ui/client/components/list/list.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; class List extends Component { diff --git a/imports/plugins/core/ui/client/components/list/listItem.js b/imports/plugins/core/ui/client/components/list/listItem.js index 93060a51324..c731b1b856a 100644 --- a/imports/plugins/core/ui/client/components/list/listItem.js +++ b/imports/plugins/core/ui/client/components/list/listItem.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Icon, Switch, Translation } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/ui/client/components/media/media.js b/imports/plugins/core/ui/client/components/media/media.js index db5ddcdf074..aecccdd9cf9 100644 --- a/imports/plugins/core/ui/client/components/media/media.js +++ b/imports/plugins/core/ui/client/components/media/media.js @@ -1,10 +1,10 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { IconButton } from "../"; import { SortableItem } from "../../containers"; class MediaItem extends Component { - handleMouseEnter = (event) => { if (this.props.onMouseEnter) { this.props.onMouseEnter(event, this.props.source); @@ -57,7 +57,7 @@ class MediaItem extends Component { if (!this.props.revision || this.props.revision.changeType !== "remove") { return (
- {this.renderRevision()} + {this.renderRevision()} - {this.renderRevision()} -
+
+ {this.renderRevision()} +
); } return null; diff --git a/imports/plugins/core/ui/client/components/media/mediaGallery.js b/imports/plugins/core/ui/client/components/media/mediaGallery.js index b9d889e721b..e2f94b96f7d 100644 --- a/imports/plugins/core/ui/client/components/media/mediaGallery.js +++ b/imports/plugins/core/ui/client/components/media/mediaGallery.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Dropzone from "react-dropzone"; import Measure from "react-measure"; import MediaItem from "./media"; diff --git a/imports/plugins/core/ui/client/components/menu/menuItem.js b/imports/plugins/core/ui/client/components/menu/menuItem.js index 0907178322d..f07d3f007dd 100644 --- a/imports/plugins/core/ui/client/components/menu/menuItem.js +++ b/imports/plugins/core/ui/client/components/menu/menuItem.js @@ -5,7 +5,6 @@ import Icon from "../icon/icon.jsx"; import { Translation } from "../"; class MenuItem extends Component { - handleClick = (event) => { event.preventDefault(); if (this.props.onClick && this.props.disabled === false) { diff --git a/imports/plugins/core/ui/client/components/metadata/metadata.js b/imports/plugins/core/ui/client/components/metadata/metadata.js index ade3d33447f..8590e244b36 100644 --- a/imports/plugins/core/ui/client/components/metadata/metadata.js +++ b/imports/plugins/core/ui/client/components/metadata/metadata.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Metafield from "./metafield"; class Metadata extends Component { diff --git a/imports/plugins/core/ui/client/components/metadata/metafield.js b/imports/plugins/core/ui/client/components/metadata/metafield.js index 075e9a9bc09..bfe603330de 100644 --- a/imports/plugins/core/ui/client/components/metadata/metafield.js +++ b/imports/plugins/core/ui/client/components/metadata/metafield.js @@ -1,10 +1,10 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Velocity from "velocity-animate"; import "velocity-animate/velocity.ui"; import { TextField, Button } from "../"; class Metafield extends Component { - componentWillReceiveProps(nextProps) { if (nextProps.metafield.key !== this.props.metafield.key) { const input = this.refs.keyInput.refs.input; diff --git a/imports/plugins/core/ui/client/components/modal/overlay.js b/imports/plugins/core/ui/client/components/modal/overlay.js index a61dde56395..fe24b4be5e5 100644 --- a/imports/plugins/core/ui/client/components/modal/overlay.js +++ b/imports/plugins/core/ui/client/components/modal/overlay.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { VelocityTransitionGroup } from "velocity-react"; import Radium from "radium"; import classnames from "classnames"; diff --git a/imports/plugins/core/ui/client/components/multiselect/multiselect.js b/imports/plugins/core/ui/client/components/multiselect/multiselect.js index a64102f34cc..54d3f0352fc 100644 --- a/imports/plugins/core/ui/client/components/multiselect/multiselect.js +++ b/imports/plugins/core/ui/client/components/multiselect/multiselect.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import Select from "react-select"; import { Translation } from "../translation"; diff --git a/imports/plugins/core/ui/client/components/numericInput/numericInput.js b/imports/plugins/core/ui/client/components/numericInput/numericInput.js index 8c2dae1ec77..65244b4c2d9 100644 --- a/imports/plugins/core/ui/client/components/numericInput/numericInput.js +++ b/imports/plugins/core/ui/client/components/numericInput/numericInput.js @@ -1,4 +1,5 @@ import React from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; const accounting = require("accounting-js"); @@ -81,10 +82,6 @@ class NumericInput extends React.Component { format(value, format) { const moneyFormat = format || this.moneyFormat; - - // value * (10 ^ (2 - moneyFormat.scale)) - - // console.log(moneyFormat, value, value * Math.pow(10, 2 - moneyFormat.precision)); const decimal = moneyFormat.decimal || undefined; const unformatedValue = this.unformat(value, decimal); @@ -103,7 +100,7 @@ class NumericInput extends React.Component { /** * Handle change event from text input - * @param {SytheticEvent} event Change event + * @param {SyntheticEvent} event Change event * @return {undefined} */ handleChange(event) { @@ -176,14 +173,14 @@ NumericInput.defaultProps = { }; NumericInput.propTypes = { - classNames: React.PropTypes.shape({}), - disabled: React.PropTypes.bool, - format: React.PropTypes.shape({ - scale: React.PropTypes.number + classNames: PropTypes.shape({}), + disabled: PropTypes.bool, + format: PropTypes.shape({ + scale: PropTypes.number }), - isEditing: React.PropTypes.bool, - onChange: React.PropTypes.func, - value: React.PropTypes.number + isEditing: PropTypes.bool, + onChange: PropTypes.func, + value: PropTypes.number }; export default NumericInput; diff --git a/imports/plugins/core/ui/client/components/popover/popover.js b/imports/plugins/core/ui/client/components/popover/popover.js index 0d779d01bb0..49081dc3306 100644 --- a/imports/plugins/core/ui/client/components/popover/popover.js +++ b/imports/plugins/core/ui/client/components/popover/popover.js @@ -1,5 +1,6 @@ import React, { Component } from "react"; import PropTypes from "prop-types"; +import { Tooltip } from "/imports/plugins/core/ui/client/components"; import classnames from "classnames"; import TetherComponent from "react-tether"; import PopoverContent from "./popoverContent"; diff --git a/imports/plugins/core/ui/client/components/popover/popoverContent.js b/imports/plugins/core/ui/client/components/popover/popoverContent.js index a34fc9886d3..059891618ea 100644 --- a/imports/plugins/core/ui/client/components/popover/popoverContent.js +++ b/imports/plugins/core/ui/client/components/popover/popoverContent.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import onclickOutside from "react-onclickoutside"; class PopoverContent extends Component { diff --git a/imports/plugins/core/ui/client/components/progress/circularProgress.js b/imports/plugins/core/ui/client/components/progress/circularProgress.js index bbde2f865ff..c03c5274a91 100644 --- a/imports/plugins/core/ui/client/components/progress/circularProgress.js +++ b/imports/plugins/core/ui/client/components/progress/circularProgress.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; class CircularProgress extends Component { renderInderterminateProgress() { diff --git a/imports/plugins/core/ui/client/components/select/select.js b/imports/plugins/core/ui/client/components/select/select.js index 259b7b55392..343a3f0a77e 100644 --- a/imports/plugins/core/ui/client/components/select/select.js +++ b/imports/plugins/core/ui/client/components/select/select.js @@ -1,3 +1,5 @@ +import { Template } from "meteor/templating"; +import { ReactiveDict } from "meteor/reactive-dict"; import { templateClassName } from "/imports/plugins/core/ui/client/helpers/helpers"; /** diff --git a/imports/plugins/core/ui/client/components/slider/slider.js b/imports/plugins/core/ui/client/components/slider/slider.js index a3e83388542..8bdc957ea48 100644 --- a/imports/plugins/core/ui/client/components/slider/slider.js +++ b/imports/plugins/core/ui/client/components/slider/slider.js @@ -2,7 +2,8 @@ * Implementing No UI Slider * https://www.npmjs.com/package/react-nouislider */ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Nouislider from "react-nouislider"; class Slider extends Component { diff --git a/imports/plugins/core/ui/client/components/switch/switch.js b/imports/plugins/core/ui/client/components/switch/switch.js index 45a7399b470..f5453df24e2 100644 --- a/imports/plugins/core/ui/client/components/switch/switch.js +++ b/imports/plugins/core/ui/client/components/switch/switch.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Translation } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/core/ui/client/components/table/index.js b/imports/plugins/core/ui/client/components/table/index.js new file mode 100644 index 00000000000..6fd0a12bd6b --- /dev/null +++ b/imports/plugins/core/ui/client/components/table/index.js @@ -0,0 +1,2 @@ +export { default as SortableTable } from "./sortableTable"; +export { default as SortableTableLegacy } from "./sortableTableLegacy"; diff --git a/imports/plugins/core/ui/client/components/table/sortableTable.js b/imports/plugins/core/ui/client/components/table/sortableTable.js new file mode 100644 index 00000000000..d0a90e855a0 --- /dev/null +++ b/imports/plugins/core/ui/client/components/table/sortableTable.js @@ -0,0 +1,281 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import _ from "lodash"; +import matchSorter from "match-sorter"; +import ReactTable from "react-table"; +import { Meteor } from "meteor/meteor"; +import { Counts } from "meteor/tmeasday:publish-counts"; +import { SortableTableFilter, SortableTablePagination } from "./sortableTableComponents"; + +class SortableTable extends Component { + constructor(props) { + super(props); + + this.state = { + currentPage: 0, + filterInput: "", + maxPages: 0, + query: this.props.query || {} + }; + + this.handleFilterInput = this.handleFilterInput.bind(this); + } + + + /** + * getMeteorData() - Absorb publication / collection information from props, output data from subscription + * @prop {String} matchingResultsCount - Send to Counts collection to get results count of sub + * @prop {String} publication - publication to subscribe to + * @prop {Object} collection - collection to get data from + * Use props to get collection, EmailTableColumn + * Use that info to call meteor and get subscription + * Output data for table + * @returns {Object} loading status (bool), results (object), and matchingResults (number) + */ + getMeteorData() { + const { collection, matchingResultsCount, publication } = this.props; + + // Get a count of the number of items matching the current filter. + // If no filter is set it will return the total number of items in the collection. + const matchingResults = Counts.get(matchingResultsCount); + + const options = {}; + + const pubHandle = Meteor.subscribe(publication, this.state.query, _.assignIn({}, options)); + + // optional transform of collection for grid results + let results = collection.find(this.state.query, options).fetch(); + if (this.props.transform) { + results = this.props.transform(results); + } + + return { + loading: !pubHandle.ready(), + results: results, + matchingResults: matchingResults + }; + } + + + /** + * customFilter() - Replace default filter with customized filter + * custom filter is case insensitive + * custom filter searches entire string, not just from string start + * @param {Object} filter user-typed data + * @param {Object} row row info for associated filter + * @returns {String|Boolean} replacement filter + */ + customFilter = (filter, row) => { + const id = filter.pivotId || filter.id; + if (row[id] !== null && typeof row[id] === "string") { + return (row[id] !== undefined + ? String(row[id].toLowerCase()).includes(filter.value.toLowerCase()) + : true); + } + } + + + /** + * handleFilterInput() - Update state when filter is changed + * @param {script} event onChange event when typing in filter field + * @param {string} value text field input + * @param {string} field input field name to watch + * @return {function} state for field value + */ + handleFilterInput = (event, value, field) => { + this.setState({ + [field]: value + }); + } + + + /** + * handleClick() - Handle click on table row + * @param {object} rowInfo row data passed in from ReactTable + * @return {function} return onRowClick function prop, or undefined if not supplied + */ + handleClick(rowInfo) { + const { onRowClick } = this.props; + + if (typeof onRowClick === "function") { + return ( + onRowClick({ + className: "sortable-table-row", + props: { + data: { + _id: rowInfo.original._id, + type: rowInfo.original.type + } + } + }) + ); + } + } + + + /** + * renderColumns() - Absorb columnMetadata information from props, output columns to display + * @prop {String} columnMetadata - Object of data field, column header + * @returns {Object} data filed (string), translated header (string), and minWidth (number / undefined) + */ + renderColumns() { + const { columnMetadata } = this.props; + + // Add minWidth = undefined to override 100px default set by ReactTable + const displayColumns = columnMetadata.map((element) => { + return _.assignIn({}, element, { + minWidth: undefined + }); + }); + + return displayColumns; + } + + + /** + * renderData() - Take data from getMeteorData() and filter if needed, or spit out raw if no filter + * @returns {Object} data filed (string), translated header (string), and minWidth (number / undefined) + */ + renderData() { + const { filteredFields } = this.props; + const { filterInput } = this.state; + + let originalData = []; + + if (this.getMeteorData().results) { + originalData = this.getMeteorData().results; + } + + const filteredData = matchSorter(originalData, filterInput, { keys: filteredFields }); + + return filteredData; + } + + + /** + * renderColumnFilter() - Uses props to determine if Column Filters should be shown + * @returns {Bool} returns true or false for column filters + */ + renderColumnFilter() { + const { filterType } = this.props; + + if (filterType === "both" || filterType === "column") { + return true; + } + + return false; + } + + + /** + * renderTableFilter() - Uses props to determine if a Table Filter should be shown + * @returns {node} returns JSX node or null + */ + renderTableFilter() { + const { filterType } = this.props; + + if (filterType === "both" || filterType === "table") { + return ( + + ); + } + + return null; + } + + + render() { + const { ...otherProps } = this.props; + + // All available props: https://github.com/tannerlinsley/react-table#props + return ( +
+ {this.renderTableFilter()} + { // eslint-disable-line no-unused-vars + return { + onClick: e => { // eslint-disable-line no-unused-vars + this.handleClick(rowInfo); + } + }; + }} + /> +
+ ); + } +} + +SortableTable.propTypes = { + /** @type {object} collection collection to get data from */ + collection: PropTypes.object, + /** @type {array} columnMetadata provides filtered columns with i18n headers */ + columnMetadata: PropTypes.array, + /** @type {number} defaultPageSize how many results per page */ + defaultPageSize: PropTypes.number, + /** @type {bool} filterType filter by table, column, or both */ + filterType: PropTypes.string, + /** @type {array} filteredFields provides filtered columns, use columnMetadata instead */ + filteredFields: PropTypes.array, + /** @type {bool} isFilterable show / hide column filter */ + isFilterable: PropTypes.bool, + /** @type {bool} isResizeable allow resizing of table columns */ + isResizeable: PropTypes.bool, + /** @type {bool} isSortable allow column sorting */ + isSortable: PropTypes.bool, + /** @type {string} matchingResultsCount provides Count publication to get count from */ + matchingResultsCount: PropTypes.string, + /** @type {number} minRows minimum amount of rows to display in table */ + minRows: PropTypes.number, + /** @type {string} noDataMessage text to display when no data is available */ + noDataMessage: PropTypes.string, + /** @type {function} onRowClick provides function / action when clicking on row */ + onRowClick: PropTypes.func, + /** @type {string} publication provides publication to get Meteor data from */ + publication: PropTypes.string, + /** @type {object} query provides query for publication filtering */ + query: PropTypes.object, + /** @type {function} transform transform of collection for grid results */ + transform: PropTypes.func +}; + +SortableTable.defaultProps = { + defaultPageSize: 10, + filterType: "table", + isFilterable: false, + isResizeable: true, + isSortable: true, + minRows: 0, + // Text props where translations are needed + noDataMessage: "No results found", + previousText: "Previous", + nextText: "Next", + loadingText: "Loading...", + noDataText: "No results found", + pageText: "Page", + ofText: "of", + rowsText: "rows" +}; + +export default SortableTable; diff --git a/imports/plugins/core/ui/client/components/table/sortableTableComponents/filter.js b/imports/plugins/core/ui/client/components/table/sortableTableComponents/filter.js new file mode 100644 index 00000000000..a782b43d6ad --- /dev/null +++ b/imports/plugins/core/ui/client/components/table/sortableTableComponents/filter.js @@ -0,0 +1,35 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { TextField } from "@reactioncommerce/reaction-ui"; + + +class SortableTableFilter extends Component { + constructor(props) { + super(props); + } + + + render() { + return ( + + ); + } +} + + +SortableTableFilter.propTypes = { + name: PropTypes.string, + onChange: PropTypes.func, + value: PropTypes.string +}; + +export default SortableTableFilter; diff --git a/imports/plugins/core/ui/client/components/table/sortableTableComponents/index.js b/imports/plugins/core/ui/client/components/table/sortableTableComponents/index.js new file mode 100644 index 00000000000..f261a441d6e --- /dev/null +++ b/imports/plugins/core/ui/client/components/table/sortableTableComponents/index.js @@ -0,0 +1,4 @@ +export { default as PaginationButtons } from "./paginationButtons"; +export { default as SortableTablePagination } from "./pagination"; + +export { default as SortableTableFilter } from "./filter"; diff --git a/imports/plugins/core/ui/client/components/table/sortableTableComponents/pagination.js b/imports/plugins/core/ui/client/components/table/sortableTableComponents/pagination.js new file mode 100644 index 00000000000..a6b2b8e22e8 --- /dev/null +++ b/imports/plugins/core/ui/client/components/table/sortableTableComponents/pagination.js @@ -0,0 +1,164 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import classnames from "classnames"; +import { PaginationButtons } from "../sortableTableComponents"; + + +class SortableTablePagination extends Component { + constructor(props) { + super(props); + + this.getSafePage = this.getSafePage.bind(this); + this.changePage = this.changePage.bind(this); + this.applyPage = this.applyPage.bind(this); + + this.state = { + page: props.page + }; + } + + componentWillReceiveProps(nextProps) { + this.setState({ page: nextProps.page }); + } + + getSafePage(page) { + if (isNaN(page)) { + page = this.props.page; // eslint-disable-line + } + return Math.min(Math.max(page, 0), this.props.pages - 1); + } + + changePage(page) { + page = this.getSafePage(page); // eslint-disable-line + this.setState({ page }); + if (this.props.page !== page) { + this.props.onPageChange(page); + } + } + + applyPage(e) { + e && e.preventDefault(); + const page = this.state.page; + this.changePage(page === "" ? this.props.page : page); + } + + render() { + const { + // Computed + pages, + // Props + page, + showPageSizeOptions, + pageSizeOptions, + pageSize, + showPageJump, + canPrevious, + canNext, + onPageSizeChange, + className, + PreviousComponent = PaginationButtons, + NextComponent = PaginationButtons + } = this.props; + + return ( +
+
+ + {this.props.pageText}{" "} + {showPageJump + ?
+ { + const val = e.target.value; + const page = val - 1; // eslint-disable-line + if (val === "") { + return this.setState({ page: val }); + } + this.setState({ page: this.getSafePage(page) }); + }} + value={this.state.page === "" ? "" : this.state.page + 1} + onBlur={this.applyPage} + onKeyPress={e => { + if (e.which === 13 || e.keyCode === 13) { + this.applyPage(); + } + }} + /> +
+ : {page + 1}}{" "} + {this.props.ofText}{" "} + {pages || 1} +
+ {showPageSizeOptions && + + + } +
+
+ { // eslint-disable-line no-unused-vars + if (!canPrevious) { + return this.changePage(page - 1); + } + }} + disabled={!canPrevious} + > + {this.props.previousText} + +
+ | +
+ { // eslint-disable-line no-unused-vars + if (!canNext) { + return this.changePage(page + 1); + } + }} + disabled={!canNext} + > + {this.props.nextText} + +
+
+ ); + } +} + +SortableTablePagination.propTypes = { + NextComponent: PropTypes.func, + PreviousComponent: PropTypes.func, + canNext: PropTypes.bool, + canPrevious: PropTypes.bool, + className: PropTypes.object, + nextText: PropTypes.string, + ofText: PropTypes.string, + onPageChange: PropTypes.func, + onPageSizeChange: PropTypes.func, + page: PropTypes.number, + pageSize: PropTypes.number, + pageSizeOptions: PropTypes.array, + pageText: PropTypes.string, + pages: PropTypes.number, + paginationStyle: PropTypes.object, + previousText: PropTypes.string, + rowsText: PropTypes.string, + showPageJump: PropTypes.bool, + showPageSizeOptions: PropTypes.bool +}; + +export default SortableTablePagination; diff --git a/imports/plugins/core/ui/client/components/table/sortableTableComponents/paginationButtons.js b/imports/plugins/core/ui/client/components/table/sortableTableComponents/paginationButtons.js new file mode 100644 index 00000000000..3dd7bf0e2cf --- /dev/null +++ b/imports/plugins/core/ui/client/components/table/sortableTableComponents/paginationButtons.js @@ -0,0 +1,79 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Button } from "/imports/plugins/core/ui/client/components"; + + +class PaginationButtons extends Component { + constructor(props) { + super(props); + } + + renderIcon() { + const { children } = this.props; + + if (children === "Previous") { + return "fa fa-angle-left"; + } + + if (children === "Next") { + return "fa fa-angle-right"; + } + + return null; + } + + + renderIconPosition() { + const { children } = this.props; + + if (children === "Previous") { + return false; + } + + if (children === "Next") { + return true; + } + + return false; + } + + renderText() { + const { children } = this.props; + + if (children === "Previous") { + return " Previous"; + } + + if (children === "Next") { + return "Next "; + } + + return null; + } + + render() { + const { disabled, onClick } = this.props; + + return ( + ); } return ( ); } diff --git a/imports/plugins/included/notifications/client/components/notificationDropdown.js b/imports/plugins/included/notifications/client/components/notificationDropdown.js index c51cd608bfc..0c8045c4ed9 100644 --- a/imports/plugins/included/notifications/client/components/notificationDropdown.js +++ b/imports/plugins/included/notifications/client/components/notificationDropdown.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import moment from "moment"; import { Reaction } from "/client/api"; @@ -9,18 +10,19 @@ class NotificationDropdown extends Component { this.handleNoNotifications = this.handleNoNotifications.bind(this); this.renderDropdownHead = this.renderDropdownHead.bind(this); this.handleClick = this.handleClick.bind(this); + this.handleClickViewAll = this.handleClickViewAll.bind(this); } handleNoNotifications(notifyArr) { if (notifyArr.length <= 0) { return ( -
  • -
    -
    - No notifications yet -
    -
    -
  • +
  • +
    +
    + No notifications yet +
    +
    +
  • ); } return null; @@ -41,57 +43,57 @@ class NotificationDropdown extends Component { return markOneAsRead(notify._id); } + handleClickViewAll() { + const url = this.prefix + "/notifications"; + Reaction.Router.go(url); + } + renderDropdownHead() { const { notificationList, unread, markAllAsRead } = this.props; return ( -
    - -

    Recent ({unread})

    + ); } render() { const { notificationList } = this.props; - const prefix = this.prefix + "/notifications"; return ( -
    - { this.renderDropdownHead() } - -
    - View All -
    +
    + { this.renderDropdownHead() } + + +
    ); } } diff --git a/imports/plugins/included/notifications/client/components/notificationRoute.js b/imports/plugins/included/notifications/client/components/notificationRoute.js index 4bd0305dea2..e358a944b93 100644 --- a/imports/plugins/included/notifications/client/components/notificationRoute.js +++ b/imports/plugins/included/notifications/client/components/notificationRoute.js @@ -1,5 +1,7 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import moment from "moment"; +import { Reaction } from "/client/api"; class NotificationRoute extends Component { @@ -14,19 +16,29 @@ class NotificationRoute extends Component { handleNoNotifications(notifyArr) { if (notifyArr.length <= 0) { return ( -
  • -
    -
    - No notifications yet -
    -
    -
  • +
  • +
    +
    + No notifications yet +
    +
    +
  • ); } return null; } handleClick(notify) { + if (notify.type === "forAdmin") { + const actionViewData = Reaction.Apps({ + name: "reaction-orders", + provides: "dashboard" + }); + Reaction.showActionView(actionViewData); + } else { + Reaction.Router.go(notify.url); + } + const { markOneAsRead } = this.props; return markOneAsRead(notify._id); } @@ -34,50 +46,46 @@ class NotificationRoute extends Component { renderDropdownHead() { const { notificationList, unread, markAllAsRead } = this.props; return ( -
    - -

    Recent ({unread})

    + ); } render() { const { notificationList } = this.props; return ( -
    - { this.renderDropdownHead() } - -
    +
    + { this.renderDropdownHead() } + +
    ); } } diff --git a/imports/plugins/included/notifications/client/containers/notificationContainer.js b/imports/plugins/included/notifications/client/containers/notificationContainer.js index dc0ba229f85..b0fa1f6d903 100644 --- a/imports/plugins/included/notifications/client/containers/notificationContainer.js +++ b/imports/plugins/included/notifications/client/containers/notificationContainer.js @@ -6,7 +6,7 @@ import { NotificationComponent } from "../components"; const NotificationContainer = (props) => { return ( - + ); }; diff --git a/imports/plugins/included/payments-authnet/client/checkout/authnet.js b/imports/plugins/included/payments-authnet/client/checkout/authnet.js index 319e3d869f3..e99e404bc15 100644 --- a/imports/plugins/included/payments-authnet/client/checkout/authnet.js +++ b/imports/plugins/included/payments-authnet/client/checkout/authnet.js @@ -1,5 +1,7 @@ /* eslint camelcase: 0 */ import { Meteor } from "meteor/meteor"; +import { $ } from "meteor/jquery"; +import { Template } from "meteor/templating"; import { Reaction, Logger } from "/client/api"; import { getCardType } from "/client/modules/core/helpers/globals"; import { Cart, Shops, Packages } from "/lib/collections"; diff --git a/imports/plugins/included/payments-authnet/client/settings/authnet.js b/imports/plugins/included/payments-authnet/client/settings/authnet.js index 557d4183d66..bc3389bbe75 100644 --- a/imports/plugins/included/payments-authnet/client/settings/authnet.js +++ b/imports/plugins/included/payments-authnet/client/settings/authnet.js @@ -20,7 +20,7 @@ AutoForm.hooks({ onSuccess: function () { return Alerts.toast(i18next.t("admin.settings.saveSuccess"), "success"); }, - onError: function () { + onError: function (error) { return Alerts.toast(`${i18next.t("admin.settings.saveFailed")} ${error}`, "error"); } } diff --git a/imports/plugins/included/payments-authnet/server/methods/authnet.js b/imports/plugins/included/payments-authnet/server/methods/authnet.js index f155c010e38..4b254069e26 100644 --- a/imports/plugins/included/payments-authnet/server/methods/authnet.js +++ b/imports/plugins/included/payments-authnet/server/methods/authnet.js @@ -181,7 +181,7 @@ function getAuthnetService(accountOptions) { login, tran_key, mode - } = accountOptions; + } = accountOptions; return new AuthNetAPI({ API_LOGIN_ID: login, diff --git a/imports/plugins/included/payments-braintree/client/checkout/braintree.js b/imports/plugins/included/payments-braintree/client/checkout/braintree.js index ab607e31d13..29d0fc19e47 100644 --- a/imports/plugins/included/payments-braintree/client/checkout/braintree.js +++ b/imports/plugins/included/payments-braintree/client/checkout/braintree.js @@ -1,6 +1,8 @@ /* eslint camelcase: 0 */ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; +import { $ } from "meteor/jquery"; import { getCardType } from "/client/modules/core/helpers/globals"; import { Cart, Shops, Packages } from "/lib/collections"; import { Braintree } from "../api/braintree"; diff --git a/imports/plugins/included/payments-braintree/client/settings/braintree.js b/imports/plugins/included/payments-braintree/client/settings/braintree.js index 8e0e304d32b..5a81ccaacdd 100644 --- a/imports/plugins/included/payments-braintree/client/settings/braintree.js +++ b/imports/plugins/included/payments-braintree/client/settings/braintree.js @@ -1,4 +1,5 @@ /* eslint no-unused-vars: 0 */ +import { AutoForm } from "meteor/aldeed:autoform"; import { Template } from "meteor/templating"; import { Reaction, i18next } from "/client/api"; import { Packages } from "/lib/collections"; @@ -38,7 +39,7 @@ AutoForm.hooks({ onSuccess: function () { return Alerts.toast(i18next.t("admin.settings.saveSuccess"), "success"); }, - onError: function () { + onError: function (error) { return Alerts.toast(`${i18next.t("admin.settings.saveFailed")} ${error}`, "error"); } } diff --git a/imports/plugins/included/payments-braintree/server/methods/braintreeApi.js b/imports/plugins/included/payments-braintree/server/methods/braintreeApi.js index 3c4db301377..2f119169c21 100644 --- a/imports/plugins/included/payments-braintree/server/methods/braintreeApi.js +++ b/imports/plugins/included/payments-braintree/server/methods/braintreeApi.js @@ -4,6 +4,7 @@ import accounting from "accounting-js"; import moment from "moment"; import Future from "fibers/future"; import { Meteor } from "meteor/meteor"; +import { check } from "meteor/check"; import { Packages } from "/lib/collections"; import { Reaction, Logger } from "/server/api"; diff --git a/imports/plugins/included/payments-braintree/server/methods/braintreeMethods.js b/imports/plugins/included/payments-braintree/server/methods/braintreeMethods.js index bd9702eb987..fd8551d1eeb 100644 --- a/imports/plugins/included/payments-braintree/server/methods/braintreeMethods.js +++ b/imports/plugins/included/payments-braintree/server/methods/braintreeMethods.js @@ -1,3 +1,4 @@ +import { check } from "meteor/check"; import { BraintreeApi } from "./braintreeApi"; import { Logger } from "/server/api"; import { PaymentMethod } from "/lib/collections/schemas"; diff --git a/imports/plugins/included/payments-example/client/checkout/example.js b/imports/plugins/included/payments-example/client/checkout/example.js index 64770eb0442..b71fe56fa60 100644 --- a/imports/plugins/included/payments-example/client/checkout/example.js +++ b/imports/plugins/included/payments-example/client/checkout/example.js @@ -1,6 +1,8 @@ /* eslint camelcase: 0 */ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; +import { $ } from "meteor/jquery"; import { Reaction } from "/client/api"; import { Cart, Shops, Packages } from "/lib/collections"; import { Example } from "../../lib/api"; diff --git a/imports/plugins/included/payments-example/client/settings/components/exampleSettingsForm.js b/imports/plugins/included/payments-example/client/settings/components/exampleSettingsForm.js index 960f23388ab..67998e72fa9 100644 --- a/imports/plugins/included/payments-example/client/settings/components/exampleSettingsForm.js +++ b/imports/plugins/included/payments-example/client/settings/components/exampleSettingsForm.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import _ from "lodash"; import { TextField, Translation, Checkbox } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/included/payments-example/client/settings/containers/exampleSettingsFormContainer.js b/imports/plugins/included/payments-example/client/settings/containers/exampleSettingsFormContainer.js index 274e00f6b2c..3836ef095de 100644 --- a/imports/plugins/included/payments-example/client/settings/containers/exampleSettingsFormContainer.js +++ b/imports/plugins/included/payments-example/client/settings/containers/exampleSettingsFormContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "/lib/api/compose"; import { Packages } from "/lib/collections"; diff --git a/imports/plugins/included/payments-example/lib/api/example.js b/imports/plugins/included/payments-example/lib/api/example.js index a5be08861f0..b89c3b8d1d6 100644 --- a/imports/plugins/included/payments-example/lib/api/example.js +++ b/imports/plugins/included/payments-example/lib/api/example.js @@ -1,3 +1,4 @@ +import { Meteor } from "meteor/meteor"; import { Packages } from "/lib/collections"; export const Example = { diff --git a/imports/plugins/included/payments-example/server/methods/exampleapi.js b/imports/plugins/included/payments-example/server/methods/exampleapi.js index 40bf01ca00f..bd4006b03c0 100644 --- a/imports/plugins/included/payments-example/server/methods/exampleapi.js +++ b/imports/plugins/included/payments-example/server/methods/exampleapi.js @@ -1,3 +1,6 @@ +import { ValidatedMethod } from "meteor/mdg:validated-method"; +import { SimpleSchema } from "meteor/aldeed:simple-schema"; +import { Random } from "meteor/random"; // You should not implement ThirdPartyAPI. It is supposed to represent your third party API // And is called so that it can be stubbed out for testing. This would be a library diff --git a/imports/plugins/included/payments-paypal/client/templates/checkout/express/checkoutButton.js b/imports/plugins/included/payments-paypal/client/templates/checkout/express/checkoutButton.js index 98e5d4db5f0..0e4e74b6f66 100644 --- a/imports/plugins/included/payments-paypal/client/templates/checkout/express/checkoutButton.js +++ b/imports/plugins/included/payments-paypal/client/templates/checkout/express/checkoutButton.js @@ -1,7 +1,10 @@ +/* global paypal */ import _ from "lodash"; import { Meteor } from "meteor/meteor"; import { Session } from "meteor/session"; +import { ReactiveDict } from "meteor/reactive-dict"; import { Template } from "meteor/templating"; +import { i18next } from "/client/api"; import { Cart } from "/lib/collections"; import { PaypalClientAPI } from "../../../lib/paypalRestApi"; import "./checkoutButton.html"; @@ -82,7 +85,7 @@ Template.paypalCheckoutButton.onRendered(function () { paypal.checkout.setup(expressCheckoutSettings.merchantId, { environment: expressCheckoutSettings.mode, button: element, - // Blank function to disable default paypal onClick functionality + // Blank function to disable default paypal onClick functionality click: function () {} }); this.state.set("isLoading", false); diff --git a/imports/plugins/included/payments-paypal/client/templates/checkout/payflow/payflowForm.js b/imports/plugins/included/payments-paypal/client/templates/checkout/payflow/payflowForm.js index 826ad612a53..7b16b698878 100644 --- a/imports/plugins/included/payments-paypal/client/templates/checkout/payflow/payflowForm.js +++ b/imports/plugins/included/payments-paypal/client/templates/checkout/payflow/payflowForm.js @@ -1,6 +1,8 @@ /* eslint camelcase: 0 */ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; +import { AutoForm } from "meteor/aldeed:autoform"; import Logger from "/client/modules/logger"; import { Cart, Shops, Packages } from "/lib/collections"; import { PaypalPayment } from "/imports/plugins/included/payments-paypal/lib/collections/schemas"; @@ -8,6 +10,7 @@ import { Reaction, i18next } from "/client/api"; import { PayPal } from "/imports/plugins/included/payments-paypal/lib/api"; import "./payflowForm.html"; +let submitting = false; function uiEnd(template, buttonText) { template.$(".cart-checkout-step *").removeAttr("disabled"); diff --git a/imports/plugins/included/payments-paypal/client/templates/checkout/return/done.js b/imports/plugins/included/payments-paypal/client/templates/checkout/return/done.js index 6c36af97bfc..e902acbc82e 100644 --- a/imports/plugins/included/payments-paypal/client/templates/checkout/return/done.js +++ b/imports/plugins/included/payments-paypal/client/templates/checkout/return/done.js @@ -2,6 +2,7 @@ import { Meteor } from "meteor/meteor"; import { Session } from "meteor/session"; import { Template } from "meteor/templating"; import { Tracker } from "meteor/tracker"; +import { $ } from "meteor/jquery"; import { Reaction } from "/client/api"; import { Cart, Packages } from "/lib/collections"; import Logger from "/client/modules/logger"; diff --git a/imports/plugins/included/payments-paypal/client/templates/settings/express.js b/imports/plugins/included/payments-paypal/client/templates/settings/express.js index 6173fbfc218..b5a8650acdc 100644 --- a/imports/plugins/included/payments-paypal/client/templates/settings/express.js +++ b/imports/plugins/included/payments-paypal/client/templates/settings/express.js @@ -1,5 +1,6 @@ /* eslint camelcase: 0 */ import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; import { Packages } from "/lib/collections"; import { PaypalPackageConfig } from "../../../lib/collections/schemas"; import "./express.html"; diff --git a/imports/plugins/included/payments-paypal/client/templates/settings/payflow.js b/imports/plugins/included/payments-paypal/client/templates/settings/payflow.js index c6a34f214b2..fc61034d22e 100644 --- a/imports/plugins/included/payments-paypal/client/templates/settings/payflow.js +++ b/imports/plugins/included/payments-paypal/client/templates/settings/payflow.js @@ -1,4 +1,5 @@ /* eslint camelcase: 0 */ +import { AutoForm } from "meteor/aldeed:autoform"; import { Template } from "meteor/templating"; import { Packages } from "/lib/collections"; import { PaypalPackageConfig } from "../../../lib/collections/schemas"; diff --git a/imports/plugins/included/payments-paypal/server/methods/express.js b/imports/plugins/included/payments-paypal/server/methods/express.js index df636108f09..5cc6e7abb74 100644 --- a/imports/plugins/included/payments-paypal/server/methods/express.js +++ b/imports/plugins/included/payments-paypal/server/methods/express.js @@ -255,7 +255,7 @@ export const methods = { } if (!response || response.statusCode !== 200) { - Logger.debug(error, "Bad Response from PayPal during Refund Creation"); + Logger.debug("Bad Response from PayPal during Refund Creation"); throw new Meteor.Error("Bad Response from PayPal during Refund Creation"); } diff --git a/imports/plugins/included/payments-paypal/server/methods/payflowproApi.js b/imports/plugins/included/payments-paypal/server/methods/payflowproApi.js index 94166707ac9..6287432835d 100644 --- a/imports/plugins/included/payments-paypal/server/methods/payflowproApi.js +++ b/imports/plugins/included/payments-paypal/server/methods/payflowproApi.js @@ -1,6 +1,7 @@ import PayFlow from "paypal-rest-sdk"; // PayFlow is PayPal PayFlow lib import moment from "moment"; import accounting from "accounting-js"; +import _ from "lodash"; import { Meteor } from "meteor/meteor"; import { Reaction, Logger } from "/server/api"; import { Shops } from "/lib/collections"; diff --git a/imports/plugins/included/payments-paypal/server/security/paypal.js b/imports/plugins/included/payments-paypal/server/security/paypal.js index c5963bd4540..9303ee2ad18 100644 --- a/imports/plugins/included/payments-paypal/server/security/paypal.js +++ b/imports/plugins/included/payments-paypal/server/security/paypal.js @@ -1,3 +1,5 @@ +import { BrowserPolicy } from "meteor/browser-policy-common"; + BrowserPolicy.content.allowEval(); BrowserPolicy.content.allowOriginForAll("http://www.paypal.com"); BrowserPolicy.content.allowOriginForAll("http://www.paypalobjects.com"); diff --git a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js index 00ca0cc8d92..f26bbf21a44 100644 --- a/imports/plugins/included/payments-stripe-connect/client/settings/settings.js +++ b/imports/plugins/included/payments-stripe-connect/client/settings/settings.js @@ -1,4 +1,6 @@ import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; +import { Meteor } from "meteor/meteor"; import { Reaction, i18next, Router } from "/client/api"; import { Packages } from "/lib/collections"; import { StripeConnectPackageConfig } from "../../lib/collections/schemas"; @@ -22,7 +24,7 @@ AutoForm.hooks({ onSuccess: function () { return Alerts.toast(i18next.t("admin.settings.saveSuccess"), "success"); }, - onError: function () { + onError: function (error) { return Alerts.toast(`${i18next.t("admin.settings.saveFailed")} ${error}`, "error"); } } diff --git a/imports/plugins/included/payments-stripe-connect/server/methods/methods.js b/imports/plugins/included/payments-stripe-connect/server/methods/methods.js index de884c41f4f..4b26a3bf529 100644 --- a/imports/plugins/included/payments-stripe-connect/server/methods/methods.js +++ b/imports/plugins/included/payments-stripe-connect/server/methods/methods.js @@ -1,7 +1,8 @@ import { Meteor } from "meteor/meteor"; import { HTTP } from "meteor/http"; import { check } from "meteor/check"; -import { Shops } from "/lib/collections"; // TODO: Should this be SellerShops? +import { Logger } from "/server/api"; +import { Shops, Packages } from "/lib/collections"; // TODO: Should this be SellerShops? Meteor.methods({ // TODO: Review all of this code for functionality diff --git a/imports/plugins/included/payments-stripe/client/checkout/stripe.js b/imports/plugins/included/payments-stripe/client/checkout/stripe.js index 90a3d7df01f..f251dc1b4f6 100644 --- a/imports/plugins/included/payments-stripe/client/checkout/stripe.js +++ b/imports/plugins/included/payments-stripe/client/checkout/stripe.js @@ -2,6 +2,7 @@ import { Meteor } from "meteor/meteor"; import { Template } from "meteor/templating"; import { AutoForm } from "meteor/aldeed:autoform"; +import { $ } from "meteor/jquery"; import { getCardType } from "/client/modules/core/helpers/globals"; import { Reaction } from "/client/api"; import { Cart, SellerShops, Packages } from "/lib/collections"; @@ -30,12 +31,15 @@ function hidePaymentAlert() { } function handleStripeSubmitError(error) { - const singleError = error; - const serverError = error ? error.message : null; - if (serverError) { - return paymentAlert("Oops! Credit card is invalid. Please check your information and try again."); - } else if (singleError) { - return paymentAlert("Oops! " + singleError); + // Match eror on card number. Not submitted to stripe + if (error && error.reason && error.reason === "Match failed") { + const message = "Your card number is invalid. Please check the number and try again"; + return paymentAlert(message); + } + + // this is a server message with a client-sanitized message + if (error && error.details) { + return paymentAlert(error.details); } } diff --git a/imports/plugins/included/payments-stripe/client/settings/stripe.js b/imports/plugins/included/payments-stripe/client/settings/stripe.js index e8574e35921..a3be99041dd 100644 --- a/imports/plugins/included/payments-stripe/client/settings/stripe.js +++ b/imports/plugins/included/payments-stripe/client/settings/stripe.js @@ -1,4 +1,5 @@ import { Template } from "meteor/templating"; +import { AutoForm } from "meteor/aldeed:autoform"; import { Reaction, i18next } from "/client/api"; import { Packages } from "/lib/collections"; import { StripePackageConfig } from "../../lib/collections/schemas"; @@ -37,7 +38,7 @@ AutoForm.hooks({ onSuccess: function () { return Alerts.toast(i18next.t("admin.settings.saveSuccess"), "success"); }, - onError: function () { + onError: function (error) { return Alerts.toast(`${i18next.t("admin.settings.saveFailed")} ${error}`, "error"); } } diff --git a/imports/plugins/included/payments-stripe/lib/api/stripe.js b/imports/plugins/included/payments-stripe/lib/api/stripe.js index ee71b23c21a..b2529efe444 100644 --- a/imports/plugins/included/payments-stripe/lib/api/stripe.js +++ b/imports/plugins/included/payments-stripe/lib/api/stripe.js @@ -1,8 +1,9 @@ -/* eslint camelcase: 0 */ import { Meteor } from "meteor/meteor"; export const Stripe = { authorize: function (cardData, paymentInfo, callback) { - Meteor.call("stripeSubmit", "authorize", cardData, paymentInfo, callback); + Meteor.call("stripeSubmit", "authorize", cardData, paymentInfo, (error, result) => { + callback(error, result); + }); } }; diff --git a/imports/plugins/included/payments-stripe/server/methods/stripe.js b/imports/plugins/included/payments-stripe/server/methods/stripe.js index 0c385b48f91..1374d10eb20 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripe.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripe.js @@ -153,16 +153,16 @@ Meteor.methods({ try { chargeResult = StripeApi.methods.createCharge.call({ chargeObj }); - if (chargeResult && chargeResult.status === "succeeded") { + if (chargeResult && chargeResult.status && chargeResult.status === "succeeded") { result = { saved: true, response: chargeResult }; } else { - Logger.debug("Stripe Call succeeded but charge failed"); + Logger.error("Stripe Call succeeded but charge failed"); result = { saved: false, - error: chargeResult.error.message + error: chargeResult.error }; } return result; diff --git a/imports/plugins/included/payments-stripe/server/methods/stripeapi-methods-charge.app-test.js b/imports/plugins/included/payments-stripe/server/methods/stripeapi-methods-charge.app-test.js index 17498ca295b..9f8d587d3f9 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripeapi-methods-charge.app-test.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripeapi-methods-charge.app-test.js @@ -185,7 +185,7 @@ describe("Stripe.authorize", function () { expect(chargeResult).to.not.be.undefined; expect(chargeResult.saved).to.be.false; - expect(chargeResult.error).to.equal("Your card was declined."); + expect(chargeResult.error.message).to.equal("Your card was declined."); expect(StripeApi.methods.createCharge.call).to.have.been.calledWith({ chargeObj: { amount: 2298, @@ -260,7 +260,7 @@ describe("Stripe.authorize", function () { chargeResult = result; expect(chargeResult).to.not.be.undefined; expect(chargeResult.saved).to.be.false; - expect(chargeResult.error).to.equal("Your card has expired."); + expect(chargeResult.error.message).to.equal("Your card has expired."); expect(StripeApi.methods.createCharge.call).to.have.been.calledWith({ chargeObj: { amount: 2298, diff --git a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js index 6fbba0e69c1..7a0b3e42e2d 100644 --- a/imports/plugins/included/payments-stripe/server/methods/stripeapi.js +++ b/imports/plugins/included/payments-stripe/server/methods/stripeapi.js @@ -1,5 +1,6 @@ /* eslint camelcase: 0 */ import _ from "lodash"; +import { ValidatedMethod } from "meteor/mdg:validated-method"; import { Meteor } from "meteor/meteor"; import { SimpleSchema } from "meteor/aldeed:simple-schema"; import { Reaction, Logger } from "/server/api"; @@ -81,11 +82,19 @@ StripeApi.methods.createCharge = new ValidatedMethod({ // Handle "expected" errors differently if (e.rawType === "card_error" && _.includes(expectedErrors, e.code)) { Logger.debug("Error from Stripe is expected, not throwing"); - return { error: e, result: null }; + const normalizedError = { + details: e.message + }; + return { error: normalizedError, result: null }; } - Logger.error("Received unexpected error code: " + e.code); + Logger.error("Received unexpected error type: " + e.rawType); Logger.error(e); - return { error: e, result: null }; + + // send raw error to server log, but sanitized version to client + const sanitisedError = { + details: "An unexpected error has occurred" + }; + return { error: sanitisedError, result: null }; } } }); diff --git a/imports/plugins/included/product-admin/client/components/productAdmin.js b/imports/plugins/included/product-admin/client/components/productAdmin.js index 7dbdaf0d57d..52ecf8c9e2e 100644 --- a/imports/plugins/included/product-admin/client/components/productAdmin.js +++ b/imports/plugins/included/product-admin/client/components/productAdmin.js @@ -1,5 +1,6 @@ import { isEqual } from "lodash"; -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Velocity from "velocity-animate"; import "velocity-animate/velocity.ui"; import { diff --git a/imports/plugins/included/product-admin/client/containers/productAdminContainer.js b/imports/plugins/included/product-admin/client/containers/productAdminContainer.js index ef7e9626636..548e7ca301f 100644 --- a/imports/plugins/included/product-admin/client/containers/productAdminContainer.js +++ b/imports/plugins/included/product-admin/client/containers/productAdminContainer.js @@ -1,5 +1,8 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import update from "react/lib/update"; +import _ from "lodash"; +import { Meteor } from "meteor/meteor"; import { Reaction } from "/client/api"; import { composeWithTracker } from "/lib/api/compose"; import { ReactionProduct } from "/lib/api"; diff --git a/imports/plugins/included/product-admin/client/templates/productAdmin.js b/imports/plugins/included/product-admin/client/templates/productAdmin.js index 3b03a0107c5..d88c5832a5b 100644 --- a/imports/plugins/included/product-admin/client/templates/productAdmin.js +++ b/imports/plugins/included/product-admin/client/templates/productAdmin.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import { ProductAdminContainer } from "../containers"; Template.ProductAdmin.helpers({ diff --git a/imports/plugins/included/product-detail-simple/client/components/addToCartButton.js b/imports/plugins/included/product-detail-simple/client/components/addToCartButton.js index 54baf62c45a..47164e5a79e 100644 --- a/imports/plugins/included/product-detail-simple/client/components/addToCartButton.js +++ b/imports/plugins/included/product-detail-simple/client/components/addToCartButton.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Alert, Translation } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/included/product-detail-simple/client/components/childVariant.js b/imports/plugins/included/product-detail-simple/client/components/childVariant.js index 6405b9e931f..c5334b89e07 100644 --- a/imports/plugins/included/product-detail-simple/client/components/childVariant.js +++ b/imports/plugins/included/product-detail-simple/client/components/childVariant.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Translation } from "/imports/plugins/core/ui/client/components"; import { MediaItem } from "/imports/plugins/core/ui/client/components"; diff --git a/imports/plugins/included/product-detail-simple/client/components/metadata.js b/imports/plugins/included/product-detail-simple/client/components/metadata.js index 02d6d382d7c..94265beb989 100644 --- a/imports/plugins/included/product-detail-simple/client/components/metadata.js +++ b/imports/plugins/included/product-detail-simple/client/components/metadata.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Metadata, Translation } from "/imports/plugins/core/ui/client/components/"; import { EditContainer } from "/imports/plugins/core/ui/client/containers"; diff --git a/imports/plugins/included/product-detail-simple/client/components/productDetail.js b/imports/plugins/included/product-detail-simple/client/components/productDetail.js index f1ade4cf46d..f3fe9d8507e 100644 --- a/imports/plugins/included/product-detail-simple/client/components/productDetail.js +++ b/imports/plugins/included/product-detail-simple/client/components/productDetail.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { AlertContainer } from "/imports/plugins/core/ui/client/containers"; import { ReactionLayout } from "/imports/plugins/core/layout/lib"; diff --git a/imports/plugins/included/product-detail-simple/client/components/productField.js b/imports/plugins/included/product-detail-simple/client/components/productField.js index 173d9900d25..1874b7bfaa7 100644 --- a/imports/plugins/included/product-detail-simple/client/components/productField.js +++ b/imports/plugins/included/product-detail-simple/client/components/productField.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import Velocity from "velocity-animate"; import "velocity-animate/velocity.ui"; diff --git a/imports/plugins/included/product-detail-simple/client/components/tags.js b/imports/plugins/included/product-detail-simple/client/components/tags.js index eb349fbc48f..8ee8ee0f52e 100644 --- a/imports/plugins/included/product-detail-simple/client/components/tags.js +++ b/imports/plugins/included/product-detail-simple/client/components/tags.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Translation } from "/imports/plugins/core/ui/client/components/"; import { TagListContainer, EditContainer } from "/imports/plugins/core/ui/client/containers"; diff --git a/imports/plugins/included/product-detail-simple/client/components/variant.js b/imports/plugins/included/product-detail-simple/client/components/variant.js index 0a3d6a08d4f..f6aa5120c7f 100644 --- a/imports/plugins/included/product-detail-simple/client/components/variant.js +++ b/imports/plugins/included/product-detail-simple/client/components/variant.js @@ -1,10 +1,10 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import classnames from "classnames"; import { Currency, Translation } from "/imports/plugins/core/ui/client/components"; import { SortableItem } from "/imports/plugins/core/ui/client/containers"; class Variant extends Component { - handleClick = (event) => { if (this.props.onClick) { this.props.onClick(event, this.props.variant); diff --git a/imports/plugins/included/product-detail-simple/client/components/variantList.js b/imports/plugins/included/product-detail-simple/client/components/variantList.js index 6f810e058f9..62aa86a70e5 100644 --- a/imports/plugins/included/product-detail-simple/client/components/variantList.js +++ b/imports/plugins/included/product-detail-simple/client/components/variantList.js @@ -1,11 +1,11 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import Variant from "./variant"; import { EditContainer } from "/imports/plugins/core/ui/client/containers"; import { Divider, IconButton } from "/imports/plugins/core/ui/client/components"; import { ChildVariant } from "./"; class VariantList extends Component { - handleVariantEditClick = (event, editButtonProps) => { if (this.props.onEditVariant) { return this.props.onEditVariant(event, editButtonProps.data); diff --git a/imports/plugins/included/product-detail-simple/client/containers/productDetailContainer.js b/imports/plugins/included/product-detail-simple/client/containers/productDetailContainer.js index e14e743e5d6..f9d27ec3792 100644 --- a/imports/plugins/included/product-detail-simple/client/containers/productDetailContainer.js +++ b/imports/plugins/included/product-detail-simple/client/containers/productDetailContainer.js @@ -1,8 +1,11 @@ +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { isEmpty } from "lodash"; +import _ from "lodash"; import { StyleRoot } from "radium"; -import React, { Component, PropTypes } from "react"; -import { composeWithTracker } from "/lib/api/compose"; +import { $ } from "meteor/jquery"; import { Meteor } from "meteor/meteor"; +import { composeWithTracker } from "/lib/api/compose"; import { ReactionProduct } from "/lib/api"; import { Reaction, i18next, Logger } from "/client/api"; import { Tags, Media, Cart } from "/lib/collections"; diff --git a/imports/plugins/included/product-detail-simple/client/containers/publishContainer.js b/imports/plugins/included/product-detail-simple/client/containers/publishContainer.js index 021a230e823..ef6ba9edea0 100644 --- a/imports/plugins/included/product-detail-simple/client/containers/publishContainer.js +++ b/imports/plugins/included/product-detail-simple/client/containers/publishContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "/lib/api/compose"; import { Router } from "/client/api"; diff --git a/imports/plugins/included/product-detail-simple/client/containers/socialContainer.js b/imports/plugins/included/product-detail-simple/client/containers/socialContainer.js index 08a274f9333..8b24bb4271b 100644 --- a/imports/plugins/included/product-detail-simple/client/containers/socialContainer.js +++ b/imports/plugins/included/product-detail-simple/client/containers/socialContainer.js @@ -1,4 +1,5 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; import { composeWithTracker } from "/lib/api/compose"; import { ReactionProduct } from "/lib/api"; import SocialButtons from "/imports/plugins/included/social/client/components/socialButtons"; diff --git a/imports/plugins/included/product-detail-simple/client/containers/variantListContainer.js b/imports/plugins/included/product-detail-simple/client/containers/variantListContainer.js index 99258edf01a..527f678591a 100644 --- a/imports/plugins/included/product-detail-simple/client/containers/variantListContainer.js +++ b/imports/plugins/included/product-detail-simple/client/containers/variantListContainer.js @@ -1,4 +1,7 @@ -import React, { Component, PropTypes } from "react"; +import React, { Component } from "react"; +import PropTypes from "prop-types"; +import { Session } from "meteor/session"; +import { Meteor } from "meteor/meteor"; import { composeWithTracker } from "/lib/api/compose"; import { ReactionProduct } from "/lib/api"; import { Reaction, i18next } from "/client/api"; diff --git a/imports/plugins/included/product-detail-simple/client/templates/productDetailSimple.js b/imports/plugins/included/product-detail-simple/client/templates/productDetailSimple.js index c87f7a5487a..aba0b3541be 100644 --- a/imports/plugins/included/product-detail-simple/client/templates/productDetailSimple.js +++ b/imports/plugins/included/product-detail-simple/client/templates/productDetailSimple.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import { ProductDetailContainer, PublishContainer } from "../containers"; Template.productDetailSimple.helpers({ diff --git a/imports/plugins/included/product-variant/client/index.js b/imports/plugins/included/product-variant/client/index.js index 41094fc66e0..c394cc3f44f 100644 --- a/imports/plugins/included/product-variant/client/index.js +++ b/imports/plugins/included/product-variant/client/index.js @@ -15,16 +15,6 @@ import "./templates/products/productDetail/productImageGallery.js"; import "./templates/products/productDetail/social.html"; import "./templates/products/productDetail/social.js"; -import "./templates/products/productGrid/content.html"; -import "./templates/products/productGrid/content.js"; -import "./templates/products/productGrid/controls.html"; -import "./templates/products/productGrid/controls.js"; -import "./templates/products/productGrid/item.html"; -import "./templates/products/productGrid/item.js"; -import "./templates/products/productGrid/notice.html"; -import "./templates/products/productGrid/notice.js"; -import "./templates/products/productGrid/productGrid.html"; -import "./templates/products/productGrid/productGrid.js"; import "./templates/products/productGrid/publishControls.html"; import "./templates/products/productGrid/publishControls.js"; diff --git a/imports/plugins/included/product-variant/client/templates/products/productDetail/edit.js b/imports/plugins/included/product-variant/client/templates/products/productDetail/edit.js index f313c8f3694..7ef3e686bf9 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productDetail/edit.js +++ b/imports/plugins/included/product-variant/client/templates/products/productDetail/edit.js @@ -1,9 +1,11 @@ import autosize from "autosize"; -import { Reaction, i18next, Logger } from "/client/api"; -import { ReactionProduct } from "/lib/api"; import { Meteor } from "meteor/meteor"; import { Session } from "meteor/session"; import { Template } from "meteor/templating"; +import { $ } from "meteor/jquery"; +import { Reaction, i18next, Logger } from "/client/api"; +import { ReactionProduct } from "/lib/api"; + /** * productDetailEdit helpers diff --git a/imports/plugins/included/product-variant/client/templates/products/productDetail/productImageGallery.js b/imports/plugins/included/product-variant/client/templates/products/productDetail/productImageGallery.js index 9628b483156..315f05535c6 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productDetail/productImageGallery.js +++ b/imports/plugins/included/product-variant/client/templates/products/productDetail/productImageGallery.js @@ -37,7 +37,7 @@ function uploadHandler(event) { // But how do we know that this is the first, not second or other variant? // Question is open. For now if product has more than 1 top variant, everyone // will have a chance to be displayed - const toGrid = variant.ancestors.length === 1; + const toGrid = variant.ancestors.length >= 1; return FS.Utility.eachFile(event, function (file) { const fileObj = new FS.File(file); @@ -146,9 +146,9 @@ Template.productImageGallery.events({ "click .remove-image": function () { const imageUrl = $(event.target) - .closest(".gallery-image") - .find("img") - .attr("src"); + .closest(".gallery-image") + .find("img") + .attr("src"); Alerts.alert({ title: "Remove Media?", diff --git a/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/childVariant.js b/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/childVariant.js index 1f8fa7e0af8..3fbfcb2973b 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/childVariant.js +++ b/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/childVariant.js @@ -1,3 +1,6 @@ +import { $ } from "meteor/jquery"; +import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; import { Reaction, i18next } from "/client/api"; import { ReactionProduct } from "/lib/api"; import { Media } from "/lib/collections"; diff --git a/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/variantForm.js b/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/variantForm.js index a32e6745f9f..c38cca4fb88 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/variantForm.js +++ b/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantForm/variantForm.js @@ -6,7 +6,7 @@ import { Reaction, i18next } from "/client/api"; import { ReactionProduct } from "/lib/api"; import { applyProductRevision } from "/lib/api/products"; import { Products } from "/lib/collections"; -import VariantFormContainer from "../../../../../containers/variantFormContainer"; +import VariantFormContainer from "/imports/plugins/included/product-variant/containers/variantFormContainer"; Template.variantForm.onCreated(function () { this.state = new ReactiveDict(); diff --git a/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantList/variantList.js b/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantList/variantList.js index 67e532223be..ccdb39d035f 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantList/variantList.js +++ b/imports/plugins/included/product-variant/client/templates/products/productDetail/variants/variantList/variantList.js @@ -1,4 +1,6 @@ import Sortable from "sortablejs"; +import { $ } from "meteor/jquery"; +import { Tracker } from "meteor/tracker"; import { Meteor } from "meteor/meteor"; import { Session } from "meteor/session"; import { Template } from "meteor/templating"; diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/content.html b/imports/plugins/included/product-variant/client/templates/products/productGrid/content.html deleted file mode 100644 index ca5439f99bd..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/content.html +++ /dev/null @@ -1,10 +0,0 @@ - diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/content.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/content.js deleted file mode 100644 index 30ddfe466e9..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/content.js +++ /dev/null @@ -1,33 +0,0 @@ -import { Reaction } from "/client/api"; - -/** - * gridContent helpers - */ - -Template.gridContent.helpers({ - pdpPath() { - const instance = Template.instance(); - const product = instance.data; - - if (product) { - let handle = product.handle; - - if (product.__published) { - handle = product.__published.handle; - } - - return Reaction.Router.pathFor("product", { - hash: { - handle - } - }); - } - - return "/"; - }, - displayPrice: function () { - if (this.price && this.price.range) { - return this.price.range; - } - } -}); diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js index 38086f52080..5fa3f16ce46 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js +++ b/imports/plugins/included/product-variant/client/templates/products/productGrid/controls.js @@ -1,7 +1,8 @@ -import { Reaction } from "/lib/api"; +import _ from "lodash"; import { Session } from "meteor/session"; import { Template } from "meteor/templating"; import { ReactiveDict } from "meteor/reactive-dict"; +import { Reaction } from "/lib/api"; import { IconButton } from "/imports/plugins/core/ui/client/components"; Template.gridControls.onCreated(function () { @@ -43,7 +44,7 @@ Template.gridControls.helpers({ const shopId = Reaction.getShopId(); return ( - Reaction.hasPermission("createProduct") && + Reaction.hasPermission("createProduct") && // does product belong to this shop seller shopId === instance.data.product.shopId ); diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/item.html b/imports/plugins/included/product-variant/client/templates/products/productGrid/item.html deleted file mode 100644 index 6a814302464..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/item.html +++ /dev/null @@ -1,49 +0,0 @@ - diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/item.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/item.js deleted file mode 100644 index 5f69121239c..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/item.js +++ /dev/null @@ -1,298 +0,0 @@ -import _ from "lodash"; -import { Meteor } from "meteor/meteor"; -import { Session } from "meteor/session"; -import { Template } from "meteor/templating"; -import { Tracker } from "meteor/tracker"; -import { $ } from "meteor/jquery"; -import { Reaction } from "/client/api"; -import Logger from "/client/modules/logger"; -import { ReactionProduct } from "/lib/api"; -import { Media } from "/lib/collections"; -import { isRevisionControlEnabled } from "/imports/plugins/core/revisions/lib/api"; - - -Template.productGridItems.onRendered(function () { - $(".page > main").on("click", function (event) { - // Do nothing if we are in preview mode - if (Reaction.isPreview() === false) { - // Don't trigger the clear selectiion if we're clicking on a grid item. - if ($(event.target).closest(".product-grid-item").length === 0) { - const selectedProducts = Session.get("productGrid/selectedProducts"); - - // Do we have any selected products? - // If we do then lets reset the Grid Settings ActionView - if (Array.isArray(selectedProducts) && selectedProducts.length) { - // Reset sessions ver of selected products - Session.set("productGrid/selectedProducts", []); - - // Reset the action view of selected products - Reaction.setActionView({ - label: "Grid Settings", - i18nKeyLabel: "gridSettingsPanel.title", - template: "productSettings", - type: "product", - data: {} - }); - } - } - } - }); -}); - -Template.productGridItems.onDestroyed(function () { - $(".page > main").off("click"); -}); - -/** - * productGridItems helpers - */ - -Template.productGridItems.helpers({ - pdpPath() { - const instance = Template.instance(); - const product = instance.data; - - if (product) { - let handle = product.handle; - - if (product.__published) { - handle = product.__published.handle; - } - - return Reaction.Router.pathFor("product", { - hash: { - handle - } - }); - } - - return "/"; - }, - - controlProps() { - const instance = Template.instance(); - - return { - product: instance.data, - onEditButtonClick() { - const data = instance.data; - - const $checkbox = instance.$(`input[type=checkbox][value=${data._id}]`); - - Session.set("productGrid/selectedProducts", []); - $checkbox.prop("checked", true).trigger("change"); - }, - onPublishButtonClick() { - if (isRevisionControlEnabled()) { - Meteor.call("products/updateProductField", instance.data._id, "isVisible", !instance.data.isVisible); - } else { - ReactionProduct.publishProduct(instance.data); - } - } - }; - }, - media: function () { - const media = Media.findOne({ - "metadata.productId": this._id, - "metadata.toGrid": 1 - }, { - sort: { "metadata.priority": 1, "uploadedAt": 1 } - }); - - return media instanceof FS.File ? media : false; - }, - additionalMedia: function () { - const mediaArray = Media.find({ - "metadata.productId": this._id, - "metadata.priority": { - $gt: 0 - }, - "metadata.toGrid": 1 - }, { limit: 3 }); - - if (mediaArray.count() > 1) { - return mediaArray; - } - - return false; - }, - weightClass: function () { - const tag = ReactionProduct.getTag(); - const positions = this.positions && this.positions[tag] || {}; - const weight = positions.weight || 0; - switch (weight) { - case 1: - return "product-medium"; - case 2: - return "product-large"; - default: - return "product-small"; - } - }, - isSelected: function () { - if (Reaction.isPreview() === false) { - return _.includes(Session.get("productGrid/selectedProducts"), this._id) ? "active" : ""; - } - return false; - }, - isMediumWeight: function () { - const tag = ReactionProduct.getTag(); - const positions = this.positions && this.positions[tag] || {}; - const weight = positions.weight || 0; - - return weight === 1; - }, - isLargeWeight: function () { - const tag = ReactionProduct.getTag(); - const positions = this.positions && this.positions[tag] || {}; - const weight = positions.weight || 0; - - return weight === 3; - }, - // TODO is it used? - shouldShowAdditionalImages: function () { - if (this.isMediumWeight && this.mediaArray) { - return true; - } - return false; - }, - // this is needed to get `pinned` from the item template - positions() { - const tag = ReactionProduct.getTag(); - return this.positions && this.positions[tag] || {}; - } -}); - -/** - * productGridItems events - */ - -Template.productGridItems.events({ - "dblclick [data-event-action=productClick]": function (event, template) { - const instance = template; - const product = instance.data; - const handle = product.__published && product.__published.handle || product.handle; - - Reaction.Router.go("product", { - handle: handle - }); - - Reaction.setActionView({ - i18nKeyLabel: "productDetailEdit.productSettings", - label: "Product Settings", - template: "ProductAdmin" - }); - }, - "click [data-event-action=productClick]": function (event, template) { - if (Reaction.hasPermission("createProduct") && Reaction.isPreview() === false) { - event.preventDefault(); - - const isSelected = $(event.target).closest("li.product-grid-item.active").length; - - if (isSelected) { - // If product is already selected, and you are single clicking WITH command key, things whould happen - if (event.metaKey || event.ctrlKey || event.shiftKey) { - let $checkbox = template.$(`input[type=checkbox][value=${this._id}]`); - const $items = $("li.product-grid-item"); - const $activeItems = $("li.product-grid-item.active"); - const selected = $activeItems.length; - - if (event.shiftKey && selected > 0) { - const indexes = [ - $items.index($checkbox.parents("li.product-grid-item")), - $items.index($activeItems.get(0)), - $items.index($activeItems.get(selected - 1)) - ]; - for (let i = _.min(indexes); i <= _.max(indexes); i++) { - $checkbox = $("input[type=checkbox]", $items.get(i)); - if ($checkbox.prop("checked") === false) { - $checkbox.prop("checked", true).trigger("change"); - } - } - } else { - $checkbox.prop("checked", !$checkbox.prop("checked")).trigger("change"); - } - } - } else { - if (event.metaKey || event.ctrlKey || event.shiftKey) { - let $checkbox = template.$(`input[type=checkbox][value=${this._id}]`); - const $items = $("li.product-grid-item"); - const $activeItems = $("li.product-grid-item.active"); - const selected = $activeItems.length; - - if (event.shiftKey && selected > 0) { - const indexes = [ - $items.index($checkbox.parents("li.product-grid-item")), - $items.index($activeItems.get(0)), - $items.index($activeItems.get(selected - 1)) - ]; - for (let i = _.min(indexes); i <= _.max(indexes); i++) { - $checkbox = $("input[type=checkbox]", $items.get(i)); - if ($checkbox.prop("checked") === false) { - $checkbox.prop("checked", true).trigger("change"); - } - } - } else { - $checkbox.prop("checked", !$checkbox.prop("checked")).trigger("change"); - } - } else { - const $checkbox = template.$(`input[type=checkbox][value=${this._id}]`); - - Session.set("productGrid/selectedProducts", []); - $checkbox.prop("checked", true).trigger("change"); - } - } - } else { - event.preventDefault(); - - const instance = template; - const product = instance.data; - const handle = product.__published && product.__published.handle || product.handle; - - Reaction.Router.go("product", { - handle: handle - }); - } - }, - "click [data-event-action=selectSingleProduct]": function (event, template) { - event.preventDefault(); - const { data } = Template.instance(); - - const $checkbox = template.$(`input[type=checkbox][value=${data._id}]`); - - Session.set("productGrid/selectedProducts", []); - $checkbox.prop("checked", true).trigger("change"); - }, - "click .publish-product"(event, instance) { - ReactionProduct.publishProduct(instance.data); - }, - "click .delete-product": function (event) { - event.preventDefault(); - ReactionProduct.archiveProduct(this); - }, - "click .update-product-weight": function (event) { - event.preventDefault(); - - const tag = ReactionProduct.getTag(); - const positions = this.positions && this.positions[tag] || {}; - let weight = positions.weight || 0; - - if (weight < 2) { - weight++; - } else { - weight = 0; - } - - const position = { - weight: weight, - updatedAt: new Date() - }; - Meteor.call("products/updateProductPosition", this._id, position, tag, error => { - if (error) { - Logger.warn(error); - throw new Meteor.Error(403, error); - } - }); - return Tracker.flush(); - } -}); diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.html b/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.html deleted file mode 100644 index d1dfd174d81..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.html +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js deleted file mode 100644 index bcbceb5058d..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/notice.js +++ /dev/null @@ -1,35 +0,0 @@ -import { ReactionProduct } from "/lib/api"; - -/** - * gridNotice helpers - */ -Template.gridNotice.helpers({ - isLowQuantity: function () { - const topVariants = ReactionProduct.getTopVariants(this._id); - - for (const topVariant of topVariants) { - const inventoryThreshold = topVariant.lowInventoryWarningThreshold; - const inventoryQuantity = ReactionProduct.getVariantQuantity(topVariant); - - if (inventoryQuantity !== 0 && inventoryThreshold >= inventoryQuantity) { - return true; - } - } - return false; - }, - isSoldOut: function () { - const topVariants = ReactionProduct.getTopVariants(this._id); - - for (const topVariant of topVariants) { - const inventoryQuantity = ReactionProduct.getVariantQuantity(topVariant); - - if (inventoryQuantity > 0) { - return false; - } - } - return true; - }, - isBackorder: function () { - return this.isBackorder; - } -}); diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/productGrid.html b/imports/plugins/included/product-variant/client/templates/products/productGrid/productGrid.html deleted file mode 100644 index f8abd4c69a8..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/productGrid.html +++ /dev/null @@ -1,19 +0,0 @@ - diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/productGrid.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/productGrid.js deleted file mode 100644 index e59f483e855..00000000000 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/productGrid.js +++ /dev/null @@ -1,126 +0,0 @@ -import _ from "lodash"; -import { Session } from "meteor/session"; -import { Template } from "meteor/templating"; -import { Reaction } from "/client/api"; -import Logger from "/client/modules/logger"; -import { ReactionProduct } from "/lib/api"; -import Sortable from "sortablejs"; - -/** - * productGrid helpers - */ - -Template.productGrid.onCreated(function () { - const selectedProducts = Reaction.getUserPreferences("reaction-product-variant", "selectedGridItems"); - - if (_.isEmpty(selectedProducts)) { - Reaction.hideActionView(); - } else { - // Save the selected items to the Session - Session.set("productGrid/selectedProducts", _.uniq(selectedProducts)); - - const products = Template.currentData().products; - - if (products) { - const filteredProducts = _.filter(products, (product) => { - return _.includes(selectedProducts, product._id); - }); - - if (Reaction.isPreview() === false) { - Reaction.showActionView({ - label: "Grid Settings", - i18nKeyLabel: "gridSettingsPanel.title", - template: "productSettings", - type: "product", - data: { - products: filteredProducts - } - }); - } - } - } -}); - -Template.productGrid.onRendered(function () { - const instance = this; - - if (Reaction.hasPermission("createProduct")) { - const productSort = $(".product-grid-list")[0]; - - this.sortable = Sortable.create(productSort, { - group: "products", - handle: ".product-grid-item", - onUpdate() { - const tag = ReactionProduct.getTag(); - - instance.$(".product-grid-item") - .toArray() - .map((element, index) => { - const productId = element.getAttribute("id"); - const position = { - position: index, - updatedAt: new Date() - }; - - Meteor.call("products/updateProductPosition", productId, position, tag, - error => { - if (error) { - Logger.warn(error); - throw new Meteor.Error(403, error); - } - }); - }); - - Tracker.flush(); - } - }); - } -}); - -Template.productGrid.events({ - "click [data-event-action=loadMoreProducts]": (event) => { - event.preventDefault(); - loadMoreProducts(); - }, - "change input[name=selectProduct]": (event) => { - let selectedProducts = Session.get("productGrid/selectedProducts"); - - if (event.target.checked) { - selectedProducts.push(event.target.value); - } else { - selectedProducts = _.without(selectedProducts, event.target.value); - } - - Reaction.setUserPreferences("reaction-product-variant", "selectedGridItems", selectedProducts); - - // Save the selected items to the Session - Session.set("productGrid/selectedProducts", _.uniq(selectedProducts)); - - const products = Template.currentData().products; - - if (products) { - const filteredProducts = _.filter(products, (product) => { - return _.includes(selectedProducts, product._id); - }); - - Reaction.showActionView({ - label: "Grid Settings", - i18nKeyLabel: "gridSettingsPanel.title", - template: "productSettings", - type: "product", - data: { - products: filteredProducts - } - }); - } - } -}); - -Template.productGrid.helpers({ - loadMoreProducts() { - return Template.instance().state.equals("canLoadMoreProducts", true); - }, - products() { - return Template.currentData().products; - } -}); diff --git a/imports/plugins/included/product-variant/client/templates/products/productGrid/publishControls.js b/imports/plugins/included/product-variant/client/templates/products/productGrid/publishControls.js index 1989becf28b..c3a6e2efdb7 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productGrid/publishControls.js +++ b/imports/plugins/included/product-variant/client/templates/products/productGrid/publishControls.js @@ -1,4 +1,5 @@ -import GridPublishContainer from "../../../containers/gridPublishContainer"; +import { Template } from "meteor/templating"; +import GridPublishContainer from "/imports/plugins/included/product-variant/containers/gridPublishContainer"; Template.gridPublishControls.helpers({ PublishComponent() { diff --git a/imports/plugins/included/product-variant/client/templates/products/productList/productList.js b/imports/plugins/included/product-variant/client/templates/products/productList/productList.js index b2f9820bb51..37f9f0fc6ca 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productList/productList.js +++ b/imports/plugins/included/product-variant/client/templates/products/productList/productList.js @@ -1,3 +1,4 @@ +import { Template } from "meteor/templating"; import { ReactionProduct } from "/lib/api"; import { Media } from "/lib/collections"; @@ -11,7 +12,7 @@ Template.productList.helpers({ }, media: function () { let defaultImage; - const variants = getTopVariants(); + const variants = ReactionProduct.getTopVariants(); if (variants.length > 0) { const variantId = variants[0]._id; defaultImage = Media.findOne({ diff --git a/imports/plugins/included/product-variant/client/templates/products/productSettings/productSettings.js b/imports/plugins/included/product-variant/client/templates/products/productSettings/productSettings.js index 5fcebd40335..7a18db82307 100644 --- a/imports/plugins/included/product-variant/client/templates/products/productSettings/productSettings.js +++ b/imports/plugins/included/product-variant/client/templates/products/productSettings/productSettings.js @@ -1,4 +1,6 @@ import _ from "lodash"; +import { Template } from "meteor/templating"; +import { Meteor } from "meteor/meteor"; import { ReactiveDict } from "meteor/reactive-dict"; import { Reaction } from "/client/api"; import Logger from "/client/modules/logger"; diff --git a/imports/plugins/included/product-variant/client/templates/products/products.html b/imports/plugins/included/product-variant/client/templates/products/products.html index 4629eb51979..eb01b4d1d18 100644 --- a/imports/plugins/included/product-variant/client/templates/products/products.html +++ b/imports/plugins/included/product-variant/client/templates/products/products.html @@ -1,34 +1,14 @@