From 068069800ed811ac4bc23a601b93b87de5c6bffc Mon Sep 17 00:00:00 2001 From: "Jana E. Beck" Date: Wed, 27 May 2015 17:20:45 -0700 Subject: [PATCH 1/6] redirect to new page on jellyfish upload metadata error --- lib/state/appActions.js | 7 +++++++ test/ui/testAppActions.js | 24 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/lib/state/appActions.js b/lib/state/appActions.js index e39e675b93..277839f196 100644 --- a/lib/state/appActions.js +++ b/lib/state/appActions.js @@ -62,6 +62,7 @@ appActions.errorStages = { STAGE_PICK_FILE : { code: 'E_SELECTING_FILE' , friendlyMessage: 'Error during file selection' }, STAGE_READ_FILE : { code: 'E_READING_FILE' , friendlyMessage: 'Error trying to read file' }, STAGE_UPLOAD : { code: 'E_UPLOADING' , friendlyMessage: 'Error uploading data' }, + STAGE_METADATA_UPLOAD : { code: 'E_METADATA_UPLOAD' , friendlyMessage: 'Error uploading upload metadata'}, STAGE_DEVICE_UPLOAD : { code: 'E_DEVICE_UPLOAD' , friendlyMessage: 'Error uploading device data' }, STAGE_DEVICE_DETECT : { code: 'E_DEVICE_DETECT' , friendlyMessage: 'Error trying to detect a device' }, STAGE_CARELINK_UPLOAD : { code: 'E_CARELINK_UPLOAD' , friendlyMessage: 'Error uploading CareLink data' }, @@ -660,6 +661,12 @@ appActions._handleUploadError = function(uploadIndex, error) { } return upload; }); + + if (error.code === appActions.errorStages['STAGE_METADATA_UPLOAD'].code) { + this.app.setState({ + page: 'error' + }); + } }; appActions._addToUploadHistory = function(upload, instance) { diff --git a/test/ui/testAppActions.js b/test/ui/testAppActions.js index efdf9f1140..4cce2707b6 100644 --- a/test/ui/testAppActions.js +++ b/test/ui/testAppActions.js @@ -824,6 +824,30 @@ describe('appActions', function() { }); }); + it('redirects to the `error` page if jellyfish errors because uploader is out-of-date', function(done) { + now = '2014-01-31T22:00:00-05:00'; + device.detect = function(driverId, options, cb) { return cb(null, {}); }; + device.upload = function(driverId, options, cb) { + now = '2014-01-31T22:00:30-05:00'; + options.progress('fetchData', 50); + var err = new Error('Oops, we got an error'); + err.code = 'E_METADATA_UPLOAD'; + return cb(err); + }; + app.state.targetId = '11'; + app.state.uploads = [{ + source: { + type: 'device', + driverId: 'DexcomG4' + } + }]; + + appActions.upload(0, {}, function(err) { + expect(app.state.page).to.equal('error'); + done(); + }); + }); + }); }); \ No newline at end of file From fc0642232c19a965ba452337b4b6c3bb75db38ff Mon Sep 17 00:00:00 2001 From: "Jana E. Beck" Date: Wed, 27 May 2015 19:27:12 -0700 Subject: [PATCH 2/6] first go at UpdatePlease component with styling --- lib/components/App.jsx | 7 ++++++ lib/components/UpdatePlease.jsx | 35 ++++++++++++++++++++++++++ styles/components/App.less | 2 +- styles/components/DeviceSelection.less | 4 +-- styles/components/UpdatePlease.less | 21 ++++++++++++++++ styles/core/mixins.less | 18 +++++++++++++ styles/main.less | 1 + 7 files changed, 84 insertions(+), 4 deletions(-) create mode 100644 lib/components/UpdatePlease.jsx create mode 100644 styles/components/UpdatePlease.less diff --git a/lib/components/App.jsx b/lib/components/App.jsx index e42d6932ed..5877d5d72c 100644 --- a/lib/components/App.jsx +++ b/lib/components/App.jsx @@ -28,6 +28,7 @@ var UploadList = require('./UploadList.jsx'); var ViewDataLink = require('./ViewDataLink.jsx'); var UploadSettings = require('./UploadSettings.jsx'); var DeviceSelection = require('./DeviceSelection.jsx'); +var UpdatePlease = require('./UpdatePlease.jsx'); var config = require('../config'); @@ -126,6 +127,12 @@ var App = React.createClass({ ); } + if (page === 'error') { + return ( + + ); + } + return null; }, diff --git a/lib/components/UpdatePlease.jsx b/lib/components/UpdatePlease.jsx new file mode 100644 index 0000000000..ce2f7eb6ff --- /dev/null +++ b/lib/components/UpdatePlease.jsx @@ -0,0 +1,35 @@ +/* +* == BSD2 LICENSE == +* Copyright (c) 2014, Tidepool Project +* +* This program is free software; you can redistribute it and/or modify it under +* the terms of the associated License, which is identical to the BSD 2-Clause +* License as published by the Open Source Initiative at opensource.org. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +* FOR A PARTICULAR PURPOSE. See the License for more details. +* +* You should have received a copy of the License along with this program; if +* not, you can obtain one from Tidepool Project at tidepool.org. +* == BSD2 LICENSE == +*/ + +var React = require('react'); + +var UpdatePlease = React.createClass({ + propTypes: { + link: React.PropTypes.string.isRequired + }, + render: function() { + return ( +
+

Your uploader is out-of-date.

+

Please follow the instructions here to update it.

+

Then try your upload again!

+
+ ); + } +}); + +module.exports = UpdatePlease; \ No newline at end of file diff --git a/styles/components/App.less b/styles/components/App.less index a006cedeef..0628178929 100644 --- a/styles/components/App.less +++ b/styles/components/App.less @@ -39,7 +39,7 @@ @App-mainPageBorder: 1px; -.App--main .App-page, .App--settings .App-page { +.App--main .App-page, .App--settings .App-page, .App--error .App-page { width: 550px; background-color: rgba(255, 255, 255, 0.75); border: @App-mainPageBorder solid @gray-border; diff --git a/styles/components/DeviceSelection.less b/styles/components/DeviceSelection.less index 54af9b849b..94d08f5ed0 100644 --- a/styles/components/DeviceSelection.less +++ b/styles/components/DeviceSelection.less @@ -1,8 +1,6 @@ .DeviceSelection { - min-height: 300px; - justify-content: center; + .center-container; } - .DeviceSelection-headline { width: 250px; margin: 20px auto 20px auto; diff --git a/styles/components/UpdatePlease.less b/styles/components/UpdatePlease.less new file mode 100644 index 0000000000..ebc32d0b0d --- /dev/null +++ b/styles/components/UpdatePlease.less @@ -0,0 +1,21 @@ +.UpdatePlease { + .center-container; + + a { + .blue-link; + } + + p { + font-size: 1.2em; + text-align: center; + // our box-flex mixin wreaked havoc here and was making spans display flex + // (effectively block) + // TODO: fix that at the source + span { + display: inline; + } + &.most-important { + font-weight: bold; + } + } +} diff --git a/styles/core/mixins.less b/styles/core/mixins.less index ab0175c4bb..8c1f9e98d1 100644 --- a/styles/core/mixins.less +++ b/styles/core/mixins.less @@ -34,3 +34,21 @@ padding-right: 15px; overflow-y: scroll; } + +// used so far for DeviceSelection and UpdatePlease +.center-container { + min-height: 300px; + justify-content: center; +} + +// a common link style +.blue-link { + color: lighten(@purple-dark, 20%); + + &:hover, + &:focus, + &:active { + color: @blue; + text-decoration: none; + } +} diff --git a/styles/main.less b/styles/main.less index 021482a5e8..d50f1154a1 100644 --- a/styles/main.less +++ b/styles/main.less @@ -35,6 +35,7 @@ @import "components/Login.less"; @import "components/ProgressBar.less"; @import "components/Scan.less"; +@import "components/UpdatePlease.less"; @import "components/Upload.less"; @import "components/UploadList.less"; @import "components/UploadSettings.less"; From 0c25059ce8096c7238bc82139ed666914ecd1b54 Mon Sep 17 00:00:00 2001 From: "Jana E. Beck" Date: Fri, 29 May 2015 12:32:27 -0700 Subject: [PATCH 3/6] update jellyfish error handling for outdated version error --- lib/state/appActions.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/state/appActions.js b/lib/state/appActions.js index c75b1e126a..98fbeccd13 100644 --- a/lib/state/appActions.js +++ b/lib/state/appActions.js @@ -76,6 +76,12 @@ function extractMessage(err) { } // if err.message is an object, that's because it's an error from jellyfish else if (typeof err.message === 'object' && err.message.message) { + if (typeof err.message.message === 'object' && err.message.message.code === 'outdatedVersion') { + var stage = appActions.errorStages['STAGE_METADATA_UPLOAD']; + err.code = stage.code; + err.friendlyMessage = stage.friendlyMessage; + return err.message.message.text; + } return err.message.message; } // sometimes the jellyfish errors don't have a `message`, only a `reason`?? *shrug* From 577ea3a06cc21288b476e61ca67a4988eb47385c Mon Sep 17 00:00:00 2001 From: "Jana E. Beck" Date: Mon, 8 Jun 2015 16:25:52 -0700 Subject: [PATCH 4/6] update jellyfish error handling when outdated uploader version --- lib/state/appActions.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/state/appActions.js b/lib/state/appActions.js index 5e562cac52..3eddcb407a 100644 --- a/lib/state/appActions.js +++ b/lib/state/appActions.js @@ -75,18 +75,17 @@ function extractMessage(err) { return err.error || 'Unknown error message'; } // if err.message is an object, that's because it's an error from jellyfish - else if (typeof err.message === 'object' && err.message.message) { - if (typeof err.message.message === 'object' && err.message.message.code === 'outdatedVersion') { + else if (typeof err.message === 'object') { + if (err.message.code === 'outdatedVersion') { var stage = appActions.errorStages['STAGE_METADATA_UPLOAD']; err.code = stage.code; err.friendlyMessage = stage.friendlyMessage; - return err.message.message.text; + return err.message.text; + } + // sometimes the jellyfish errors don't have a `message`, only a `reason`?? *shrug* + else if (err.message.reason) { + return err.message.reason; } - return err.message.message; - } - // sometimes the jellyfish errors don't have a `message`, only a `reason`?? *shrug* - else if (typeof err.message === 'object' && err.message.reason) { - return err.message.reason; } else { return err.message; From 3a830ec432a9a20b34ae315040630814e6c2a70c Mon Sep 17 00:00:00 2001 From: "Jana E. Beck" Date: Mon, 8 Jun 2015 16:28:20 -0700 Subject: [PATCH 5/6] add comment re: TODO add link to tidepool.org or knowledge base page explaining how to update uploader --- lib/components/App.jsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/components/App.jsx b/lib/components/App.jsx index dfc56f679c..8b931deb2d 100644 --- a/lib/components/App.jsx +++ b/lib/components/App.jsx @@ -134,6 +134,8 @@ var App = React.createClass({ if (page === 'error') { return ( + // TODO: add the link to help page on tidepool.org or knowledge base + // re: how to update the uploader ); } From 9cb679dd1ba970c119876c875067318c5685a483 Mon Sep 17 00:00:00 2001 From: "Jana E. Beck" Date: Mon, 8 Jun 2015 19:27:53 -0700 Subject: [PATCH 6/6] factor out text (for future internationalization?) --- lib/components/UpdatePlease.jsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/components/UpdatePlease.jsx b/lib/components/UpdatePlease.jsx index ce2f7eb6ff..ca2de9fd06 100644 --- a/lib/components/UpdatePlease.jsx +++ b/lib/components/UpdatePlease.jsx @@ -22,11 +22,18 @@ var UpdatePlease = React.createClass({ link: React.PropTypes.string.isRequired }, render: function() { + var text = { + OUT_OF_DATE: 'Your uploader is out-of-date.', + TO_UPDATE: 'To update it, please follow ', + LINK_TEXT: 'these instructions', + TRY_AGAIN: 'Then try your upload again!' + }; + return (
-

Your uploader is out-of-date.

-

Please follow the instructions here to update it.

-

Then try your upload again!

+

{text.OUT_OF_DATE}

+

{text.TO_UPDATE}{text.LINK_TEXT}.

+

{text.TRY_AGAIN}

); }