Skip to content

Commit

Permalink
[Instrument manager] Reactify Menu Filters (#4142)
Browse files Browse the repository at this point in the history
Update the instrument manager to use the React menu filter template.
  • Loading branch information
xlecours authored and driusan committed Nov 23, 2018
1 parent a5083bf commit dcb1e1b
Show file tree
Hide file tree
Showing 7 changed files with 8,532 additions and 338 deletions.
173 changes: 173 additions & 0 deletions modules/instrument_manager/jsx/instrumentManagerIndex.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';

import {Tabs, TabPane} from 'Tabs';
import Loader from 'Loader';
import FilterableDataTable from 'FilterableDataTable';

import InstrumentUploadForm from './uploadForm';

class InstrumentManagerIndex extends Component {
constructor(props) {
super(props);

this.state = {
data: {},
error: false,
isLoaded: false,
};

this.fetchData = this.fetchData.bind(this);
this.formatColumn = this.formatColumn.bind(this);
}

componentDidMount() {
this.fetchData()
.then(() => this.setState({isLoaded: true}));
}

/**
* Retrieve data from the provided URL and save it in state
* Additionally add hiddenHeaders to global loris variable
* for easy access by columnFormatter.
*
* @return {object}
*/
fetchData() {
return fetch(this.props.dataURL, {credentials: 'same-origin'})
.then((resp) => resp.json())
.then((data) => this.setState({data}))
.catch((error) => {
this.setState({error: true});
console.error(error);
});
}

/**
* Modify behaviour of specified column cells in the Data Table component
*
* @param {string} column - column name
* @param {string} cell - cell content
* @param {object} row - row content indexed by column
*
* @return {*} a formated table cell for a given column
*/
formatColumn(column, cell, row) {
return (
<td>{cell}</td>
);
}

render() {
// If error occurs, return a message.
// XXX: Replace this with a UI component for 500 errors.
if (this.state.error) {
return <h3>An error occured while loading the page.</h3>;
}

// Waiting for async data to load
if (!this.state.isLoaded) {
return <Loader/>;
}

const fields = [
{label: 'Instrument', show: true, filter: {
name: 'instrument',
type: 'text',
}},
{label: 'Instrument Type', show: true, filter: {
name: 'instrumentType',
type: 'select',
options: {
'Instrument Builder': 'Instrument Builder',
'PHP': 'PHP',
'Missing': 'Missing',
},
}},
{label: 'Table Installed', show: true, filter: {
name: 'tableInstalled',
type: 'select',
options: {
'Exists': 'Exists',
'Missing': 'Missing',
},
}},
{label: 'Table Valid', show: true, filter: {
name: 'tableValid',
type: 'text',
}},
{label: 'Pages Valid', show: true, filter: {
name: 'pagesValid',
type: 'text',
}},
];

const tabs = [
{id: 'browse', label: 'Browse'},
{id: 'upload', label: 'Upload'},
];

const feedback = () => {
if (!this.state.data.caninstall) {
return (
<div className='alert alert-warning'>
Instrument installation is not possible given the current server
configuration; the LORIS 'quatUser' is not configured properly.
File upload is still possible but instruments will need to be
installed manually
</div>
);
}
};

const uploadTab = () => {
let content = null;
if (this.state.data.writable) {
let url = loris.BaseURL.concat('/instrument_manager/?format=json');
content = (
<InstrumentUploadForm action={url}/>
);
} else {
content = (
<div className='alert alert-warning'>
Installation is not possible given the current server configuration.
Please contact your administrator if you require this functionality
</div>
);
}
return content;
};

return (
<Tabs tabs={tabs} defaultTab="browse" updateURL={true}>
<TabPane TabId={tabs[0].id}>
<FilterableDataTable
name="instrument_manager"
data={this.state.data.Data}
fields={fields}
getFormattedCell={this.formatColumn}
/>
</TabPane>
<TabPane TabId='upload'>
{feedback()}
{uploadTab()}
</TabPane>
</Tabs>
);
}
}

InstrumentManagerIndex.propTypes = {
dataURL: PropTypes.string.isRequired,
hasPermission: PropTypes.func.isRequired,
};

window.addEventListener('load', () => {
ReactDOM.render(
<InstrumentManagerIndex
dataURL={`${loris.BaseURL}/instrument_manager/?format=json`}
hasPermission={loris.userHasPermission}
/>,
document.getElementById('lorisworkspace')
);
});
97 changes: 97 additions & 0 deletions modules/instrument_manager/jsx/uploadForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import React, {Component} from 'react';
import PropTypes from 'prop-types';

class InstrumentUploadForm extends Component {
constructor(props) {
super(props);

this.state = {
data: {},
selectedFile: null,
};

this.fileSelected = this.fileSelected.bind(this);
this.upload = this.upload.bind(this);
}

fileSelected(element, file) {
this.setState({
selectedFile: file,
});
}

upload() {
const data = new FormData();
data.append('install_file', this.state.selectedFile);

fetch(this.props.action, {
method: 'POST',
credentials: 'same-origin',
body: data,
})
.then((resp) => {
if (resp.status == 201) {
swal({
title: 'Installation Successful!',
type: 'success',
}, function() {
window.location.assign(loris.BaseURL + '/instrument_manager/');
});
}
return resp.json();
})
.then((data) => {
if (data.message) {
swal({
title: 'Upload Successful!',
type: 'success',
text: data.message,
}, function() {
window.location.assign(loris.BaseURL + '/instrument_manager/');
});
}
if (data.error) {
swal({
title: 'An error occured',
type: 'error',
text: data.error,
});
}
})
.catch((error) => {
this.setState({error: true});
console.error(error);
});
}

render() {
const disabled = () => this.state.selectedFile === 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">
<FileElement
name='install_file'
label='Instrument file'
onUserInput={this.fileSelected}
value={this.state.selectedFile}
/>
<button className="btn btn-default" onClick={this.upload} disabled={disabled()}>Install</button>
</div>
</div>
</div>
</div>
</div>
);
}
}

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

export default InstrumentUploadForm;
Loading

0 comments on commit dcb1e1b

Please sign in to comment.