From dc90ca080749de2e48f79d509e861637af06f09d Mon Sep 17 00:00:00 2001 From: Forrest Li Date: Mon, 23 Apr 2018 17:18:43 -0400 Subject: [PATCH 1/2] fix(FileLoader): Display error notification to user on errored load --- Sources/MainView.js | 12 ++++++ Sources/controls/FileLoader/index.js | 9 +++- Sources/io/ReaderFactory.js | 8 ++-- Sources/ui/Messages/Messages.mcss | 8 ++++ Sources/ui/Messages/index.js | 47 +++++++++++++++++++++ Sources/ui/index.js | 2 + package-lock.json | 63 +++++++++++++++------------- package.json | 1 + 8 files changed, 117 insertions(+), 33 deletions(-) create mode 100644 Sources/ui/Messages/Messages.mcss create mode 100644 Sources/ui/Messages/index.js diff --git a/Sources/MainView.js b/Sources/MainView.js index 1731c065..dd2997ad 100644 --- a/Sources/MainView.js +++ b/Sources/MainView.js @@ -3,6 +3,9 @@ import 'normalize.css/normalize.css'; import React from 'react'; import PropTypes from 'prop-types'; +import { ToastContainer, Slide } from 'react-toastify'; +import 'react-toastify/dist/ReactToastify.css'; + import UI from './ui'; import Layouts from './layouts'; import LayoutConfig from './config/glanceLayoutConfig'; @@ -185,6 +188,15 @@ export default class MainView extends React.Component { > + ); } diff --git a/Sources/controls/FileLoader/index.js b/Sources/controls/FileLoader/index.js index c7ba62ee..aea90b97 100644 --- a/Sources/controls/FileLoader/index.js +++ b/Sources/controls/FileLoader/index.js @@ -1,12 +1,14 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { toast } from 'react-toastify'; + import UI from '../../ui'; import ReaderFactory from '../../io/ReaderFactory'; import RawReader from './RawReader'; import style from './FileLoader.mcss'; -const { Button, FaIcon } = UI; +const { Button, FaIcon, Messages } = UI; export default class FileLoader extends React.Component { constructor(props) { @@ -34,7 +36,10 @@ export default class FileLoader extends React.Component { this.setState({ file: null }); this.props.updateTab('pipeline'); }) - .catch(() => { + .catch((error) => { + if (error) { + toast.error(Messages.LoadFailure); + } // No reader found if (files.length === 1) { this.setState({ file: files[0] }); diff --git a/Sources/io/ReaderFactory.js b/Sources/io/ReaderFactory.js index 5e07d51c..44fce44a 100644 --- a/Sources/io/ReaderFactory.js +++ b/Sources/io/ReaderFactory.js @@ -95,9 +95,11 @@ function readRawData({ fileName, data }) { reader[fileNameMethod](fileName); } const ds = reader[parseMethod](data); - Promise.resolve(ds).then((dataset) => - resolve({ dataset, reader, sourceType, name: fileName }) - ); + Promise.resolve(ds) + .then((dataset) => + resolve({ dataset, reader, sourceType, name: fileName }) + ) + .catch(reject); } else { reject(); } diff --git a/Sources/ui/Messages/Messages.mcss b/Sources/ui/Messages/Messages.mcss new file mode 100644 index 00000000..e04ac1d5 --- /dev/null +++ b/Sources/ui/Messages/Messages.mcss @@ -0,0 +1,8 @@ +.errorLine { + margin: 0; + padding: 2px; +} + +.errorLink { + color: yellow; +} diff --git a/Sources/ui/Messages/index.js b/Sources/ui/Messages/index.js new file mode 100644 index 00000000..b504cb6e --- /dev/null +++ b/Sources/ui/Messages/index.js @@ -0,0 +1,47 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import style from './Messages.mcss'; + +function Link(props) { + return ( + + {props.children} + + ); +} + +Link.propTypes = { + children: PropTypes.node, +}; + +Link.defaultProps = { + children: null, +}; + +export const LoadFailure = ( +
+

Failed to load image.

+

+ + Perhaps AdBlock is enabled? + +

+

+ Or your image is not yet supported.  + + Tell us! + +

+
+); + +export default { + LoadFailure, +}; diff --git a/Sources/ui/index.js b/Sources/ui/index.js index 3c48bd46..1d62df16 100644 --- a/Sources/ui/index.js +++ b/Sources/ui/index.js @@ -1,4 +1,5 @@ import Button from './Button'; +import Messages from './Messages'; import FaIcon from './FaIcon'; import Menu from './Menu'; import Progress from './Progress'; @@ -6,6 +7,7 @@ import TitleModal from './TitleModal'; export default { Button, + Messages, FaIcon, Menu, Progress, diff --git a/package-lock.json b/package-lock.json index 157a72fc..580612da 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1030,8 +1030,7 @@ "asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", - "dev": true + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" }, "asn1.js": { "version": "4.10.1", @@ -2988,8 +2987,7 @@ "classnames": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", - "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=", - "dev": true + "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=" }, "clean-css": { "version": "4.1.11", @@ -4440,6 +4438,11 @@ } } }, + "dom-helpers": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz", + "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg==" + }, "dom-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", @@ -4624,7 +4627,6 @@ "version": "0.1.12", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, "requires": { "iconv-lite": "0.4.21" } @@ -5810,7 +5812,6 @@ "version": "0.8.16", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", - "dev": true, "requires": { "core-js": "1.2.7", "isomorphic-fetch": "2.2.1", @@ -5824,8 +5825,7 @@ "core-js": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", - "dev": true + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" } } }, @@ -8232,7 +8232,6 @@ "version": "0.4.21", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", - "dev": true, "requires": { "safer-buffer": "2.1.2" } @@ -9003,8 +9002,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-subset": { "version": "0.1.1", @@ -9087,7 +9085,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "dev": true, "requires": { "node-fetch": "1.7.3", "whatwg-fetch": "2.0.4" @@ -9164,8 +9161,7 @@ "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" }, "js-yaml": { "version": "3.7.0", @@ -9968,7 +9964,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, "requires": { "js-tokens": "3.0.2" } @@ -10688,7 +10683,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, "requires": { "encoding": "0.1.12", "is-stream": "1.1.0" @@ -10880,8 +10874,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", @@ -17813,7 +17806,6 @@ "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "dev": true, "requires": { "asap": "2.0.6" } @@ -17834,7 +17826,6 @@ "version": "15.6.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz", "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==", - "dev": true, "requires": { "fbjs": "0.8.16", "loose-envify": "1.3.1", @@ -18271,6 +18262,26 @@ "warning": "3.0.0" } }, + "react-toastify": { + "version": "4.0.0-rc.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-4.0.0-rc.5.tgz", + "integrity": "sha512-0wviE5FjfITvIAze9b2mLFaA8CDNXpTF2ZGbNkOrqZzv86hbMNMBq+kxOEe0dySsSVvxg8u1L9WO/6aPuYYrDQ==", + "requires": { + "classnames": "2.2.5", + "prop-types": "15.6.1", + "react-transition-group": "2.3.1" + } + }, + "react-transition-group": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.3.1.tgz", + "integrity": "sha512-hu4/LAOFSKjWt1+1hgnOv3ldxmt6lvZGTWz4KUkFrqzXrNDIVSu6txIcPszw7PNduR8en9YTN55JLRyd/L1ZiQ==", + "requires": { + "dom-helpers": "3.3.1", + "loose-envify": "1.3.1", + "prop-types": "15.6.1" + } + }, "read-chunk": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-2.1.0.tgz", @@ -18830,8 +18841,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sax": { "version": "1.2.4", @@ -19245,8 +19255,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" }, "setprototypeof": { "version": "1.1.0", @@ -20901,8 +20910,7 @@ "ua-parser-js": { "version": "0.7.17", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==", - "dev": true + "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" }, "uglify-js": { "version": "3.3.20", @@ -22609,8 +22617,7 @@ "whatwg-fetch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", - "dev": true + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" }, "whet.extend": { "version": "0.9.9", diff --git a/package.json b/package.json index 98807c9f..b396cdbf 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "mout": "1.0.0", "normalize.css": "^8.0.0", "paraviewweb": "3.0.13", + "react-toastify": "^4.0.0-rc.5", "shelljs": "0.7.8", "vtk.js": "6.4.19" }, From ce5c0815321672c0be97e77d38ca395c1fe2ff7b Mon Sep 17 00:00:00 2001 From: Forrest Li Date: Mon, 23 Apr 2018 17:19:20 -0400 Subject: [PATCH 2/2] fix(RawReader): No loading prop on Button --- Sources/controls/FileLoader/RawReader.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Sources/controls/FileLoader/RawReader.js b/Sources/controls/FileLoader/RawReader.js index 7e4030e7..27029806 100644 --- a/Sources/controls/FileLoader/RawReader.js +++ b/Sources/controls/FileLoader/RawReader.js @@ -210,9 +210,8 @@ export default class RawReader extends React.Component {