Skip to content

Commit

Permalink
Merge pull request #3049 from reactioncommerce/mm-shop-manager-2864
Browse files Browse the repository at this point in the history
Adds the ability to set shops to active / disabled
  • Loading branch information
spencern authored Oct 6, 2017
2 parents 045b060 + a6a291d commit 2d0f779
Show file tree
Hide file tree
Showing 17 changed files with 339 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
.rui.sortable-table-container {
position: relative;
padding: 20px;
}

.sortable-table .title {
text-transform: capitalize;
}

.sortable-table .col-dropdown,
.sortable-table .col-button {
width: 100%;
font-weight: @badge-font-weight;
display: inherit;
text-align: center;
}

.sortable-table .rt-td span {
line-height: 2;
}

.sortable-table .-odd {
background: transparent;
}

.sortable-table .rt-td .btn {
padding: 0 5%;
width: 80%;
}

.sortable-table .rt-thead.-header .rt-th {
text-align: left;
margin-left: 20px;
line-height: 2;
}

.sortable-table .rt-tr-group:last-child {
border-bottom: 1px solid @rui-default-disabled;
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
@import "dashboard/package.less";
@import "dashboard/accounts.less";
@import "dashboard/settings.less";
@import "dashboard/tables.less";
@import "dashboard/widget.less";

// Layout
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as MarketplaceShops } from "./marketplaceShops";
export { default as MarketplaceShopTableCell } from "./marketplaceShopTableCell";
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import _ from "lodash";
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Components, registerComponent } from "@reactioncommerce/reaction-components";
import { SHOP_WORKFLOW_STATUS_ACTIVE, SHOP_WORKFLOW_STATUS_DISABLED } from "../../lib/constants";

class MarketplaceShopTableCell extends Component {
static propTypes = {
data: PropTypes.object,
field: PropTypes.string,
onWorkflowChange: PropTypes.func
}

get shop() {
return this.props.data.original;
}

get status() {
if (this.shop.workflow) {
return this.shop.workflow.status;
}

return SHOP_WORKFLOW_STATUS_ACTIVE;
}

handleWorkflowChange = (event, value) => {
if (this.props.onWorkflowChange) {
// Get the shop id from the original document
const { _id } = this.shop;

this.props.onWorkflowChange(_id, value);
}
}

render() {
const { field, data } = this.props;

if (field === "emails" && Array.isArray(data.value) && data.value.length) {
return (
<div className="table-cell body">
<span>{data.value[0].address}</span>
</div>
);
}

if (field === "workflow") {
return (
<Components.DropDownMenu
buttonElement={
<div className="col-dropdown">
<Components.Button bezelStyle="solid" label={_.startCase(this.status)}>
&nbsp;
<i className="fa fa-chevron-down" />
</Components.Button>
</div>
}
onChange={this.handleWorkflowChange}
value={this.status}
>
<Components.MenuItem
label="Active"
value={SHOP_WORKFLOW_STATUS_ACTIVE}
/>
<Components.MenuItem
label="Disabled"
value={SHOP_WORKFLOW_STATUS_DISABLED}
/>
</Components.DropDownMenu>
);
}


return (
<div className="table-cell body">
<span>{data.value}</span>
</div>
);
}
}

registerComponent("MarketplaceShopTableCell", MarketplaceShopTableCell);

export default MarketplaceShopTableCell;
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Components } from "@reactioncommerce/reaction-components";

class MarketplaceShops extends Component {
static propTypes = {
onWorkflowChange: PropTypes.func,
shops: PropTypes.arrayOf(PropTypes.object)
}

renderShopsTable() {
const fields = ["name", "emails", "workflow"];

const columnMetadata = fields.map((field) => {
return {
Header: <Components.Translation i18nKey={`marketplaceShops.headers.${field}`} defaultValue={field} />,
accessor: field,
Cell: (data) => (
<Components.MarketplaceShopTableCell
data={data}
field={field}
onWorkflowChange={this.props.onWorkflowChange}
/>
)
};
});

return (
<Components.SortableTable
data={this.props.shops}
columnMetadata={columnMetadata}
filteredFields={fields}
filterType="none"
showFilter={true}
isSortable={false}
/>
);
}

render() {
return (
<div className="rui sortable-table-container">
<div className="rui sortable-table">
{this.renderShopsTable()}
</div>
</div>
);
}
}

export default MarketplaceShops;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as MarketplaceShopsContainer } from "./marketplaceShops";
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { composeWithTracker, registerComponent } from "@reactioncommerce/reaction-components";
import { Meteor } from "meteor/meteor";
import { Shops } from "/lib/collections";
import { Reaction } from "/client/api";
import MarketplaceShops from "../components/marketplaceShops";

const onWorkflowChange = (shopId, value) => {
Meteor.call("marketplace/updateShopWorkflow", shopId, value);
};

const composer = (props, onData) => {
// Get all shops, excluding the primary shop
const shops = Shops.find({
_id: {
$nin: [Reaction.getPrimaryShopId()]
}
}).fetch();

onData(null, {
shops,
onWorkflowChange
});
};

registerComponent("MarketplaceShops", MarketplaceShops, composeWithTracker(composer));

export default composeWithTracker(composer)(MarketplaceShops);
3 changes: 3 additions & 0 deletions imports/plugins/included/marketplace/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,6 @@ import "./templates/stripeConnectSignupButton/stripeConnectSignupButton.html";
import "./templates/stripeConnectSignupButton/stripeConnectSignupButton.js";

