mirror of
https://git.rwth-aachen.de/acs/public/villas/web/
synced 2025-03-09 00:00:01 +01:00
add result file, simplify timestamp
This commit is contained in:
parent
2b5f5568c8
commit
1d97694016
4 changed files with 206 additions and 36 deletions
|
@ -16,7 +16,9 @@
|
|||
******************************************************************************/
|
||||
|
||||
import React from 'react';
|
||||
import {FormGroup, FormControl, FormLabel, Col} from 'react-bootstrap';
|
||||
import {FormGroup, FormControl, FormLabel, Col, Button, ProgressBar} from 'react-bootstrap';
|
||||
import AppDispatcher from "../common/app-dispatcher";
|
||||
|
||||
import Table from "../common/table";
|
||||
|
||||
import Dialog from '../common/dialogs/dialog';
|
||||
|
@ -29,10 +31,10 @@ class EditResultDialog extends React.Component {
|
|||
super(props);
|
||||
|
||||
this.state = {
|
||||
configSnapshots: '',
|
||||
id: 0,
|
||||
description: '',
|
||||
resultFileIDs: [],
|
||||
id:0,
|
||||
uploadFile: null,
|
||||
uploadProgress: 0,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -55,10 +57,9 @@ class EditResultDialog extends React.Component {
|
|||
|
||||
resetState = () => {
|
||||
this.setState({
|
||||
configSnapshots: this.props.configSnapshots,
|
||||
description: this.props.description,
|
||||
resultFileIDs: this.props.resultFileIDs,
|
||||
id: this.props.id,
|
||||
id: this.props.result.id,
|
||||
description: this.props.result.description,
|
||||
result: this.props.result,
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -66,28 +67,46 @@ class EditResultDialog extends React.Component {
|
|||
this.setState({ startParameters });
|
||||
};
|
||||
|
||||
// TODO: file reading necessary? or can it just be saved?
|
||||
loadFile = event => {
|
||||
// get file
|
||||
const file = event.target.files[0];
|
||||
|
||||
// create file reader
|
||||
let reader = new FileReader();
|
||||
let self = this;
|
||||
selectUploadFile(event) {
|
||||
this.setState({ uploadFile: event.target.files[0] });
|
||||
};
|
||||
|
||||
reader.onload = event => {
|
||||
const config = JSON.parse(event.target.result);
|
||||
startFileUpload(){
|
||||
// upload file
|
||||
const formData = new FormData();
|
||||
formData.append("file", this.state.uploadFile);
|
||||
//console.log("formData: ");
|
||||
//console.log(formData);
|
||||
|
||||
self.imported = true;
|
||||
self.valid = true;
|
||||
this.setState({filename: config.name, file: config });
|
||||
};
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/start-upload',
|
||||
data: formData,
|
||||
resultID: this.state.id,
|
||||
token: this.props.sessionToken,
|
||||
progressCallback: this.updateUploadProgress,
|
||||
finishedCallback: this.clearProgress,
|
||||
scenarioID: this.props.scenarioID,
|
||||
});
|
||||
|
||||
reader.readAsBinaryString(file);
|
||||
}
|
||||
this.setState({ uploadFile: null });
|
||||
};
|
||||
|
||||
clearProgress = (newFileID) => {
|
||||
this.setState({ uploadProgress: 0 });
|
||||
};
|
||||
|
||||
updateUploadProgress = (event) => {
|
||||
this.setState({ uploadProgress: parseInt(event.percent.toFixed(), 10) });
|
||||
};
|
||||
|
||||
render() {
|
||||
return <Dialog show={this.props.show} title={'Edit Result No. '+this.state.id} buttonTitle='Save' onClose={this.onClose} onReset={this.resetState} valid={true}>
|
||||
return <Dialog show={this.props.show}
|
||||
title={'Edit Result No. '+this.state.id}
|
||||
buttonTitle='Save'
|
||||
onClose={this.onClose}
|
||||
onReset={this.resetState}
|
||||
valid={true}>
|
||||
|
||||
<form>
|
||||
<FormGroup as={Col} controlId='description'>
|
||||
<FormLabel column={false}>Description</FormLabel>
|
||||
|
@ -95,12 +114,27 @@ class EditResultDialog extends React.Component {
|
|||
<FormControl.Feedback />
|
||||
</FormGroup>
|
||||
|
||||
|
||||
|
||||
<FormGroup controlId='resultfile'>
|
||||
<FormLabel>Add Result File</FormLabel>
|
||||
<FormControl type='file' onChange={this.loadFile} />
|
||||
<FormControl type='file' onChange={(event) => this.selectUploadFile(event)} />
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup as={Col} >
|
||||
<Button
|
||||
disabled={this.state.uploadFile === null}
|
||||
onClick={() => this.startFileUpload()}>
|
||||
Upload
|
||||
</Button>
|
||||
</FormGroup>
|
||||
|
||||
<FormGroup as={Col} >
|
||||
<ProgressBar
|
||||
striped={true}
|
||||
animated={true}
|
||||
now={this.state.uploadProgress}
|
||||
label={this.state.uploadProgress + '%'}
|
||||
/>
|
||||
</FormGroup>
|
||||
|
||||
</form>
|
||||
</Dialog>;
|
||||
|
|
|
@ -24,8 +24,83 @@ class ResultStore extends ArrayStore {
|
|||
super('results', ResultsDataManager);
|
||||
}
|
||||
|
||||
saveFile(state, action){
|
||||
|
||||
let fileID = parseInt(action.id)
|
||||
state.forEach((element, index, array) => {
|
||||
if (element.id === fileID) {
|
||||
// save blob object
|
||||
array[index]["data"] = new Blob([action.data.data], {type: action.data.type});
|
||||
// update file type
|
||||
array[index]["type"] = action.data.type;
|
||||
|
||||
if (array[index]["objectURL"] !== ''){
|
||||
// free memory of previously generated object URL
|
||||
URL.revokeObjectURL(array[index]["objectURL"]);
|
||||
}
|
||||
// create an object URL for the file
|
||||
array[index]["objectURL"] = URL.createObjectURL(array[index]["data"])
|
||||
}
|
||||
});
|
||||
|
||||
// announce change to listeners
|
||||
this.__emitChange();
|
||||
return state
|
||||
}
|
||||
|
||||
simplify(timestamp) {
|
||||
let parts = timestamp.split("T");
|
||||
let datestr = parts[0];
|
||||
let time = parts[1].split(".");
|
||||
|
||||
return datestr + ', ' + time[0];;
|
||||
}
|
||||
|
||||
simplifyTimestamps(data) {
|
||||
data.forEach((result) => {
|
||||
result.createdAt = this.simplify(result.createdAt);
|
||||
result.updatedAt = this.simplify(result.updatedAt);
|
||||
});
|
||||
}
|
||||
|
||||
reduce(state, action) {
|
||||
return super.reduce(state, action);
|
||||
switch (action.type) {
|
||||
case 'results/loaded':
|
||||
this.simplifyTimestamps(action.data);
|
||||
return super.reduce(state, action);
|
||||
|
||||
case 'resultfiles/start-download':
|
||||
ResultsDataManager.download(action)
|
||||
return state
|
||||
|
||||
case 'resultfiles/start-upload':
|
||||
ResultsDataManager.upload(action.data, action.resultID, action.token, action.progressCallback, action.finishedCallback, action.scenarioID);
|
||||
return state;
|
||||
|
||||
case 'resultfiles/uploaded':
|
||||
return state;
|
||||
|
||||
case 'resultfiles/upload-error':
|
||||
console.log(action.error);
|
||||
return state;
|
||||
|
||||
case 'resultfiles/downloaded':
|
||||
// in this case a file is contained in the response (no JSON)
|
||||
return this.saveFile(state, action);
|
||||
|
||||
case 'resultfiles/start-edit':
|
||||
ResultsDataManager.update(action.data, action.token, action.id);
|
||||
return state;
|
||||
|
||||
case 'resultfiles/edited':
|
||||
return this.updateElements(state, [action.data]);
|
||||
|
||||
case 'resultfiles/edit-error':
|
||||
return state;
|
||||
|
||||
default:
|
||||
return super.reduce(state, action);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,8 +15,9 @@
|
|||
* along with VILLASweb. If not, see <http://www.gnu.org/licenses/>.
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
import RestDataManager from '../common/data-managers/rest-data-manager';
|
||||
import RestAPI from '../common/api/rest-api';
|
||||
import AppDispatcher from '../common/app-dispatcher';
|
||||
|
||||
class ResultsDataManager extends RestDataManager{
|
||||
|
||||
|
@ -24,6 +25,65 @@ class ResultsDataManager extends RestDataManager{
|
|||
super('result', '/results');
|
||||
}
|
||||
|
||||
upload(file, resultID, token = null, progressCallback = null, finishedCallback = null, scenarioID) {
|
||||
RestAPI.upload(this.makeURL(this.url + '/' + resultID + '/file') , file, token, progressCallback, scenarioID).then(response => {
|
||||
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/uploaded',
|
||||
});
|
||||
|
||||
// Trigger a files reload
|
||||
AppDispatcher.dispatch({
|
||||
type: 'results/start-load',
|
||||
param: '?scenarioID=' + scenarioID,
|
||||
token: token
|
||||
});
|
||||
|
||||
if (finishedCallback) {
|
||||
finishedCallback(response.result.id);
|
||||
}
|
||||
}).catch(error => {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/upload-error',
|
||||
error
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
download(action){
|
||||
RestAPI.download(this.makeURL(this.url), action.token, action.data).then(response => {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/downloaded',
|
||||
data: response,
|
||||
id: action.data,
|
||||
token: action.token
|
||||
});
|
||||
|
||||
}).catch(error => {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/load-error',
|
||||
error: error
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* only update file ids
|
||||
update(file, token, id) {
|
||||
|
||||
RestAPI.put(this.makeURL(this.url + '/' + id), file, token).then(response => {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/edited',
|
||||
data: response[this.type]
|
||||
});
|
||||
}).catch(error => {
|
||||
AppDispatcher.dispatch({
|
||||
type: 'resultfiles/edit-error',
|
||||
error: error
|
||||
});
|
||||
});
|
||||
}
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
export default new ResultsDataManager()
|
||||
export default new ResultsDataManager();
|
|
@ -572,8 +572,6 @@ class Scenario extends React.Component {
|
|||
############################################## */
|
||||
|
||||
closeNewResultModal(data) {
|
||||
console.log(this.state.results);
|
||||
console.log(data);
|
||||
this.setState({ newResultModal: false });
|
||||
if (data) {
|
||||
data["scenarioID"] = this.state.scenario.id;
|
||||
|
@ -691,17 +689,20 @@ class Scenario extends React.Component {
|
|||
title='Options'
|
||||
width='300'
|
||||
editButton
|
||||
addRemoveFilesButton
|
||||
downloadAllButton
|
||||
deleteButton
|
||||
onEdit={index => this.setState({ editResultsModal: true, modalResultsData: this.state.results[index], modalResultsIndex: index })}
|
||||
onAddRemove={(index) => this.setState({ editFilesModal: true, modalResultsData: this.state.results[index], modalResultsIndex: index})}
|
||||
onDownloadAll={(index) => this.downloadData(this.state.results[index])}
|
||||
onDelete={(index) => this.setState({ deleteResultsModal: true, modalResultsData: this.state.results[index], modalResultsIndex: index })}
|
||||
/>
|
||||
</Table>
|
||||
|
||||
<EditResultDialog show={this.state.editResultsModal} result={this.state.modalResultsData} onClose={data => this.closeEditResultsModal(data)} />
|
||||
<EditResultDialog
|
||||
sessionToken={this.state.sessionToken}
|
||||
show={this.state.editResultsModal}
|
||||
result={this.state.modalResultsData}
|
||||
scenarioID={this.state.scenario.id}
|
||||
onClose={data => this.closeEditResultsModal(data)} />
|
||||
<DeleteDialog title="result" name={this.state.modalResultsData.id} show={this.state.deleteResultsModal} onClose={(e) => this.closeDeleteResultsModal(e)} />
|
||||
</div>
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue