From 910d37e327f19d26f8a45c9419ffa55e3c27a292 Mon Sep 17 00:00:00 2001 From: Eric Dobbertin Date: Thu, 17 Oct 2019 04:58:21 -0500 Subject: [PATCH 01/16] feat: remove /operator prefix from all routes Signed-off-by: Eric Dobbertin --- .../ProfileImageWithData.js | 2 +- .../ShopLogoWithData/ShopLogoWithData.js | 2 +- .../client/ui/components/Sidebar/Sidebar.js | 6 +++--- imports/client/ui/layouts/App.js | 21 +++++-------------- imports/client/ui/layouts/Dashboard.js | 2 +- .../client/containers/updatePassword.js | 2 +- .../client/components/OperatorLanding.js | 2 +- .../layout/client/components/coreLayout.js | 6 ------ .../orders/client/components/OrderHeader.js | 2 +- .../orders/client/components/OrderIdCell.js | 2 +- .../orders/client/components/OrderPrint.js | 2 +- .../orders/client/components/OrdersTable.js | 2 +- .../tags/client/components/TagProductTable.js | 2 +- .../tags/client/pages/TagFormPageWithData.js | 4 ++-- .../client/pages/TagSettingsPageWithData.js | 4 ++-- .../core/ui/client/components/app/app.js | 9 +------- .../core/ui/client/components/tags/tagItem.js | 2 +- .../client/components/ProductHeader.js | 16 +++++++------- .../client/components/ProductList.js | 6 +++--- .../client/components/ProductTable.js | 2 +- .../client/components/VariantTable.js | 6 +++--- .../components/productGridItems.js | 2 +- .../containers/productGridItemsContainer.js | 6 +++--- 23 files changed, 43 insertions(+), 67 deletions(-) diff --git a/imports/client/ui/components/ProfileImageWithData/ProfileImageWithData.js b/imports/client/ui/components/ProfileImageWithData/ProfileImageWithData.js index 9d4a547c40..f7caf67afa 100644 --- a/imports/client/ui/components/ProfileImageWithData/ProfileImageWithData.js +++ b/imports/client/ui/components/ProfileImageWithData/ProfileImageWithData.js @@ -73,7 +73,7 @@ class ProfileImageWithData extends Component { open={Boolean(menuAnchorEl)} onClose={() => setMenuAnchorEl(null)} > - + {i18next.t("admin.userAccountDropdown.profileLabel")} Meteor.logout()}>{i18next.t("accountsUI.signOut")} diff --git a/imports/client/ui/components/ShopLogoWithData/ShopLogoWithData.js b/imports/client/ui/components/ShopLogoWithData/ShopLogoWithData.js index 7316c320da..9b026b87c3 100644 --- a/imports/client/ui/components/ShopLogoWithData/ShopLogoWithData.js +++ b/imports/client/ui/components/ShopLogoWithData/ShopLogoWithData.js @@ -125,7 +125,7 @@ ShopLogoWithData.propTypes = { }; ShopLogoWithData.defaultProps = { - linkTo: "/operator", + linkTo: "/", shouldShowShopName: false, size: 60 }; diff --git a/imports/client/ui/components/Sidebar/Sidebar.js b/imports/client/ui/components/Sidebar/Sidebar.js index 6eec1c601a..e917e8227a 100644 --- a/imports/client/ui/components/Sidebar/Sidebar.js +++ b/imports/client/ui/components/Sidebar/Sidebar.js @@ -140,7 +140,7 @@ function Sidebar(props) { { setIsSettingsOpen(false); @@ -170,7 +170,7 @@ function Sidebar(props) { const [firstRoute] = settingRoutes; if (firstRoute) { - history.push(`/operator${firstRoute.path}`); + history.push(firstRoute.path); } } setIsSettingsOpen(!isSettingsOpen); @@ -192,7 +192,7 @@ function Sidebar(props) { diff --git a/imports/client/ui/layouts/App.js b/imports/client/ui/layouts/App.js index ec8c11b238..e9ca3a86fc 100644 --- a/imports/client/ui/layouts/App.js +++ b/imports/client/ui/layouts/App.js @@ -3,7 +3,6 @@ import Helmet from "react-helmet"; import { Route, Switch } from "react-router-dom"; import i18next from "i18next"; import useAuth from "../hooks/useAuth"; -import useRouter from "../hooks/useRouter"; import Dashboard from "./Dashboard"; import { routes } from "/imports/client/ui"; import ContentViewFullLayout from "./ContentViewFullLayout"; @@ -16,26 +15,16 @@ import DefaultPage from "./DefaultPage"; */ function App() { const { isAdmin, isLoggedIn, redirectUrl } = useAuth(); - const { location } = useRouter(); - - - if (location.pathname === "/") { - window.location.replace("/operator"); - } - - if (isLoggedIn && !isAdmin) { - return ; - } - - if (isAdmin && location.pathname.startsWith("/operator")) { - return ; - } if (redirectUrl) { window.location.href = redirectUrl; return null; } + if (isLoggedIn) { + return isAdmin ? : ; + } + return ( <> @@ -43,7 +32,7 @@ function App() { routes.map((route, index) => ( { const title = i18next.t(route.sidebarI18nLabel, { defaultValue: "Reaction Admin" }); diff --git a/imports/client/ui/layouts/Dashboard.js b/imports/client/ui/layouts/Dashboard.js index cda2032855..44e994e5ab 100644 --- a/imports/client/ui/layouts/Dashboard.js +++ b/imports/client/ui/layouts/Dashboard.js @@ -131,7 +131,7 @@ class Dashboard extends Component { { const title = i18next.t(route.sidebarI18nLabel, { defaultValue: "Reaction Admin" }); // If the layout component is explicitly null diff --git a/imports/plugins/core/accounts/client/containers/updatePassword.js b/imports/plugins/core/accounts/client/containers/updatePassword.js index 0aac93fea4..d67aff5802 100644 --- a/imports/plugins/core/accounts/client/containers/updatePassword.js +++ b/imports/plugins/core/accounts/client/containers/updatePassword.js @@ -83,7 +83,7 @@ const wrapComponent = (Comp) => ( const { storefrontUrls } = Reaction.getCurrentShop(); if (Reaction.hasDashboardAccessForAnyShop()) { - this.props.history("/operator"); + this.props.history("/"); } else if (!storefrontUrls || !storefrontUrls.storefrontLoginUrl) { throw new ReactionError("error-occurred", "Missing storefront URLs. Please set these properties from the shop settings panel."); } else { diff --git a/imports/plugins/core/dashboard/client/components/OperatorLanding.js b/imports/plugins/core/dashboard/client/components/OperatorLanding.js index 3b81a5977c..4371c2d731 100644 --- a/imports/plugins/core/dashboard/client/components/OperatorLanding.js +++ b/imports/plugins/core/dashboard/client/components/OperatorLanding.js @@ -27,7 +27,7 @@ function OperatorLanding() { {/* eslint-disable-next-line max-len */} - Use Reaction Admin to manage Orders, Products, Tags, Accounts, and Navigation, or change shop settings. + Use Reaction Admin to manage Orders, Products, Tags, Accounts, and Navigation, or change shop settings. diff --git a/imports/plugins/core/layout/client/components/coreLayout.js b/imports/plugins/core/layout/client/components/coreLayout.js index 630eb76d4e..be3a32cef0 100644 --- a/imports/plugins/core/layout/client/components/coreLayout.js +++ b/imports/plugins/core/layout/client/components/coreLayout.js @@ -45,12 +45,6 @@ function CoreLayout({ classes, isAdmin, isLoading, isLoggedIn, location, storefr // If we're not on /account or /account/login for hydra, and the user is signed in, // then we will redirect or show a logout button if (!location.pathname.startsWith("/account") && !location.pathname.startsWith("/reset")) { - // If the current user is an admin then redirect to /operator - if (!location.pathname.startsWith("/operator") && isAdmin) { - window.location.replace("/operator"); - return null; - } - // If the user is logged in, which makes them no longer anonymous // But they aren't an admin, then give them a logout button. if (isLoggedIn && !isAdmin) { diff --git a/imports/plugins/core/orders/client/components/OrderHeader.js b/imports/plugins/core/orders/client/components/OrderHeader.js index 9bd51a9158..946ff28d9b 100644 --- a/imports/plugins/core/orders/client/components/OrderHeader.js +++ b/imports/plugins/core/orders/client/components/OrderHeader.js @@ -66,7 +66,7 @@ function OrderHeader(props) { {paymentStatusChip} + ); } From 249e7e5277c37776b94a8cc7d28483a33922b734 Mon Sep 17 00:00:00 2001 From: Eric Dobbertin Date: Thu, 17 Oct 2019 09:58:52 -0500 Subject: [PATCH 05/16] feat: remove unused Reaction methods Signed-off-by: Eric Dobbertin --- client/modules/core/main.js | 96 ++----------------------------------- 1 file changed, 3 insertions(+), 93 deletions(-) diff --git a/client/modules/core/main.js b/client/modules/core/main.js index 71aabbd58e..e3dc728ca8 100644 --- a/client/modules/core/main.js +++ b/client/modules/core/main.js @@ -349,20 +349,6 @@ export default { return ""; }, - /** - * @name getPrimaryShopSettings - * @method - * @memberof Core/Client - * @returns {Object} shop settings of the primary shop - */ - getPrimaryShopSettings() { - const settings = Packages.findOne({ - name: "core", - shopId: this.getPrimaryShopId() - }) || {}; - return settings.settings || {}; - }, - /** * @name getCurrentShop * @summary Get the proper current shop based on various checks. This mirrors the logic in @@ -461,36 +447,6 @@ export default { return this.getShopId() === this.getPrimaryShopId(); }, - /** - * @name getShopName - * @method - * @memberof Core/Client - * @summary gets name of shop by provided shopId, or current active shop if shopId is not provided - * @param {String} providedShopId - shopId of shop to return name of - * @returns {String} - shop name - */ - getShopName(providedShopId) { - const shopId = providedShopId || this.getShopId(); - const shop = Shops.findOne({ - _id: shopId - }); - return shop && shop.name; - }, - - /** - * @name getShopSettings - * @method - * @memberof Core/Client - * @returns {Object} shop settings - */ - getShopSettings() { - const settings = Packages.findOne({ - name: "core", - shopId: this.shopId - }) || {}; - return settings.settings || {}; - }, - getShopLanguage() { const shopId = this.getShopId(); const shop = Shops.findOne({ _id: shopId }); @@ -529,36 +485,6 @@ export default { return slug; }, - /** - * @name getPackageSettings - * @method - * @memberof Core/Client - * @param {String} name package name - * @returns {Object} package settings - */ - getPackageSettings(name) { - const shopId = this.getShopId(); - const query = { name }; - - if (shopId) { - query.shopId = shopId; - } - - return Packages.findOne(query); - }, - - /** - * @name getPackageSettingsWithOptions - * @method - * @memberof Core/Client - * @param {Object} options options to pass to query - * @returns {Object} package settings with options - */ - getPackageSettingsWithOptions(options) { - const query = options; - return Packages.findOne(query); - }, - /** * @name allowGuestCheckout * @method @@ -566,9 +492,10 @@ export default { * @returns {Boolean} is guest checkout allowed */ allowGuestCheckout() { - const settings = this.getShopSettings(); + const pkg = Packages.findOne({ name: "core", shopId: this.getShopId() }) || {}; + const shopSettings = pkg.settings || {}; // we can disable in admin, let's check. - return !!(settings.public && settings.public.allowGuestCheckout); + return !!(shopSettings.public && shopSettings.public.allowGuestCheckout); }, /** @@ -917,22 +844,5 @@ export default { } Logger.debug("getRegistryForCurrentRoute not found", template, provides); return {}; - }, - - /** - * @name getMarketplaceSettings - * @method - * @memberof Core/Client - * @summary finds the enabled `reaction-marketplace` package for the primary shop and returns the settings - * @returns {Object} The marketplace settings from the primary shop or undefined - */ - getMarketplaceSettings() { - const marketplaceSettings = Packages.findOne({ - name: "reaction-marketplace", - shopId: this.getPrimaryShopId(), // the primary shop always owns the marketplace settings - enabled: true // only use the marketplace settings if marketplace is enabled - }); - - return marketplaceSettings && marketplaceSettings.settings; } }; From 2c29b2c4ec26eaa2b40e031111ecefa47f2a17ae Mon Sep 17 00:00:00 2001 From: Eric Dobbertin Date: Thu, 17 Oct 2019 09:59:35 -0500 Subject: [PATCH 06/16] feat: cleaner subscription pattern Subscribe to Packages only where necessary. We're trying to get rid of it. Signed-off-by: Eric Dobbertin --- client/modules/core/subscriptions.js | 32 ++++------------------------ 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/client/modules/core/subscriptions.js b/client/modules/core/subscriptions.js index 29086491cd..2f4994c894 100644 --- a/client/modules/core/subscriptions.js +++ b/client/modules/core/subscriptions.js @@ -1,8 +1,4 @@ -import { Meteor } from "meteor/meteor"; -import { Tracker } from "meteor/tracker"; import { SubsManager } from "meteor/meteorhacks:subs-manager"; -import Reaction from "./main"; -import { getUserId } from "./helpers/utils"; export const Subscriptions = {}; @@ -14,28 +10,8 @@ Subscriptions.Manager = new SubsManager(); * General Subscriptions */ -Tracker.autorun(() => { - const userId = getUserId(); - Subscriptions.Account = Subscriptions.Manager.subscribe("Accounts"); - Subscriptions.UserProfile = Meteor.subscribe("UserProfile", userId); -}); - -// Primary shop subscription -Subscriptions.PrimaryShop = Subscriptions.Manager.subscribe("PrimaryShop"); - -// This Packages subscription is used for the Active shop's packages -Subscriptions.Packages = Subscriptions.Manager.subscribe("Packages"); - -Subscriptions.Groups = Subscriptions.Manager.subscribe("Groups"); - Subscriptions.BrandAssets = Subscriptions.Manager.subscribe("BrandAssets"); - -Tracker.autorun(() => { - // Reload Packages sub if shopId changes - // We have a persistent subscription to the primary shop's packages, - // so don't refresh sub if we're updating to primaryShopId sub - const shopId = Reaction.getShopId(); - if (shopId && shopId !== Reaction.getPrimaryShopId()) { - Subscriptions.Packages = Subscriptions.Manager.subscribe("Packages", shopId); - } -}); +Subscriptions.Groups = Subscriptions.Manager.subscribe("Groups"); +Subscriptions.MyAccount = Subscriptions.Manager.subscribe("MyAccount"); +Subscriptions.PrimaryShop = Subscriptions.Manager.subscribe("PrimaryShop"); +Subscriptions.UserProfile = Subscriptions.Manager.subscribe("UserProfile"); From 2861983b4f6501add3ccc3a0473efb0cea8c47c0 Mon Sep 17 00:00:00 2001 From: Eric Dobbertin Date: Thu, 17 Oct 2019 10:00:02 -0500 Subject: [PATCH 07/16] chore: remove unused reactionTemplate Blaze helper Signed-off-by: Eric Dobbertin --- client/modules/core/helpers/layout.js | 107 -------------------------- 1 file changed, 107 deletions(-) delete mode 100644 client/modules/core/helpers/layout.js diff --git a/client/modules/core/helpers/layout.js b/client/modules/core/helpers/layout.js deleted file mode 100644 index b6bbd34502..0000000000 --- a/client/modules/core/helpers/layout.js +++ /dev/null @@ -1,107 +0,0 @@ -import _ from "lodash"; -import { Meteor } from "meteor/meteor"; -import { Template } from "meteor/templating"; -import { Reaction } from "/client/api"; -import Logger from "/client/modules/logger"; -import * as Collections from "/lib/collections"; - -/** - * @name reactionTemplate - * @summary use the reactionTemplate helper when you are using templates defined - * as workflow templates in the package registry.Layout - * use "collection" on the layout to indicate a workflow source - * @memberof BlazeTemplateHelpers - * @description reactionTemplate provides templates as defined in ReactionRegistry.Layout - * @param {Object} options - workflow defaults to "coreLayout/coreWorkflow" - * @returns {Array} returns an array with labels, templates that match workflow - */ -Template.registerHelper("reactionTemplate", (options) => { - const shopId = options.hash.shopId || Reaction.getShopId(); - // get shop info, defaults to current - const Shop = Collections.Shops.findOne(shopId); - const groupSub = Meteor.subscribe("Groups", { shopId }); - let defaultRoles; - if (groupSub.ready()) { - const groups = Collections.Groups.findOne({ slug: "customer", shopId }); - defaultRoles = groups.permissions; - } - - const reactionTemplates = []; - // fetch collection from shop.layout configuration - let layout = _.find(Shop.layout, { - workflow: options.hash.workflow || "coreWorkflow" - }); - - let layoutConfigCollection; - let currentId; - - // determine if workflow has a target - // collection defined. This is where we'll - // fetch/save workflow changes. - if (layout) { - layoutConfigCollection = layout.collection || "Cart"; - } else { - Logger.error("Shop Layout Undefined"); - layoutConfigCollection = "Cart"; - } - - // if we've got an id, we'll use it with the layout's collection - // and get the current status of the workflowTargetCollection - if (Template.currentData() && Template.currentData()._id) { - currentId = Template.currentData()._id; - } - - // we'll get current cart status by default, as the most common case - // TODO: expand query options - currentId = options.hash.id || currentId; - - // The currentCollection must have workflow schema attached. - // layoutConfigCollection is the collection defined in Shops.workflow - const workflowTargetCollection = Collections[layoutConfigCollection]; - const currentCollection = workflowTargetCollection.findOne({ _id: currentId }); - if (!currentCollection || !currentCollection.workflow) { - return reactionTemplates; - } - - const currentStatus = currentCollection.workflow.status; - const currentCollectionWorkflow = currentCollection.workflow.workflow; - const packages = Collections.Packages.find({ - layout: { - $elemMatch: options.hash - }, - shopId - }); - - // we can have multiple packages contributing to the layout / workflow - packages.forEach((reactionPackage) => { - const layoutWorkflows = _.filter(reactionPackage.layout, options.hash); - // check the packages for layout workflow templates - for (layout of layoutWorkflows) { - // audience is layout permissions - if (layout.audience === undefined) { - layout.audience = defaultRoles || "owner"; - } - - // check permissions so you don't have to on template. - if (Reaction.hasPermission(layout.audience)) { - // todo: review this hack to remove layout - // from the workflow - if (!layout.layout) { - // default is boolean false status - // true = we've completed this workflow - // false = pending (future) step - //