Skip to content

Commit

Permalink
Merge pull request #273 from KPMP/develop
Browse files Browse the repository at this point in the history
v2.7 release merge
  • Loading branch information
rlreamy authored Dec 20, 2019
2 parents 5be5fb4 + 117c228 commit d287843
Show file tree
Hide file tree
Showing 17 changed files with 3,543 additions and 3,176 deletions.
19 changes: 11 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
# Development Environment
* Create an environment file (.env) in the root of this project. See .env.example for referece.
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/b7c3c2e2642c4f6780de82e1ee6aef50)](https://www.codacy.com/manual/rlreamy/orion-web?utm_source=github.com&utm_medium=referral&utm_content=KPMP/orion-web&utm_campaign=Badge_Grade)
[![Build Status](https://travis-ci.org/KPMP/orion-web.svg?branch=develop)](https://travis-ci.org/KPMP/orion-web)

# orion-web
Repo for the KPMP upload tool front-end

## Development Environment
* Create an environment file (.env) in the root of this project. See .env.example for referece.

## Windows
* Uses /~https://github.com/Angelinsky7/Docker-Volume-Watcher for watching the host filesystem and sending linux container events via sh/bash when a file changes. Docker for Windows natively does not support this.
* Folders/files may be ignored from watch task for faster compilations within .dvwignore file in root.
* Uses </~https://github.com/Angelinsky7/Docker-Volume-Watcher> for watching the host filesystem and sending linux container events via sh/bash when a file changes. Docker for Windows natively does not support this.
* Folders/files may be ignored from watch task for faster compilations within .dvwignore file in root.

## MacOS
* Natively supported

# orion-web
Repo for the KPMP upload tool front-end
* Natively supported
5,975 changes: 3,074 additions & 2,901 deletions package-lock.json

Large diffs are not rendered by default.

57 changes: 27 additions & 30 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
{
"name": "orion-web",
"version": "2.4.0",
"version": "2.6.0",
"private": true,
"devDependencies": {
"acorn": "7.0.0",
"enzyme": "3.9.0",
"enzyme-adapter-react-16": "1.10.0",
"node-sass-chokidar": "1.3.4",
"acorn": "7.1.0",
"enzyme": "3.10.0",
"enzyme-adapter-react-16": "1.15.1",
"node-sass-chokidar": "1.4.0",
"npm-run-all": "4.1.5",
"react-scripts": "3.1.1"
"react-scripts": "3.2.0"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "1.2.8",
"@fortawesome/free-brands-svg-icons": "^5.10.2",
"@fortawesome/free-regular-svg-icons": "^5.10.2",
"@fortawesome/free-solid-svg-icons": "5.5.0",
"@fortawesome/react-fontawesome": "0.1.3",
"antd": "3.14.1",
"@fortawesome/fontawesome-svg-core": "1.2.25",
"@fortawesome/free-brands-svg-icons": "5.11.2",
"@fortawesome/free-regular-svg-icons": "5.11.2",
"@fortawesome/free-solid-svg-icons": "5.11.2",
"@fortawesome/react-fontawesome": "0.1.7",
"antd": "3.26.0",
"axios": "0.19.0",
"bootstrap-css-only": "4.3.1",
"bowser": "2.3.0",
"braces": "2.3.2",
"bowser": "2.7.0",
"braces": "3.0.2",
"dateformat": "3.0.3",
"detect-browser": "2.5.1",
"eslint": "6.3.0",
"filesize": "3.6.1",
"detect-browser": "4.8.0",
"eslint": "6.7.2",
"filesize": "6.0.1",
"fine-uploader": "5.16.2",
"js-polyfills": "0.1.42",
"moment": "2.24.0",
"popper.js": "1.14.3",
"popper.js": "1.16.0",
"prop-types": "15.7.2",
"react": "16.7.0",
"react-datetime": "2.14.0",
"react-dom": "16.7.0",
"react": "16.12.0",
"react-datetime": "2.16.3",
"react-dom": "16.12.0",
"react-fine-uploader": "1.1.1",
"react-ga": "2.5.3",
"react-redux": "5.1.1",
"react-router-dom": "4.3.1",
"react-ga": "2.7.0",
"react-redux": "7.1.3",
"react-router-dom": "5.1.2",
"react-switch": "5.0.1",
"react-tabs": "2.2.2",
"react-toastify": "5.3.2",
"react-transition-group": "2.6.1",
"reactstrap": "7.1.0",
"redux": "4.0.1",
"redux-form": "7.4.2",
"react-toastify": "5.4.1",
"reactstrap": "8.1.1",
"redux": "4.0.4",
"redux-thunk": "2.3.0"
},
"scripts": {
Expand Down
14 changes: 7 additions & 7 deletions src/actions/Error/errorActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ const api = Api.getInstance();
export const handleError = (statusCode) => {
return (dispatch) => {
if (statusCode === 404) {
window.location.href = "/notRegistered";
window.location.href = '/notRegistered';
} else if (statusCode === 403) {
window.location.href = "/permissionDenied"
window.location.href = '/permissionDenied';
} else {
window.location.href = "/oops";
window.location.href = '/oops';
}
}
};
Expand All @@ -19,17 +19,17 @@ export const sendMessageToBackend = (error) => {
if (error.response && error.response.status && error.response.status >= 400) {
return (dispatch) => {
let href = window.location.href;
if (!href.includes("/oops") && !href.includes("/permissionDenied") && !href.includes("/notRegistered")) {
if (!href.includes('/oops') && !href.includes('/permissionDenied') && !href.includes('/notRegistered')) {
dispatch(handleError(error.response.status));
}
}
} else {
let errorMessage = { error: error.message , stackTrace: error.stack }
let errorMessage = { error: error.message , stackTrace: error.stack };
return (dispatch) => {
api.post('/api/v1/error', errorMessage)
.then(res=> {
.then((res) => {
dispatch(handleError(error.response.status));
});
};
}
}
};
15 changes: 7 additions & 8 deletions src/actions/Packages/packageActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ export const finishPackage = (packageId) => {
}
}

export const setShowLargeFileModal = (gdriveId) => {
export const setShowLargeFileModal = (globusURL) => {
return {
type: actionNames.SET_SHOW_LARGE_FILE_MODAL,
payload: gdriveId
payload: globusURL
}
}

Expand All @@ -108,9 +108,9 @@ export const clearShowLargeFileModal = () => {
}
}

export const processLargeFile = (gdriveId) => {
export const processLargeFile = (globusURL) => {
return (dispatch) => {
dispatch(setShowLargeFileModal(gdriveId));
dispatch(setShowLargeFileModal(globusURL));
}
}

Expand All @@ -135,18 +135,17 @@ export const uploadPackage = (packageInfo, uploader) => {
});
return (dispatch) => {
dispatch(setIsUploading(true));
api.post('/api/v1/packages', packageInfo)
api.post('/api/v1/packages', packageInfo, { params: { hostname: window.location.hostname} })
.then(res=> {
let packageId = res.data.packageId;
let gdriveId = res.data.gdriveId;
console.log(gdriveId);
let globusURL = res.data.globusURL;
let canceledFiles = uploader.methods.getUploads(
{status: [qq.status.CANCELED]});
let allFiles = uploader.methods.getUploads();
let totalFiles = allFiles.length - canceledFiles.length;
if (packageInfo.largeFilesChecked) {
dispatch(setIsUploading(false));
dispatch(processLargeFile(gdriveId));
dispatch(processLargeFile(globusURL));
} else {
uploader.on('allComplete', function (succeeded, failed) {
if (succeeded.length === totalFiles) {
Expand Down
2 changes: 1 addition & 1 deletion src/actions/Upload/uploadActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const getFormDTD = () => {
dispatch(setPackageTypesFromDTD(res.data));
dispatch(setTisNamesFromDTD(res.data));
})
.catch(err => {
.catch((err) => {
dispatch(sendMessageToBackend(err));
});
}
Expand Down
4 changes: 2 additions & 2 deletions src/actions/filterActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ export const filterTypes = {
export const addFilter = (type, value) => {
return {
type: actionNames.ADD_FILTER,
payload: { filterType: type, value: value }
payload: { filterType: type, value }
}
}

export const removeFilter = (type, value) => {
return {
type: actionNames.REMOVE_FILTER,
payload: { filterType: type, value: value }
payload: { filterType: type, value }
}
}

Expand Down
13 changes: 7 additions & 6 deletions src/actions/packageTypeIconsActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ import { sendMessageToBackend } from './Error/errorActions';

const api = Api.getInstance();

export const setPackageTypeIcons = (packageTypeIcons) => {
return {
type: actionNames.SET_PACKAGE_TYPE_ICONS,
payload: packageTypeIcons
}
}

export const getPackageTypeIcons = () => {
return (dispatch) => {
api.get('/api/v1/packageTypeIcons')
Expand All @@ -17,9 +24,3 @@ export const getPackageTypeIcons = () => {
}
}

export const setPackageTypeIcons = (packageTypeIcons) => {
return {
type: actionNames.SET_PACKAGE_TYPE_ICONS,
payload: packageTypeIcons
}
}
8 changes: 5 additions & 3 deletions src/components/Packages/LargeFileModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ class LargeFileModal extends Component {
Upload Instructions
</ModalHeader>
<ModalBody className="largeFileModalBody">
<p>This method requires you to do the following in order to upload your file(s) into the data lake:</p>
<ol>
<li>Click this link to <a rel="noopener noreferrer" href={"https://drive.google.com/drive/folders/" + this.props.link} target="_blank">open the destination folder</a> on Google Drive.</li>
<li>Upload your files to the Google Drive folder. <br/>(NOTE: You may need to sign in with a Google account)</li>
<li>Click this link to <a href={this.props.link} target="_blank" rel="noopener noreferrer">open the destination folder</a> on the Globus endpoint.</li>
<li>Upload your files using the Globus file manager. </li>
<li>Email <a target="_blank" rel="noopener noreferrer" href="mailto:datalakeuploadersupport@kpmp.org">datalakeuploadersupport@kpmp.org</a> to let us know you have finished uploading your file(s).</li>
</ol>
<hr/>
<p><strong>PLEASE NOTE:</strong> This method requires you to <a href="https://www.globus.org/globus-connect-personal" target="_blank" rel="noopener noreferrer">install Globus Connect Personal</a> in order to upload your file(s) to the data lake.</p>
<p>You will need to log in to use the Globus Web App and create a collection for your data source. For help or more information, see: <a href="https://docs.globus.org/how-to/get-started/" target="_blank" rel="noopener noreferrer"> How To Log In and Transfer Files with Globus</a></p>
</ModalBody>
<ModalFooter>
<article id="largeFileModalFooter" className="justify-content-right">
Expand Down
7 changes: 5 additions & 2 deletions src/components/Packages/PackagePanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ class PackagePanel extends Component {
<PackagePanelStateText
handleStateInfoClick={this.handleStateInfoClick}
panelState={this.props.uploadPackage.state}
currentUser={this.props.userInformation}
packageSubmitter={packageInfo.submitter}
largeFileUpload={packageInfo.largeFilesChecked}
/>
</Col>
}
Expand All @@ -120,8 +123,8 @@ class PackagePanel extends Component {
PackagePanel.propTypes = {
uploadPackage: PropTypes.object.isRequired,
packageTypeIcons: PropTypes.array.isRequired,
dtds: PropTypes.object.isRequired

dtds: PropTypes.object.isRequired,
userInformation: PropTypes.object.isRequired
}

export default PackagePanel;
1 change: 1 addition & 0 deletions src/components/Packages/PackagePanelContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const mapStateToProps = (state, props) =>
packageTypeIcons: state.packageTypeIcons,
index: props.index,
uploadPackage: props.uploadPackage,
userInformation: state.userInformation
});

const mapDispatchToProps = (dispatch, props) =>
Expand Down
65 changes: 25 additions & 40 deletions src/components/Packages/PackagePanelStateText.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,12 @@
import React, { Component } from 'react';
import { Popover, PopoverBody } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faClock } from '@fortawesome/free-solid-svg-icons';
import PropTypes from 'prop-types';
import { getIcon, getMessage, PANEL_CONFIGS } from './packagePanelStateHelper';

const POPOVER_CLASSES = {
classNames: "",
innerClassNames: "rounded p-2 small text-sm-left"
};

const PANEL_CONFIGS = {
FILES_RECEIVED: {
text: "Finishing upload",
classNames: "alert-success",
message: "The file(s) in this package are being finalized. Once completed, they will be available for download."
},

METADATA_RECEIVED: {
text: "Waiting for files...",
classNames: "alert-primary",
icon: faClock,
message: "Awaiting file(s) to be uploaded to the Google drive folder. Click the clock icon for upload instructions."
},

UPLOAD_FAILED: {
text: "Upload failed",
classNames: "alert-danger",
message: <div>
<div>The file(s) in this package could not be processed. It is recommended that you re-upload this package.</div>
<br/>
<div>For more information please contact KPMP support at <a target="_blank" rel="noopener noreferrer" href="mailto:datalakeuploadersupport@kpmp.org">datalakeuploadersupport@kpmp.org</a></div>
</div>

}
classNames: '',
innerClassNames: 'rounded p-2 small text-sm-left'
};

class PackagePanelStateText extends Component {
Expand All @@ -41,6 +15,7 @@ class PackagePanelStateText extends Component {
super(props);

this.toggle = this.toggle.bind(this);
this.configurePanelOptions = this.configurePanelOptions.bind(this);
this.state = {
popoverOpen: false
};
Expand All @@ -51,41 +26,51 @@ class PackagePanelStateText extends Component {
popoverOpen: !this.state.popoverOpen
});
}


configurePanelOptions() {
let baseConfig = PANEL_CONFIGS[this.props.panelState.state];
let panelConfig = baseConfig;
panelConfig.message = getMessage(baseConfig, this.props.panelState.state, this.props.largeFileUpload, this.props.currentUser.shibId, this.props.packageSubmitter.shibId);
if (this.props.handleStateInfoClick) {
panelConfig.icon = getIcon(this.props.panelState.state, this.props.largeFileUpload, this.props.currentUser.shibId, this.props.packageSubmitter.shibId);
}
return panelConfig;
}

render() {
let panelConfig = PANEL_CONFIGS[this.props.panelState.state];
let panelConfig = this.configurePanelOptions();

if(panelConfig === undefined) {
return null;
}

let popoverTargetId = 'popover-' + this.props.panelState.packageId;
let hasIcon = panelConfig.icon && this.props.handleStateInfoClick;

return <React.Fragment>
<div className="d-flex align-items-start">
<div className="w-75">
<div className={"mr-2 my-0 px-2 py-1 alert clickable text-dark " + panelConfig.classNames} id={popoverTargetId} >
<div className='d-flex align-items-start'>
<div className='w-75'>
<div className={'mr-2 my-0 px-2 py-1 alert clickable text-dark ' + panelConfig.classNames} id={popoverTargetId} >
<span>{panelConfig.text}</span>
</div>
{ panelConfig.message &&
<span>
<Popover className={POPOVER_CLASSES.classNames}
innerClassName={POPOVER_CLASSES.innerClassNames}
placement={"bottom"}
delay={{"hide": 300}}
placement={'bottom'}
delay={{'hide': 300}}
isOpen={this.state.popoverOpen}
toggle={this.toggle}
target={popoverTargetId}
html={true}
trigger={"hover"}>
trigger={'hover'}>
<PopoverBody>{panelConfig.message}</PopoverBody>
</Popover>
</span>
}
</div>
{ hasIcon && <span onClick={this.props.handleStateInfoClick}>
<div className="additional-icon clickable"><FontAwesomeIcon className="float-right" icon={panelConfig.icon} size="lg" inverse/></div>
{ panelConfig.icon &&
<span onClick={this.props.handleStateInfoClick}>
<div className='additional-icon clickable'><FontAwesomeIcon className='float-right' icon={panelConfig.icon} size='lg' inverse/></div>
</span>
}
</div>
Expand Down
Loading

0 comments on commit d287843

Please sign in to comment.