diff --git a/client/templates/layout.html b/client/templates/layout.html deleted file mode 100644 index 6de1a5cc271..00000000000 --- a/client/templates/layout.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/client/templates/layout.js b/client/templates/layout.js deleted file mode 100644 index 1a3e2e07609..00000000000 --- a/client/templates/layout.js +++ /dev/null @@ -1,11 +0,0 @@ -/* - * This is an example of a customized template. - * This layout replaces the "coreLayout" template defined in the reactioncommerce:core package. - * https://github.com/reactioncommerce/reaction-core/blob/master/client/templates/layout/layout.html - * To use custom template in layout.html uncomment - * - * Template.layout.replaces "coreLayout" - */ - - -// Template.layout.replaces("coreLayout"); diff --git a/imports/plugins/core/accounts/register.js b/imports/plugins/core/accounts/register.js index 4a0334c9d7f..b23547e701b 100644 --- a/imports/plugins/core/accounts/register.js +++ b/imports/plugins/core/accounts/register.js @@ -57,7 +57,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "accountsDashboard", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "notFound", dashboardHeader: "dashboardHeader", diff --git a/imports/plugins/core/checkout/client/index.js b/imports/plugins/core/checkout/client/index.js index d851c168016..967e3d8c955 100644 --- a/imports/plugins/core/checkout/client/index.js +++ b/imports/plugins/core/checkout/client/index.js @@ -10,7 +10,6 @@ import "./templates/cartIcon/cartIcon.js"; import "./templates/checkout/addressBook/addressBook.html"; import "./templates/checkout/completed/completed.html"; import "./templates/checkout/completed/completed.js"; -import "./templates/checkout/header/header.html"; import "./templates/checkout/login/login.html"; import "./templates/checkout/login/login.js"; import "./templates/checkout/progressBar/progressBar.html"; diff --git a/imports/plugins/core/checkout/client/templates/checkout/header/header.html b/imports/plugins/core/checkout/client/templates/checkout/header/header.html deleted file mode 100644 index 92cadc5a346..00000000000 --- a/imports/plugins/core/checkout/client/templates/checkout/header/header.html +++ /dev/null @@ -1,15 +0,0 @@ - diff --git a/imports/plugins/core/checkout/register.js b/imports/plugins/core/checkout/register.js index e3e6028ac43..768d13d407c 100644 --- a/imports/plugins/core/checkout/register.js +++ b/imports/plugins/core/checkout/register.js @@ -28,7 +28,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "cartCheckout", - layoutHeader: "checkoutHeader", + layoutHeader: "NavBarCheckout", layoutFooter: "", notFound: "notFound", dashboardHeader: "", diff --git a/imports/plugins/core/dashboard/register.js b/imports/plugins/core/dashboard/register.js index f98027c1557..b108f1ffb8a 100644 --- a/imports/plugins/core/dashboard/register.js +++ b/imports/plugins/core/dashboard/register.js @@ -50,7 +50,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "dashboardPackages", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "notFound", dashboardHeader: "dashboardHeader", diff --git a/imports/plugins/core/email/register.js b/imports/plugins/core/email/register.js index efbfb36c0b1..da80ae404a3 100644 --- a/imports/plugins/core/email/register.js +++ b/imports/plugins/core/email/register.js @@ -29,7 +29,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "email", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "notFound", dashboardHeader: "dashboardHeader", diff --git a/imports/plugins/core/layout/client/components/coreLayout.js b/imports/plugins/core/layout/client/components/coreLayout.js index 39fc003bd3c..6c46cf2ef84 100644 --- a/imports/plugins/core/layout/client/components/coreLayout.js +++ b/imports/plugins/core/layout/client/components/coreLayout.js @@ -1,33 +1,34 @@ import React from "react"; import PropTypes from "prop-types"; import classnames from "classnames"; -import { Components, registerComponent } from "@reactioncommerce/reaction-components"; +import { getComponent, registerComponent } from "@reactioncommerce/reaction-components"; import Blaze from "meteor/gadicc:blaze-react-component"; import { Template } from "meteor/templating"; const CoreLayout = ({ actionViewIsOpen, structure }) => { - const { layoutFooter, template } = structure || {}; + const { layoutHeader, layoutFooter, template } = structure || {}; const pageClassName = classnames({ "page": true, "show-settings": actionViewIsOpen }); + const headerComponent = layoutHeader && getComponent(layoutHeader); + const footerComponent = layoutFooter && getComponent(layoutFooter); + return (
- + + {headerComponent && React.createElement(headerComponent, {})} - { Template[template] && + {Template[template] &&
-
- } + } - { Template[layoutFooter] && - - } + {footerComponent && React.createElement(footerComponent, {})}
); }; diff --git a/imports/plugins/core/layout/client/components/footer.js b/imports/plugins/core/layout/client/components/footer.js new file mode 100644 index 00000000000..8e7bc511a78 --- /dev/null +++ b/imports/plugins/core/layout/client/components/footer.js @@ -0,0 +1,17 @@ +import React from "react"; +import { registerComponent } from "/imports/plugins/core/components/lib"; + +const Footer = () => ( +
+ +
+); + + +registerComponent("Footer", Footer); + +export default Footer; diff --git a/imports/plugins/core/layout/client/index.js b/imports/plugins/core/layout/client/index.js index 34f0dcdfe39..04cf45f5af5 100644 --- a/imports/plugins/core/layout/client/index.js +++ b/imports/plugins/core/layout/client/index.js @@ -1,16 +1,11 @@ -import "./templates/layout/admin/admin.html"; -import "./templates/layout/admin/admin.js"; import "./templates/layout/alerts/alerts.html"; import "./templates/layout/alerts/alerts.js"; import "./templates/layout/alerts/inlineAlerts.js"; import "./templates/layout/alerts/reactionAlerts.js"; import "./templates/layout/createContentMenu/createContentMenu.html"; import "./templates/layout/createContentMenu/createContentMenu.js"; -import "./templates/layout/footer/footer.html"; import "./templates/layout/header/brand.html"; import "./templates/layout/header/button.html"; -import "./templates/layout/header/header.html"; -import "./templates/layout/header/header.js"; import "./templates/layout/header/tags.html"; import "./templates/layout/notFound/notFound.html"; import "./templates/layout/notFound/notFound.js"; @@ -20,5 +15,7 @@ import "./templates/layout/notice/unauthorized.js"; import "./templates/theme/theme.html"; import "./templates/theme/theme.js"; +import "./components/footer"; + export CoreLayout from "./components/coreLayout"; export PrintLayout from "./components/printLayout"; diff --git a/imports/plugins/core/layout/client/templates/layout/admin/admin.html b/imports/plugins/core/layout/client/templates/layout/admin/admin.html deleted file mode 100644 index a7dfed557ec..00000000000 --- a/imports/plugins/core/layout/client/templates/layout/admin/admin.html +++ /dev/null @@ -1,35 +0,0 @@ - diff --git a/imports/plugins/core/layout/client/templates/layout/admin/admin.js b/imports/plugins/core/layout/client/templates/layout/admin/admin.js deleted file mode 100644 index 808a50fa050..00000000000 --- a/imports/plugins/core/layout/client/templates/layout/admin/admin.js +++ /dev/null @@ -1,157 +0,0 @@ -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"; -import ToolbarContainer from "/imports/plugins/core/dashboard/client/containers/toolbarContainer"; -import Toolbar from "/imports/plugins/core/dashboard/client/components/toolbar"; -import { ActionViewContainer } from "/imports/plugins/core/dashboard/client/containers"; -import { ActionView } from "/imports/plugins/core/dashboard/client/components"; - -Template.coreAdminLayout.onRendered(function () { - $("body").addClass("admin"); -}); - -Template.coreAdminLayout.onDestroyed(() => { - $("body").removeClass("admin"); -}); - -Template.coreAdminLayout.helpers({ - PublishContainerComponent() { - return { - component: ToolbarContainer(Toolbar), - data: Template.currentData() - }; - }, - ActionViewComponent() { - return { - component: ActionViewContainer(ActionView), - data: Template.currentData() - }; - }, - shortcutButtons() { - const instance = Template.instance(); - const shortcuts = Reaction.Apps({ provides: "shortcut", enabled: true }); - const items = []; - - if (_.isArray(shortcuts)) { - for (const shortcut of shortcuts) { - if (!shortcut.container) { - items.push({ - type: "link", - href: Reaction.Router.pathFor(shortcut.name), - className: Reaction.Router.isActiveClassName(shortcut.name), - icon: shortcut.icon, - tooltip: shortcut.label || "", - i18nKeyTooltip: shortcut.i18nKeyLabel, - tooltipPosition: "left middle" - }); - } - } - } - - items.push({ type: "seperator" }); - - items.push({ - icon: "plus", - tooltip: "Create Content", - i18nKeyTooltip: "app.createContent", - tooltipPosition: "left middle", - onClick(event) { - if (!instance.dropInstance) { - instance.dropInstance = new Drop({ - target: event.currentTarget, - content: "", - constrainToWindow: true, - classes: "drop-theme-arrows", - position: "right center" - }); - - Blaze.renderWithData(Template.createContentMenu, {}, instance.dropInstance.content); - } - - instance.dropInstance.open(); - } - }); - - return items; - }, - - isSeperator(props) { - if (props.type === "seperator") { - return true; - } - return false; - }, - - packageButtons() { - const routeName = Reaction.Router.getRouteName(); - - if (routeName !== "dashboard") { - const registryItems = Reaction.Apps({ provides: "settings", container: routeName }); - const buttons = []; - - for (const item of registryItems) { - if (Reaction.hasPermission(item.route, Meteor.userId())) { - let icon = item.icon; - - if (!item.icon && item.provides && item.provides.includes("settings")) { - icon = "gear"; - } - - buttons.push({ - href: item.route, - icon: icon, - tooltip: i18next.t(item.i18nKeyLabel, item.i18n), - tooltipPosition: "left middle", - onClick() { - Reaction.showActionView(item); - } - }); - } - } - - return buttons; - } - return []; - }, - - control: function () { - return Reaction.getActionView(); - }, - - adminControlsClassname: function () { - if (Reaction.isActionViewOpen()) { - return "show-settings"; - } - return ""; - }, - - /** - * thisApp - * @return {Object} Registry entry for item - */ - thisApp() { - const reactionApp = Packages.findOne({ - "registry.provides": "settings", - "registry.route": Reaction.Router.getRouteName() - }, { - enabled: 1, - registry: 1, - name: 1, - route: 1 - }); - - if (reactionApp) { - const settingsData = _.find(reactionApp.registry, function (item) { - return item.route === Reaction.Router.getRouteName() && item.provides && item.provides.includes("settings"); - }); - - return settingsData; - } - return reactionApp; - } -}); diff --git a/imports/plugins/core/layout/client/templates/layout/footer/footer.html b/imports/plugins/core/layout/client/templates/layout/footer/footer.html deleted file mode 100644 index e3e546d90b8..00000000000 --- a/imports/plugins/core/layout/client/templates/layout/footer/footer.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/imports/plugins/core/layout/client/templates/layout/header/header.html b/imports/plugins/core/layout/client/templates/layout/header/header.html deleted file mode 100644 index 3a183d998eb..00000000000 --- a/imports/plugins/core/layout/client/templates/layout/header/header.html +++ /dev/null @@ -1,14 +0,0 @@ - diff --git a/imports/plugins/core/layout/client/templates/layout/header/header.js b/imports/plugins/core/layout/client/templates/layout/header/header.js deleted file mode 100644 index 25c14747219..00000000000 --- a/imports/plugins/core/layout/client/templates/layout/header/header.js +++ /dev/null @@ -1,27 +0,0 @@ -import { Template } from "meteor/templating"; -import { $ } from "meteor/jquery"; - -/** - * layoutHeader events - */ -Template.layoutHeader.events({ - "click .navbar-accounts .dropdown-toggle": function () { - return setTimeout(function () { - return $("#login-email").focus(); - }, 100); - }, - "click .header-tag, click .navbar-brand": function () { - return $(".dashboard-navbar-packages ul li").removeClass("active"); - } -}); - -Template.layoutHeader.helpers({ - coreNavProps() { - const instance = Template.instance(); - return { - onMenuButtonClick() { - instance.toggleMenuCallback(); - } - }; - } -}); diff --git a/imports/plugins/core/orders/register.js b/imports/plugins/core/orders/register.js index 5017d0ffb9a..51c10ef7bb9 100644 --- a/imports/plugins/core/orders/register.js +++ b/imports/plugins/core/orders/register.js @@ -45,8 +45,8 @@ Reaction.registerPackage({ enabled: true, structure: { template: "orders", - layoutHeader: "layoutHeader", - layoutFooter: "layoutFooter", + layoutHeader: "NavBar", + layoutFooter: "Footer", notFound: "notFound", dashboardHeader: "dashboardHeader", dashboardHeaderControls: "orderListFilters", @@ -60,8 +60,8 @@ Reaction.registerPackage({ enabled: true, structure: { template: "completedPDFLayout", - layoutHeader: "layoutHeader", - layoutFooter: "layoutFooter" + layoutHeader: "NavBar", + layoutFooter: "Footer" } }, { layout: "coreLayout", diff --git a/imports/plugins/core/ui-navbar/client/components/navbar.js b/imports/plugins/core/ui-navbar/client/components/navbar.js index d14dc07ea71..f841c7abfb1 100644 --- a/imports/plugins/core/ui-navbar/client/components/navbar.js +++ b/imports/plugins/core/ui-navbar/client/components/navbar.js @@ -24,8 +24,23 @@ class NavBar extends Component { brandMedia: PropTypes.object, hasProperPermission: PropTypes.bool, searchEnabled: PropTypes.bool, - shop: PropTypes.object - } + shop: PropTypes.object, + visibility: PropTypes.object.isRequired + }; + + static defaultProps = { + visibility: { + hamburger: true, + brand: true, + tags: true, + search: true, + notifications: true, + languages: true, + currency: true, + mainDropdown: true, + cartContainer: true + } + }; state = { navBarVisible: false @@ -135,15 +150,15 @@ class NavBar extends Component { render() { return (
- {this.renderHamburgerButton()} - {this.renderBrand()} - {this.renderTagNav()} - {this.renderSearchButton()} - {this.renderNotificationIcon()} - {this.renderLanguage()} - {this.renderCurrency()} - {this.renderMainDropdown()} - {this.renderCartContainerAndPanel()} + {this.props.visibility.hamburger && this.renderHamburgerButton()} + {this.props.visibility.brand && this.renderBrand()} + {this.props.visibility.tags && this.renderTagNav()} + {this.props.visibility.search && this.renderSearchButton()} + {this.props.visibility.notifications && this.renderNotificationIcon()} + {this.props.visibility.languages && this.renderLanguage()} + {this.props.visibility.currency && this.renderCurrency()} + {this.props.visibility.mainDropdown && this.renderMainDropdown()} + {this.props.visibility.cartContainer && this.renderCartContainerAndPanel()}
); } diff --git a/imports/plugins/core/ui-navbar/client/components/navbarCheckout.js b/imports/plugins/core/ui-navbar/client/components/navbarCheckout.js new file mode 100644 index 00000000000..7e1c5f3af23 --- /dev/null +++ b/imports/plugins/core/ui-navbar/client/components/navbarCheckout.js @@ -0,0 +1,23 @@ +import React from "react"; +import NavBar from "../components/navbar"; + +const NavBarCheckout = (props, context) => { + const visibility = { + hamburger: false, + brand: true, + tags: false, + search: false, + notifications: false, + languages: false, + currency: false, + mainDropdown: false, + cartContainer: false + }; + const newProps = { + ...props, + visibility + }; + return React.createElement(NavBar, newProps, context); +}; + +export default NavBarCheckout; diff --git a/imports/plugins/core/ui-navbar/client/containers/navbar.js b/imports/plugins/core/ui-navbar/client/containers/navbar.js index b46ba3429e5..31dcd53a6c8 100644 --- a/imports/plugins/core/ui-navbar/client/containers/navbar.js +++ b/imports/plugins/core/ui-navbar/client/containers/navbar.js @@ -4,7 +4,7 @@ import { Reaction } from "/client/api"; import NavBar from "../components/navbar"; import { Media, Shops } from "/lib/collections"; -function composer(props, onData) { +export function composer(props, onData) { const shop = Shops.findOne(Reaction.getShopId()); const searchPackage = Reaction.Apps({ provides: "ui-search" }); let searchEnabled; diff --git a/imports/plugins/core/ui-navbar/client/containers/navbarCheckout.js b/imports/plugins/core/ui-navbar/client/containers/navbarCheckout.js new file mode 100644 index 00000000000..7a59f0475d4 --- /dev/null +++ b/imports/plugins/core/ui-navbar/client/containers/navbarCheckout.js @@ -0,0 +1,7 @@ +import { registerComponent, composeWithTracker } from "@reactioncommerce/reaction-components"; +import NavBarCheckout from "../components/navbarCheckout"; +import { composer } from "./navbar"; + +registerComponent("NavBarCheckout", NavBarCheckout, composeWithTracker(composer)); + +export default composeWithTracker(composer)(NavBarCheckout); diff --git a/imports/plugins/core/ui-navbar/client/index.js b/imports/plugins/core/ui-navbar/client/index.js index 54221bda4b4..639529c622a 100644 --- a/imports/plugins/core/ui-navbar/client/index.js +++ b/imports/plugins/core/ui-navbar/client/index.js @@ -1,2 +1,3 @@ export { default as Brand } from "./components/brand"; export { default as Navbar } from "./containers/navbar"; +export { default as NavBarCheckout } from "./containers/navbarCheckout"; diff --git a/imports/plugins/core/ui/register.js b/imports/plugins/core/ui/register.js index a9894763690..671f87de283 100644 --- a/imports/plugins/core/ui/register.js +++ b/imports/plugins/core/ui/register.js @@ -30,7 +30,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "uiDashboard", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "notFound", dashboardHeader: "dashboardHeader", diff --git a/imports/plugins/core/versions/server/migrations/18_use_react_for_header_and_footer_layout.js b/imports/plugins/core/versions/server/migrations/18_use_react_for_header_and_footer_layout.js new file mode 100644 index 00000000000..d50bc8c31bc --- /dev/null +++ b/imports/plugins/core/versions/server/migrations/18_use_react_for_header_and_footer_layout.js @@ -0,0 +1,94 @@ +import { Migrations } from "meteor/percolate:migrations"; +import { Shops, Packages } from "/lib/collections"; + +const pkgs = [ + "reaction-accounts", + "reaction-checkout", + "reaction-dashboard", + "reaction-email", + "reaction-orders", + "reaction-ui", + "reaction-product-variant", + "product-detail-simple", + "core" +]; + +const query = { + name: { $in: pkgs }, + layout: { $type: 3 } // docs with layouts set +}; + +Migrations.add({ + version: 18, + up() { + const packages = Packages.find(query).fetch(); + packages.forEach(updateHandler( + Packages + )); + + const shops = Shops.find().fetch(); + shops.forEach(updateHandler( + Shops + )); + }, + down() { + const packages = Packages.find(query).fetch(); + packages.forEach(downgradeHandler( + Packages + )); + + const shops = Shops.find().fetch(); + shops.forEach(downgradeHandler( + Shops + )); + } +}); + +function updateHandler(collection) { + return function (doc) { + let changed = false; + for (const layout of doc.layout) { + if (layout.structure && layout.structure.template === "cartCheckout") { + layout.structure.layoutHeader = "NavBarCheckout"; + changed = true; + } else if (layout.structure && layout.structure.layoutHeader === "layoutHeader") { + layout.structure.layoutHeader = "NavBar"; + changed = true; + } + if (layout.structure && layout.structure.layoutFooter === "layoutFooter") { + layout.structure.layoutFooter = "Footer"; + changed = true; + } + } + + if (changed) { + collection.update( + { _id: doc._id }, { + $set: { layout: doc.layout } + }); + } + }; +} + +function downgradeHandler(collection) { + return function (doc) { + let changed = false; + for (const layout of doc.layout) { + if (layout.structure && layout.structure.layoutHeader === "NavBar") { + layout.structure.layoutHeader = "layoutHeader"; + changed = true; + } + if (layout.structure && layout.structure.layoutFooter === "Footer") { + layout.structure.layoutFooter = "layoutFooter"; + changed = true; + } + } + + if (changed) { + collection.update( + { _id: doc._id }, { + $set: { layout: doc.layout } + }); + } + }; +} diff --git a/imports/plugins/core/versions/server/migrations/index.js b/imports/plugins/core/versions/server/migrations/index.js index 5298528e16a..de38509089a 100644 --- a/imports/plugins/core/versions/server/migrations/index.js +++ b/imports/plugins/core/versions/server/migrations/index.js @@ -15,3 +15,4 @@ import "./14_rebuild_order_search_collection"; import "./15_update_shipping_status_to_workflow"; import "./16_update_billing_paymentMethod"; import "./17_set_shop_uols"; +import "./18_use_react_for_header_and_footer_layout"; diff --git a/imports/plugins/included/product-detail-simple/register.js b/imports/plugins/included/product-detail-simple/register.js index 9c2dcb3cbb5..e9d49ae27b4 100644 --- a/imports/plugins/included/product-detail-simple/register.js +++ b/imports/plugins/included/product-detail-simple/register.js @@ -19,7 +19,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "productDetailSimple", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "productNotFound", dashboardHeader: "productDetailSimpleToolbar", diff --git a/imports/plugins/included/product-variant/register.js b/imports/plugins/included/product-variant/register.js index 243adb9f46b..6bd45c0aa5d 100644 --- a/imports/plugins/included/product-variant/register.js +++ b/imports/plugins/included/product-variant/register.js @@ -32,7 +32,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "productDetail", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "productNotFound", dashboardHeader: "productDetailSimpleToolbar", @@ -48,7 +48,7 @@ Reaction.registerPackage({ enabled: true, structure: { template: "products", - layoutHeader: "layoutHeader", + layoutHeader: "NavBar", layoutFooter: "", notFound: "productNotFound", dashboardHeader: "gridPublishControls", diff --git a/server/startup/registry/core.js b/server/startup/registry/core.js index 03d087cd2b6..0f7e59497da 100644 --- a/server/startup/registry/core.js +++ b/server/startup/registry/core.js @@ -34,8 +34,8 @@ export default function () { enabled: true, structure: { template: "products", - layoutHeader: "layoutHeader", - layoutFooter: "layoutFooter", + layoutHeader: "NavBar", + layoutFooter: "Footer", notFound: "productNotFound", dashboardControls: "dashboardControls", adminControlsFooter: "adminControlsFooter" @@ -47,8 +47,8 @@ export default function () { enabled: true, structure: { template: "unauthorized", - layoutHeader: "layoutHeader", - layoutFooter: "layoutFooter" + layoutHeader: "NavBar", + layoutFooter: "Footer" } }] });