Skip to content

Commit

Permalink
Merge pull request #181 from davidrosenblum/exports-modal-refactor
Browse files Browse the repository at this point in the history
Exports modal rector - new file + copy text
  • Loading branch information
davidrosenblum authored Nov 20, 2018
2 parents ffd8f24 + 0f9c036 commit 228c492
Show file tree
Hide file tree
Showing 18 changed files with 218 additions and 179 deletions.
14 changes: 7 additions & 7 deletions web/build/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"main.css": "/static/css/main.3f045fbd.chunk.css",
"main.js": "/static/js/main.360a4901.chunk.js",
"main.js.map": "/static/js/main.360a4901.chunk.js.map",
"static/js/1.bb64f55a.chunk.js": "/static/js/1.bb64f55a.chunk.js",
"static/js/1.bb64f55a.chunk.js.map": "/static/js/1.bb64f55a.chunk.js.map",
"main.css": "/static/css/main.ea2cd49b.chunk.css",
"main.js": "/static/js/main.bc5c6c73.chunk.js",
"main.js.map": "/static/js/main.bc5c6c73.chunk.js.map",
"static/js/1.8c800647.chunk.js": "/static/js/1.8c800647.chunk.js",
"static/js/1.8c800647.chunk.js.map": "/static/js/1.8c800647.chunk.js.map",
"runtime~main.js": "/static/js/runtime~main.229c360f.js",
"runtime~main.js.map": "/static/js/runtime~main.229c360f.js.map",
"static/css/main.3f045fbd.chunk.css.map": "/static/css/main.3f045fbd.chunk.css.map",
"static/css/main.ea2cd49b.chunk.css.map": "/static/css/main.ea2cd49b.chunk.css.map",
"index.html": "/index.html",
"precache-manifest.9d55ac0d557ef13c93a360878e757dbb.js": "/precache-manifest.9d55ac0d557ef13c93a360878e757dbb.js",
"precache-manifest.135e02cd615be672e63b794c3750fbe3.js": "/precache-manifest.135e02cd615be672e63b794c3750fbe3.js",
"service-worker.js": "/service-worker.js"
}
2 changes: 1 addition & 1 deletion web/build/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><title>Plague Project</title><link rel="icon" href="/favicon.png" type="image/png"/><link href="/static/css/main.3f045fbd.chunk.css" rel="stylesheet"></head><body><div id="root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],p[t]&&i.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},p={2:0},c=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var r=window.webpackJsonp=window.webpackJsonp||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="/static/js/1.bb64f55a.chunk.js"></script><script src="/static/js/main.360a4901.chunk.js"></script></body></html>
<!doctype html><html lang="en"><head><title>Plague Project</title><link rel="icon" href="/favicon.png" type="image/png"/><link href="/static/css/main.ea2cd49b.chunk.css" rel="stylesheet"></head><body><div id="root"></div><script>!function(l){function e(e){for(var r,t,n=e[0],o=e[1],u=e[2],f=0,i=[];f<n.length;f++)t=n[f],p[t]&&i.push(p[t][0]),p[t]=0;for(r in o)Object.prototype.hasOwnProperty.call(o,r)&&(l[r]=o[r]);for(s&&s(e);i.length;)i.shift()();return c.push.apply(c,u||[]),a()}function a(){for(var e,r=0;r<c.length;r++){for(var t=c[r],n=!0,o=1;o<t.length;o++){var u=t[o];0!==p[u]&&(n=!1)}n&&(c.splice(r--,1),e=f(f.s=t[0]))}return e}var t={},p={2:0},c=[];function f(e){if(t[e])return t[e].exports;var r=t[e]={i:e,l:!1,exports:{}};return l[e].call(r.exports,r,r.exports,f),r.l=!0,r.exports}f.m=l,f.c=t,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(r,e){if(1&e&&(r=f(r)),8&e)return r;if(4&e&&"object"==typeof r&&r&&r.__esModule)return r;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:r}),2&e&&"string"!=typeof r)for(var n in r)f.d(t,n,function(e){return r[e]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var r=window.webpackJsonp=window.webpackJsonp||[],n=r.push.bind(r);r.push=e,r=r.slice();for(var o=0;o<r.length;o++)e(r[o]);var s=n;a()}([])</script><script src="/static/js/1.8c800647.chunk.js"></script><script src="/static/js/main.bc5c6c73.chunk.js"></script></body></html>
22 changes: 22 additions & 0 deletions web/build/precache-manifest.135e02cd615be672e63b794c3750fbe3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
self.__precacheManifest = [
{
"revision": "229c360febb4351a89df",
"url": "/static/js/runtime~main.229c360f.js"
},
{
"revision": "bc5c6c737a6a0d3e9ddf",
"url": "/static/js/main.bc5c6c73.chunk.js"
},
{
"revision": "8c8006471e5ab62c26c1",
"url": "/static/js/1.8c800647.chunk.js"
},
{
"revision": "bc5c6c737a6a0d3e9ddf",
"url": "/static/css/main.ea2cd49b.chunk.css"
},
{
"revision": "7041021ee90422cb209936602582f59f",
"url": "/index.html"
}
];
22 changes: 0 additions & 22 deletions web/build/precache-manifest.9d55ac0d557ef13c93a360878e757dbb.js

This file was deleted.

2 changes: 1 addition & 1 deletion web/build/service-worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.2/workbox-sw.js");

importScripts(
"/precache-manifest.9d55ac0d557ef13c93a360878e757dbb.js"
"/precache-manifest.135e02cd615be672e63b794c3750fbe3.js"
);

workbox.clientsClaim();
Expand Down
1 change: 0 additions & 1 deletion web/build/static/css/main.3f045fbd.chunk.css.map

This file was deleted.

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions web/build/static/css/main.ea2cd49b.chunk.css.map

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions web/build/static/js/main.360a4901.chunk.js

This file was deleted.

1 change: 0 additions & 1 deletion web/build/static/js/main.360a4901.chunk.js.map

This file was deleted.

2 changes: 2 additions & 0 deletions web/build/static/js/main.bc5c6c73.chunk.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions web/build/static/js/main.bc5c6c73.chunk.js.map

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions web/src/components/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -156,11 +156,4 @@ footer a:hover{
height: 100%;
max-width: 650px;
max-height: 200px;
}

.modal-url-text{
width: 100%;
min-height: 125px;
border: 1px solid gray;
border-radius: 6px;
}
10 changes: 10 additions & 0 deletions web/src/components/ExportsModal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.copy-text-container{
float: right;
}

.modal-url-text{
width: 100%;
min-height: 125px;
border: 1px solid gray;
border-radius: 6px;
}
155 changes: 155 additions & 0 deletions web/src/components/ExportsModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import "./ExportsModal.css";
import React from "react";
import { Modal, ModalBody, ModalHeader, Dropdown, DropdownItem, DropdownMenu, DropdownToggle, Button, Input } from "reactstrap";
import Simulator from "../Simulator";
import GraphData from "../GraphData";

export class ExportsModal extends React.Component{
constructor(props){
super(props);

// export refs
this.exportUrlRef = React.createRef();
this.csvFilenameElement = null; // later to set an <input> (reactstrap inner ref)

this.state = {
exportOption: null,
exportDropdown: false,
copyMessage: null
};
}

// downloads the csv file
downloadCSV(){
if(!this.state.pending){
// disable buttons
this.setState({pending: true});

// optional filename override
let filename = this.csvFilenameElement ? this.csvFilenameElement.value : null;

Simulator.downloadCSVFile(this.props.getInputsDictionary(), filename)
.catch(err => {
// something went wrong (server did not respond or bad request)
this.setState({message: err.message});
})
.then(() => {
// (this fires when any response happens not successful only!)
// always enable buttons
this.setState({pending: false})
});
}
}

toggleModal(){
this.setState({exportOption: null, copyMessage: null});
this.props.toggle();
}

toggleExportDropdown(){
this.setState(prev => ({exportDropdown: !prev.exportDropdown}));
}

getExportURL(){
let dict = this.props.getInputsDictionary();

let url = `${window.location.origin}?`;

for(let param in dict){
url += `${param}=${dict[param]}&`;
}

url += `trend_line=${GraphData.trendLineY}`;

return url;
}

copyLinkText(){
let elem = this.exportUrlRef.current;
if(elem){
elem.select();
document.execCommand("copy");

this.setState({copyMessage: "(Copied to clipboard)"});
}
}

renderExportOptBody(){
if(this.state.exportOption === "csv"){
return (
<div>
<div>
Exports a comma separated value (.csv) file containing the results displayed in the table.
This file is easily accesible in Excel.
</div>
<br/>
<div>
<Input
innerRef={element => this.csvFilenameElement = element}
placeholder="Optional filename (.csv automatically appended)"
type="text"
maxLength={25}
/>
</div>
<br/>
<div>
<Button color="fade" onClick={this.downloadCSV.bind(this)}>Download CSV</Button>
</div>
</div>
);
}
else if(this.state.exportOption === "sim-link"){
return (
<div>
<div>
Exports a URL for this application with preset values that can be shared.
</div>
<br/>
<div>
<textarea ref={this.exportUrlRef} className="modal-url-text" defaultValue={this.getExportURL()} readOnly>
</textarea>
</div>
<br/>
<div>
<Button color="fade" onClick={this.copyLinkText.bind(this)}>Copy Link</Button>
<span className="copy-text-container">
{this.state.copyMessage}
</span>
</div>
</div>
);
}
return (
<div>
Please select an export option.
</div>
)
}

render(){
return (
<Modal isOpen={this.props.isOpen}>
<ModalHeader toggle={this.toggleModal.bind(this)}>
<Dropdown isOpen={this.state.exportDropdown} toggle={this.toggleExportDropdown.bind(this)}>
<DropdownToggle color="fade" caret>
Export Options
</DropdownToggle>
<DropdownMenu>
<DropdownItem onClick={() => this.setState({exportOption: "csv"})}>
Table CSV
</DropdownItem>
<DropdownItem onClick={() => this.setState({exportOption: "sim-link"})}>
Simulation Link
</DropdownItem>
</DropdownMenu>
</Dropdown>
</ModalHeader>
<ModalBody>
<div>
{this.renderExportOptBody()}
</div>
</ModalBody>
</Modal>
);
}
}
Loading

0 comments on commit 228c492

Please sign in to comment.