export { default as InviteOwner } from "./components/inviteOwner";

export * from "./components";
export * from "./containers";
4 changes: 4 additions & 0 deletions imports/plugins/included/marketplace/lib/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

export const SHOP_WORKFLOW_STATUS_ACTIVE = "active";
export const SHOP_WORKFLOW_STATUS_DISABLED = "disabled";
export const SHOP_WORKFLOW_STATUS_ARCHIVED = "archived";
17 changes: 17 additions & 0 deletions imports/plugins/included/marketplace/register.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,23 @@ Reaction.registerPackage({
container: "dashboard",
template: "marketplaceShopSettings",
showForShopTypes: ["primary"]
}, {
route: "shop/settings/shops",
template: "MarketplaceShops",
name: "marketplaceShops",
label: "Marketplace Shops",
icon: "fa fa-globe",
provides: ["settings"],
container: "dashboard",
meta: {
actionView: {
dashboardSize: "lg"
}
},
permissions: [{
label: "Marketplace Shops",
permission: "marketplaceShops"
}]
}, {
// does this work?
// override default shop settings
Expand Down
7 changes: 7 additions & 0 deletions imports/plugins/included/marketplace/server/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@
"errorCannotCreateShop": "Could not create shop for current user {{user}}",
"yourShopIsReady": "Your shop is now ready!"
},
"marketplaceShops": {
"headers": {
"name": "Shop name",
"emails": "Contact email",
"workflow": "Status"
}
},
"app": {
"shops": "Shops",
"myShop": "My Shop"
Expand Down
25 changes: 24 additions & 1 deletion imports/plugins/included/marketplace/server/i18n/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import { loadTranslations } from "/server/startup/i18n";

import ar from "./ar.json";
import bg from "./bg.json";
import cs from "./cs.json";
import de from "./de.json";
import el from "./el.json";
import en from "./en.json";
import es from "./es.json";
import fr from "./fr.json";
import he from "./he.json";
import hr from "./hr.json";
import hu from "./hu.json";
import it from "./it.json";
import my from "./my.json";
import nb from "./nb.json";
import nl from "./nl.json";
import pl from "./pl.json";
import pt from "./pt.json";
import ro from "./ro.json";
import ru from "./ru.json";
import sl from "./sl.json";
import sv from "./sv.json";
import tr from "./tr.json";
import vi from "./vi.json";
import zh from "./zh.json";

//
// we want all the files in individual
// imports for easier handling by
// automated translation software
//
loadTranslations([en]);
loadTranslations([ar, bg, cs, de, el, en, es, fr, he, hr, hu, it, my, nb, nl, pl, pt, ro, ru, sl, sv, tr, vi, zh]);
1 change: 1 addition & 0 deletions imports/plugins/included/marketplace/server/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import "./methods.js";
import "./i18n";
import "./publications.js";
66 changes: 43 additions & 23 deletions imports/plugins/included/marketplace/server/methods.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
// import { Meteor } from "meteor/meteor";
// // import { check } from "meteor/check";
// // import { Reaction } from "/lib/api";
// // import { Shops } from "/lib/collections";
//
//
// Meteor.methods({
// // "marketplace/updateShopDetails": function (doc, _id) {
// // check(_id, String);
// // check(doc, Object);
// //
// // if (!Reaction.hasPermission("admin", this.userId, Reaction.getSellerShopId(this.userId))) {
// // return;
// // }
// //
// // Shops.update(_id, doc, function (error) {
// // if (error) {
// // throw new Meteor.Error(500, error.message);
// // }
// // });
// // }
// //
// });
import { Meteor } from "meteor/meteor";
import { check } from "meteor/check";
import { Reaction } from "/lib/api";
import { Shops } from "/lib/collections";
import { SHOP_WORKFLOW_STATUS_ACTIVE, SHOP_WORKFLOW_STATUS_DISABLED } from "../lib/constants";

const status = [
SHOP_WORKFLOW_STATUS_ACTIVE,
SHOP_WORKFLOW_STATUS_DISABLED
];

export function marketplaceUpdateShopWorkflow(shopId, workflowStatus) {
check(shopId, String);
check(workflowStatus, String);

if (shopId === Reaction.getPrimaryShopId()) {
throw new Meteor.Error("access-denied", "Cannot change shop status");
}

if (!Reaction.hasPermission("admin", this.userId, Reaction.getPrimaryShopId())) {
throw new Meteor.Error("access-denied", "Cannot change shop status");
}

if (status.includes(workflowStatus)) {
return Shops.update({
_id: shopId
}, {
$set: {
"workflow.status": workflowStatus
}
}, function (error) {
if (error) {
throw new Meteor.Error("server-error", error.message);
}
});
}

throw new Meteor.Error("server-error", "Workflow status could not be updated, should be 'active' or 'disabled'");
}

Meteor.methods({
"marketplace/updateShopWorkflow": marketplaceUpdateShopWorkflow
});
5 changes: 5 additions & 0 deletions lib/collections/schemas/shops.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Email } from "./accounts";
import { Address } from "./address";
import { Layout } from "./layouts";
import { Metafield } from "./metafield";
import { Workflow } from "./workflow";

/**
* CustomEmailSettings Schema
Expand Down Expand Up @@ -357,5 +358,9 @@ export const Shop = new SimpleSchema({
type: [Object],
blackbox: true,
defaultValue: []
},
"workflow": {
type: Workflow,
optional: true
}
});
Loading

0 comments on commit 2d0f779

Please sign in to comment.