Skip to content

Commit

Permalink
Merge pull request reactioncommerce#4383 from reactioncommerce/feat-4…
Browse files Browse the repository at this point in the history
…281-kieckhafer-productChangeIndicator

feat: Indicator to notify of pending product changes not yet published to catalog
  • Loading branch information
nnnnat authored Jun 29, 2018
2 parents 5a2ea57 + 5aea5f0 commit 730d12a
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 7 deletions.
91 changes: 85 additions & 6 deletions imports/plugins/core/catalog/client/components/publishControls.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import classnames from "classnames";
import { Meteor } from "meteor/meteor";
import { ReactiveVar } from "meteor/reactive-var";
import { Components } from "@reactioncommerce/reaction-components";
import {
Button,
Expand All @@ -10,7 +13,7 @@ import {
import { Translatable } from "/imports/plugins/core/ui/client/providers";

/** TMP **/
import { Reaction } from "/client/api";
import { i18next, Reaction } from "/client/api";

class PublishControls extends Component {
static propTypes = {
Expand All @@ -37,14 +40,28 @@ class PublishControls extends Component {
constructor(props) {
super(props);

this.state = {
showDiffs: false
};
this.currentProductHash = new ReactiveVar([]);

this.handleToggleShowChanges = this.handleToggleShowChanges.bind(this);
this.handlePublishClick = this.handlePublishClick.bind(this);
}

state = {
isHashUpdating: false,
showDiffs: false
};

componentWillReceiveProps() {
this.setState({
isHashUpdating: false
});
}

componentDidUpdate() {
// Re-calculate hash after publishing
this.renderHashCalculation();
}

handleToggleShowChanges() {
this.setState({
showDiffs: !this.state.showDiffs
Expand All @@ -54,6 +71,10 @@ class PublishControls extends Component {
handlePublishClick() {
if (this.props.onPublishClick) {
this.props.onPublishClick(this.props.revisions);

this.setState({
isHashUpdating: true
});
}
}

Expand Down Expand Up @@ -200,13 +221,13 @@ class PublishControls extends Component {

return (
<div className="hidden-xs">
{this.renderChangesNotification()}
<Button
bezelStyle="outline"
bezelStyle="solid"
disabled={isDisabled}
label="Publish"
onClick={this.handlePublishClick}
status="success"
tooltip={"This product has changes that need to be published before they are visible to your customers."}
i18nKeyLabel="productDetailEdit.publish"
{...buttonProps}
/>
Expand Down Expand Up @@ -304,6 +325,64 @@ class PublishControls extends Component {
);
}

renderHashCalculation = () => {
const productDocument = this.props && this.props.documents && this.props.documents[0];

if (productDocument) {
Meteor.call("products/getpublishedProductHash", productDocument._id, (err, result) => {
if (err) {
Alerts.toast(i18next.t("admin.catalogCalculateHashError", { err: err.reason }), "error");
}
if (result) {
this.currentProductHash.set(result);
}
});
}
return;
}

renderChangesNotification = () => {
const publishedProductHash = (this.props && this.props.documents && this.props.documents[0] && this.props.documents[0].publishedProductHash) || null;
const { isHashUpdating } = this.state;

// Calculate hash to compare
this.renderHashCalculation();
const currentProductHash = this.currentProductHash.get();

const hashIndicator = classnames({
"rui": true,
"hash-icon": true,
"fa-stack": true,
"fa-lg": true,
"hash-icon-visible": publishedProductHash !== currentProductHash,
"hash-icon-hidden": publishedProductHash === currentProductHash
});

const primaryIcon = classnames({
"fa": true,
"fa-stack-2x": true,
"fa-circle": isHashUpdating,
"fa-circle-o": !isHashUpdating
});

const secondaryIcon = classnames({
"fa": true,
"fa-stack-1x": true,
"fa-refresh": isHashUpdating,
"fa-circle": !isHashUpdating,
"fa-spin": isHashUpdating
});

// We don't use the `<Icon>` component here as we do not have layered
// icons built in to the existing component
return (
<span className={hashIndicator} style={{ fontSize: 11, position: "absolute", top: "2px", right: "4px" }}>
<i className={primaryIcon} style={{ color: "#ffffff" }} />
<i className={secondaryIcon} style={{ fontSize: "1.5em", color: "#f4c43c" }} />
</span>
);
}

render() {
return (
<Components.ToolbarGroup lastChild={true}>
Expand Down
1 change: 1 addition & 0 deletions imports/plugins/core/catalog/server/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"reaction-catalog": {
"admin": {
"catalogProductPublishSuccess": "Product published to catalog",
"catalogCalculateHashError": "There was an error trying to calculate this products hash.",
"shortcut": {
"catalogLabel": "Catalog",
"catalogTitle": "Catalog"
Expand Down
19 changes: 19 additions & 0 deletions imports/plugins/core/catalog/server/methods/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Hooks, Logger, Reaction } from "/server/api";
import { MediaRecords, Products, Tags } from "/lib/collections";
import { Media } from "/imports/plugins/core/files/server";
import rawCollections from "/imports/collections/rawCollections";
import { createProductHash } from "../no-meteor/mutations/hashProduct";
import getProductPriceRange from "../no-meteor/utils/getProductPriceRange";
import getVariants from "../no-meteor/utils/getVariants";
import hasChildVariant from "../no-meteor/utils/hasChildVariant";
Expand Down Expand Up @@ -1576,5 +1577,23 @@ Meteor.methods({

// if collection updated we return new `isVisible` state
return res === 1 && !product.isVisible;
},

/**
* @name products/getpublishedProductHash
* @memberof Methods/Products
* @method
* @summary hashes product information for comparison purposes
* @param {String} productId - the product _id of the product to hash
* @return {String} hash of product
*/
"products/getpublishedProductHash"(productId) {
check(productId, String);

const product = Products.findOne({ _id: productId });

const productHash = createProductHash(product, rawCollections);

return productHash;
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import createCatalogProduct from "../utils/createCatalogProduct";
* @param {Object} collections - Raw mongo collections
* @return {String} product hash
*/
async function createProductHash(productToConvert, collections) {
export async function createProductHash(productToConvert, collections) {
const product = await createCatalogProduct(productToConvert, collections);

const hashableFields = {
Expand Down
12 changes: 12 additions & 0 deletions imports/plugins/included/default-theme/client/styles/toolbar.less
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,15 @@ html.rtl .rui.toolbar.toolbar-vertical {
display: flex !important;
}
}

.rui.hash-icon {
transition: opacity 200ms linear;
}

.rui.hash-icon.hash-icon-visible {
opacity: 1.0;
}

.rui.hash-icon.hash-icon-hidden {
opacity: 0.0;
}

0 comments on commit 730d12a

Please sign in to comment.