Skip to content

Commit

Permalink
RS-604 display debugMessages on product details page (#486)
Browse files Browse the repository at this point in the history
* display debugMessages on product details page

* add getErrorMessages function

* Added checking cart.is.not.empty error

* Small fixes in quick order

* displaying multiple messages

* Add the key to map functions
  • Loading branch information
yulia-dnistrian authored and shaunmaharaj committed Nov 15, 2019
1 parent 56b8367 commit 39abd81
Show file tree
Hide file tree
Showing 14 changed files with 168 additions and 125 deletions.
17 changes: 0 additions & 17 deletions app/src/containers/CheckoutPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import {
import { login } from '../utils/AuthService';
import { cortexFetch } from '../utils/Cortex';
import Config from '../ep.config.json';
import { ErrorInlet } from '../utils/MessageContext';

import './CheckoutPage.less';

Expand Down Expand Up @@ -173,22 +172,6 @@ class CheckoutPage extends React.Component<RouteComponentProps, CheckoutPageStat
orderData: res._defaultcart[0],
isLoading: false,
});
const { messages } = res._defaultcart[0]._order[0];
const messageData = {
debugMessages: '',
type: '',
id: '',
};
if (messages.length > 0) {
let debugMessages = '';
for (let i = 0; i < messages.length; i++) {
debugMessages = debugMessages.concat(`${messages[i]['debug-message']} \n `);
}
messageData.debugMessages = debugMessages;
messageData.type = messages[0].type;
messageData.id = messages[0].id;
}
ErrorInlet(messageData);
})
.catch((error) => {
// eslint-disable-next-line no-console
Expand Down
17 changes: 0 additions & 17 deletions app/src/containers/OrderReviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
} from '../utils/Analytics';
import { cortexFetch } from '../utils/Cortex';
import Config from '../ep.config.json';
import { ErrorInlet } from '../utils/MessageContext';

import './OrderReviewPage.less';

Expand Down Expand Up @@ -108,22 +107,6 @@ class OrderReviewPage extends React.Component<RouteComponentProps, OrderReviewPa
this.setState({
orderData: res._defaultcart[0],
});
if (res._defaultcart && res._defaultcart[0]._order && res._defaultcart[0]._order[0].messages[0]) {
const messageData = {
debugMessages: '',
type: '',
id: '',
};
let debugMessages = '';
const messagesArray = res._defaultcart[0]._order[0].messages;
for (let i = 0; i < messagesArray.length; i++) {
debugMessages = debugMessages.concat(`${messagesArray[i]['debug-message']} \n `);
}
messageData.debugMessages = debugMessages;
messageData.type = messagesArray[0].type;
messageData.id = messagesArray[0].id;
ErrorInlet(messageData);
}
})
.catch((error) => {
// eslint-disable-next-line no-console
Expand Down
50 changes: 35 additions & 15 deletions app/src/utils/Cortex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,42 @@ export function cortexFetch(input, init): any {
return timeout((<any>Config).cortexApi.reqTimeout || 30000, fetch(`${Config.cortexApi.path}${input}${queryFormat}`, requestInit)
.then((res) => {
res.clone().json().then((json) => {
if (json.messages) {
const messageData = {
debugMessages: '',
type: '',
id: '',
};
let debugMessages = '';
for (let i = 0; i < json.messages.length; i++) {
debugMessages = debugMessages.concat(`${json.messages[i]['debug-message']} \n `);
}
if (debugMessages) {
messageData.debugMessages = debugMessages;
messageData.type = json.messages[0].type;
messageData.id = json.messages[0].id;
ErrorInlet(messageData);
function getErrorMessages(data) {
let messages = [];
if (data.messages && data.messages.length) {
const messageData = {
debugMessages: '',
type: '',
id: '',
};
let debugMessages = '';
for (let i = 0; i < data.messages.length; i++) {
debugMessages = debugMessages.concat(`${data.messages[i]['debug-message']} \n `);
}
if (debugMessages) {
messageData.debugMessages = debugMessages;
messageData.type = data.messages[0].type;
messageData.id = data.messages[0].id;
if (messageData.id !== 'cart.is.not.empty') {
messages.push(messageData);
}
}
}
const dataKeys = Object.keys(data).filter(key => key[0] === '_');
dataKeys.forEach((key) => {
if (Array.isArray(data[key])) {
data[key].forEach((el) => {
const res1 = getErrorMessages(el);
messages = messages.concat(res1);
});
}
});
return messages;
}

const errorMessages = getErrorMessages(json);
if (errorMessages.length > 0) {
ErrorInlet(errorMessages[0]);
}
}).catch((error) => {
// eslint-disable-next-line no-console
Expand Down
24 changes: 21 additions & 3 deletions app/src/utils/MessageContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,35 @@ import React, {

const ErrorContext:any = React.createContext('');
let setE:any = () => {};
let removeE:any = () => {};
function ErrorDisplayBoundary({ children }) {
const [error, setError] = useState(null);
setE = setError;
const [error, setError]:any = useState([]);
const ctx:any = useMemo(() => ({ error, setError }), [error]);
// eslint-disable-next-line consistent-return
setE = (e) => {
if (e && error && error.find(el => el.debugMessages === e.debugMessages)) {
return [];
}
return setError([...error, e]);
};
removeE = (index) => {
const arrayMsg = [...error];
arrayMsg.splice(index, 1);
return setError(arrayMsg);
};
return (<ErrorContext.Provider value={ctx}>{children}</ErrorContext.Provider>);
}

function ErrorInlet(error) {
setE(error);
return null;
}

function ErrorRemove(index) {
removeE(index);
return null;
}

export {
ErrorContext, ErrorDisplayBoundary, ErrorInlet,
ErrorContext, ErrorDisplayBoundary, ErrorInlet, ErrorRemove,
};
2 changes: 1 addition & 1 deletion components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion components/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@elasticpath/store-components",
"version": "1.1.35",
"version": "1.1.36",
"main": "build/cjs/index",
"main:src": "src/index",
"types": "src/index",
Expand Down
10 changes: 0 additions & 10 deletions components/src/BulkOrder/bulkorder.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import { cortexFetch } from '../utils/Cortex';
import { getConfig, IEpConfig } from '../utils/ConfigProvider';

import './bulkorder.main.less';
import { ErrorInlet } from '../../../app/src/utils/MessageContext';

let Config: IEpConfig | any = {};
let intl = { get: (str, ...args: any[]) => str };
Expand Down Expand Up @@ -131,19 +130,10 @@ export class BulkOrder extends React.Component<BulkOrderProps, BulkOrderState> {
}
if (res.status >= 400) {
let debugMessages = '';
const messageData = {
debugMessages: '',
type: '',
id: '',
};
res.json().then((json) => {
for (let i = 0; i < json.messages.length; i++) {
debugMessages = debugMessages.concat(`\n${json.messages[i]['debug-message']} \n `);
}
messageData.debugMessages = debugMessages;
messageData.type = json.messages[0].type;
messageData.id = json.messages[0].id;
ErrorInlet(messageData);
}).then(() => {
if (isQuickOrder) {
this.setState({
Expand Down
74 changes: 49 additions & 25 deletions components/src/MessageContainer/messagecontainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,44 +24,68 @@ import { ReactComponent as CloseIcon } from '../../../app/src/images/icons/close
import { ReactComponent as ErrorIcon } from '../../../app/src/images/icons/error-icon.svg';
import { ReactComponent as WarningIcon } from '../../../app/src/images/icons/warning-icon.svg';
import { ReactComponent as InfoIcon } from '../../../app/src/images/icons/info-icon.svg';
import { ErrorInlet } from '../../../app/src/utils/MessageContext';
import { ErrorRemove } from '../../../app/src/utils/MessageContext';

import './messagecontainer.less';

interface MessageContainerProps {
message: any
}

class MessageContainer extends React.Component<MessageContainerProps> {
static handleCloseErrorMsg() {
ErrorInlet({});
interface MessageContainerState {
messages: any,
}

class MessageContainer extends React.Component<MessageContainerProps, MessageContainerState> {
constructor(props) {
super(props);
this.state = {
messages: [],
};
this.handleCloseMessageContainer = this.handleCloseMessageContainer.bind(this);
}

componentWillReceiveProps(nextProps) {
this.setState({ messages: nextProps.message });
}

handleCloseMessageContainer(index) {
const { messages } = this.state;
const arrayMsg = [...messages];
arrayMsg.splice(index, 1);
this.setState({ messages: arrayMsg });
ErrorRemove(index);
}

render() {
const { message } = this.props;
if (message && message.debugMessages) {
let messageType = '';
if (message.type === 'error' && message.id.includes('field')) {
messageType = 'warning-message';
} else if (message.type === 'error') {
messageType = 'danger-message';
} else if (message.type === 'needinfo') {
messageType = 'info-message';
}
const { messages } = this.state;
if (messages.length > 0) {
return (
<div className="debug-messages-block">
<div className="debug-messages-inner">
<div className={`container debug-messages-container ${messageType}`}>
<ErrorIcon className="debug-msg-icon error" />
<WarningIcon className="debug-msg-icon warning" />
<InfoIcon className="debug-msg-icon info" />
<p>
{message.debugMessages}
</p>
<button type="button" className="close-btn" onClick={MessageContainer.handleCloseErrorMsg}>
<CloseIcon />
</button>
</div>
{messages.map((el, index) => {
let messageType = '';
if (el.type === 'error' && el.id.includes('field')) {
messageType = 'warning-message';
} else if (el.type === 'error') {
messageType = 'danger-message';
} else if (el.type === 'needinfo') {
messageType = 'info-message';
}
return (
<div className={`container debug-messages-container ${messageType}`} key={`${el.id}_${Math.random().toString(36).substr(2, 9)}`}>
<ErrorIcon className="debug-msg-icon error" />
<WarningIcon className="debug-msg-icon warning" />
<InfoIcon className="debug-msg-icon info" />
<p>
{el.debugMessages}
</p>
<button type="button" className="close-btn" onClick={() => this.handleCloseMessageContainer(index)}>
<CloseIcon />
</button>
</div>
);
})}
</div>
</div>
);
Expand Down
39 changes: 21 additions & 18 deletions components/src/ProductDisplayItem/productdisplayitem.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -182,27 +182,30 @@ class ProductDisplayItemMain extends React.Component<ProductDisplayItemMainProps
}

componentWillReceiveProps(nextProps) {
login().then(() => {
itemLookup(nextProps.productId)
.then((res) => {
if (Config.arKit.enable) {
this.urlExists(Config.arKit.skuArImagesUrl.replace('%sku%', res._code[0].code), (exists) => {
const { productId } = this.props;
if (nextProps.productId !== productId) {
login().then(() => {
itemLookup(nextProps.productId)
.then((res) => {
if (Config.arKit.enable) {
this.urlExists(Config.arKit.skuArImagesUrl.replace('%sku%', res._code[0].code), (exists) => {
this.setState({
productData: res,
arFileExists: exists,
});
});
} else {
this.setState({
productData: res,
arFileExists: exists,
});
});
} else {
this.setState({
productData: res,
});
}
})
.catch((error) => {
// eslint-disable-next-line no-console
console.error(error.message);
});
});
}
})
.catch((error) => {
// eslint-disable-next-line no-console
console.error(error.message);
});
});
}
}

fetchMultiCartData() {
Expand Down
2 changes: 1 addition & 1 deletion components/src/PurchaseDetails/purchasedetails.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const PurchaseDetailsMain: React.FunctionComponent<PurchaseDetailsMainProps> = (
{intl.get('payment-method')}
</h3>
{postedPayments[0]._element.map(postedpayment => (
<PaymentMethodContainer displayName={postedpayment} />
<PaymentMethodContainer displayName={postedpayment} key={postedpayment['display-name']} />
))}
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion components/src/QuickOrder/quickorder.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ class QuickOrderMain extends React.Component<QuickOrderMainProps, QuickOrderMain
</div>
<CartLineItem
key={Math.floor(Math.random() * 1000000001)}
item={data}
item={productItemInfo}
itemQuantity={itemQuantity}
handleQuantityChange={() => { this.handleQuantityChange(); }}
hideRemoveButton
Expand Down
2 changes: 2 additions & 0 deletions components/src/QuickOrderForm/quickorderform.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class QuickOrderForm extends React.Component<QuickOrderFormProps, QuickOrderForm
} else if (!res._price) {
this.setState({
skuErrorMessage: `${intl.get('product-message-without-price', { SKUCode: productId })}`,
product: res,
isLoading: false,
});
onItemSubmit({
code, quantity, product: {}, isValidField: false,
Expand Down
2 changes: 1 addition & 1 deletion components/src/Reorder/reorder.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ class ReorderMain extends React.Component<ReorderMainProps, ReorderMainState> {
{productsData._lineitems[0]._element.map((item) => {
const { quantity, _code } = item._item[0];
return (
<div>
<div key={item.name}>
<CartLineItem
key={_code[0].code}
item={item._item[0]}
Expand Down
Loading

0 comments on commit 39abd81

Please sign in to comment.