Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[instrument_manager] Parse Instrument Data from CSV file #9472

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion modules/instrument_manager/jsx/instrumentManagerIndex.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ class InstrumentManagerIndex extends Component {
} else if (this.state.data.fieldOptions.writable) {
let url = loris.BaseURL.concat('/instrument_manager/');
content = (
<InstrumentUploadForm action={url}/>
<InstrumentUploadForm action={url} data={this.state.data} />
);
} else {
content = (
Expand Down
211 changes: 184 additions & 27 deletions modules/instrument_manager/jsx/uploadForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {Component} from 'react';
import PropTypes from 'prop-types';
import swal from 'sweetalert2';
import {FileElement} from 'jsx/Form';
import {SelectElement} from '../../../jsx/Form';

/**
* Instrument Upload Form component
Expand All @@ -15,32 +16,49 @@ class InstrumentUploadForm extends Component {
super(props);

this.state = {
data: {},
selectedFile: null,
selectedInstrumentFile: null,
selectedDataFile: null,
selectedInstrument: '',
};

this.fileSelected = this.fileSelected.bind(this);
this.upload = this.upload.bind(this);
this.instrumentFileSelected = this.instrumentFileSelected.bind(this);
this.uploadInstrument = this.uploadInstrument.bind(this);
this.getInstrumentOptions = this.getInstrumentOptions.bind(this);
this.dataFileSelected = this.dataFileSelected.bind(this);
this.uploadInstrumentData = this.uploadInstrumentData.bind(this);
}

/**
* Update selectedFile on file selection
* Update selectedInstrumentFile on instrument file selection
*
* @param {string} element - Element name
* @param {string} file
*/
fileSelected(element, file) {
instrumentFileSelected(element, file) {
this.setState({
selectedFile: file,
selectedInstrumentFile: file,
});
}

/**
* Update selectedDataFile on data file selection
*
* @param {string} element - Element name
* @param {string} file
*/
dataFileSelected(element, file) {
this.setState({
selectedDataFile: file,
});
}

/**
* Upload instrument
*/
upload() {
uploadInstrument() {
const data = new FormData();
data.append('install_file', this.state.selectedFile);
data.append('upload_type', 'instrument');
data.append('install_file', this.state.selectedInstrumentFile);

fetch(this.props.action, {
method: 'POST',
Expand Down Expand Up @@ -81,45 +99,184 @@ class InstrumentUploadForm extends Component {
});
}


/**
* Upload instrument data
*/
uploadInstrumentData() {
const data = new FormData();
data.append('upload_type', 'data');
data.append('instrument', this.state.selectedInstrument);
data.append('data_file', this.state.selectedDataFile);

fetch(this.props.action, {
method: 'POST',
credentials: 'same-origin',
body: data,
})
.then((resp) => {
return resp.json();
})
.then((data) => {
console.log('data', data);
if (data.success) {
swal.fire({
title: 'Upload Successful!',
type: 'success',
text: data.message,
}).then(() => {
this.setState({
selectedDataFile: null,
});
});
} else {
let message = '<div>';
message += `<br/># Errors: ${data.message.length}<br/><br/>`;
data.message.forEach((error) => {
message += (error + '<br/>');
});
message += '</div>';

swal.fire({
title: 'No data uploaded',
type: 'warning',
html: message,
});
}
})
.catch((error) => {
this.setState({error: true});
});
}

getInstrumentOptions() {
const instruments = {};
if (this.props.data) {
this.props.data.Data.map((instrument) => {
const instrumentName = instrument[0];
instruments[instrumentName] = instrumentName;
});
}
return instruments;
}


/**
* Renders the React component.
*
* @return {JSX} - React markup for the component
* @return {JSX.Element} - React markup for the component
*/
render() {
const disabled = () => this.state.selectedFile === null;
const uploadInstrumentDisabled
= () => this.state.selectedInstrumentFile === null;
const instrumentSelected = this.state.selectedInstrument !== '';
const uploadDataDisabled
= () => !instrumentSelected || this.state.selectedDataFile === null;

return (
<div className="row">
<div className="col-xs-4">
<div className="panel panel-primary">
<div className="panel-heading">Upload Instrument</div>
<div className="panel-body">
<div className="col-xs-12">
<>
<div className="row">
<div className="col-xs-4">
<UploadPanel
title={'Upload Instrument'}
>
<FileElement
name='install_file'
label='Instrument file'
onUserInput={this.instrumentFileSelected}
value={this.state.selectedInstrumentFile}
/>
<button
className="btn btn-default"
onClick={this.uploadInstrument}
disabled={uploadInstrumentDisabled()}
>
Install
</button>
</UploadPanel>
</div>
<div className="col-xs-4">
<UploadPanel
title={'Upload Instrument Data'}
>
<div className="row">
<SelectElement
name={'select_instrument'}
options={this.getInstrumentOptions()}
label={'Select Instrument'}
value={this.state.selectedInstrument}
onUserInput={(e, value) => this.setState({
...this.state,
selectedInstrument: value,
})}
emptyOption={true}
sortByValue={true}
/>
</div>
<div className="row">
<FileElement
name='install_file'
label='Instrument file'
onUserInput={this.fileSelected}
value={this.state.selectedFile}
name='install_data_file'
label='Instrument Data File'
onUserInput={this.dataFileSelected}
value={this.state.selectedDataFile}
/>
</div>
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<button
className="btn btn-default"
onClick={this.upload}
disabled={disabled()}
onClick={this.uploadInstrumentData}
disabled={uploadDataDisabled()}
>
Install
Upload Data
</button>
<a
className="btn btn-default"
disabled={!instrumentSelected}
href={
`${this.props.action}?instrument` +
`=${this.state.selectedInstrument}`
}
>
Download Expected Template
</a>
</div>
</div>
</UploadPanel>
</div>
</div>
</div>
</>
);
}
}

InstrumentUploadForm.propTypes = {
action: PropTypes.string.isRequired,
data: PropTypes.object.isRequired,
};

export default InstrumentUploadForm;

/**
* Panel containing upload form
*
* @param {object} props - react props
* @return {JSX.Element}
*/
function UploadPanel(props) {
const children = React.Children.toArray(props.children);
return <div className="panel panel-primary">
<div className="panel-heading">
{props.title}
</div>
<div className="panel-body">
<div className="col-xs-12">
{children}
</div>
</div>
</div>;
}

UploadPanel.propTypes = {
children: PropTypes.array,
title: PropTypes.string,
};


Loading
Loading