1
0
Fork 0
mirror of https://git.rwth-aachen.de/acs/public/villas/web/ synced 2025-03-09 00:00:01 +01:00

Change of file API; files belong to scenario now (not to widget or component config); preparations for # 219

This commit is contained in:
Sonja Happ 2020-05-27 10:45:57 +02:00
parent 02c24bfecd
commit 908730b072
16 changed files with 43 additions and 93 deletions

View file

@ -5,7 +5,7 @@ import createControls from '../../widget/edit-widget/edit-widget-control-creator
import EditWidgetTextControl from '../../widget/edit-widget/edit-widget-text-control';
import EditWidgetColorControl from '../../widget/edit-widget/edit-widget-color-control';
import EditWidgetTimeControl from '../../widget/edit-widget/edit-widget-time-control';
import EditImageWidgetControl from '../../widget/edit-widget/edit-widget-image-control';
import EditFileWidgetControl from '../../widget/edit-widget/edit-widget-file-control';
import EditWidgetSignalControl from '../../widget/edit-widget/edit-widget-signal-control';
import EditWidgetSignalsControl from '../../widget/edit-widget/edit-widget-signals-control';
import EditWidgetOrientation from '../../widget/edit-widget/edit-widget-orientation';
@ -28,7 +28,7 @@ describe('edit widget control creator', () => {
{ args: { widgetType: 'Value' }, result: { controlNumber: 5, controlTypes: [EditWidgetTextControl, EditWidgetSignalControl, EditWidgetTextSizeControl, EditWidgetCheckboxControl] } },
{ args: { widgetType: 'Plot' }, result: { controlNumber: 5, controlTypes: [EditWidgetTimeControl, EditWidgetSignalsControl, EditWidgetTextControl, EditWidgetMinMaxControl] } },
{ args: { widgetType: 'Table' }, result: { controlNumber: 2, controlTypes: [EditWidgetCheckboxControl] } },
{ args: { widgetType: 'Image' }, result: { controlNumber: 2, controlTypes: [EditImageWidgetControl, EditWidgetAspectControl] } },
{ args: { widgetType: 'Image' }, result: { controlNumber: 2, controlTypes: [EditFileWidgetControl, EditWidgetAspectControl] } },
{ args: { widgetType: 'Gauge' }, result: { controlNumber: 6, controlTypes: [EditWidgetTextControl, EditWidgetSignalControl, EditWidgetCheckboxControl, EditWidgetColorZonesControl, EditWidgetMinMaxControl] } },
{ args: { widgetType: 'PlotTable' }, result: { controlNumber: 5, controlTypes: [EditWidgetSignalsControl, EditWidgetTextControl, EditWidgetTimeControl, EditWidgetMinMaxControl] } },
{ args: { widgetType: 'Slider' }, result: { controlNumber: 9, controlTypes: [EditWidgetTextControl, EditWidgetOrientation, EditWidgetSignalControl, EditWidgetCheckboxControl, EditWidgetCheckboxControl, EditWidgetMinMaxControl, EditWidgetNumberControl, EditWidgetNumberControl] } },

View file

@ -123,9 +123,9 @@ class RestAPI {
});
}
upload(url, data, token, progressCallback, objectType, objectID) {
upload(url, data, token, progressCallback, scenarioID) {
return new Promise(function (resolve, reject) {
const req = request.post(url + "?objectType=" + objectType + "&objectID=" + objectID).send(data); //.on('progress', progressCallback);
const req = request.post(url + "?scenarioID=" + scenarioID).send(data); //.on('progress', progressCallback);
if (token != null) {
req.set('Authorization', "Bearer " + token);

View file

@ -68,7 +68,7 @@ class ConfigDataManager extends RestDataManager {
loadFiles(token, configs){
for (let config of configs) {
// request files of config
RestAPI.get(this.makeURL('/files?objectType=config&objectID=' + config.id), token).then(response => {
RestAPI.get(this.makeURL('/files?scenarioID' + config.scenarioID), token).then(response => {
AppDispatcher.dispatch({
type: 'files/loaded',
data: response.files

View file

@ -121,7 +121,7 @@ class EditConfigDialog extends React.Component {
</FormControl>
</FormGroup>
<SelectFile type='config' name='Configuration File' onChange={(e) => this.handleSelectedFileChange(e)} value={this.state.selectedFileID} objectID={this.props.config.id}/>
<SelectFile type='config' name='Configuration File' onChange={(e) => this.handleSelectedFileChange(e)} value={this.state.selectedFileID} scenarioID={this.props.config.scenarioID}/>
<FormGroup controlId='startParameters'>
<FormLabel> Start Parameters </FormLabel>

View file

@ -75,8 +75,10 @@ class Dashboard extends Component {
// filter component configurations to the ones that belong to this scenario
let configs = []
let files = []
if (dashboard !== null) {
configs = ConfigStore.getState().filter(config => config.scenarioID === dashboard.scenarioID);
files = FileStore.getState().filter(file => file.scenarioID === dashboard.scenarioID);
}
// filter signals to the ones belonging to the scenario at hand
@ -91,18 +93,6 @@ class Dashboard extends Component {
}
}
// filter files to the ones associated with a widget of this dashboard
let allFiles = FileStore.getState();
let files = [];
let file, widget;
for (file of allFiles){
for (widget of widgets){
if (file.widgetID === widget.id){
files.push(file);
}
}
}
// filter ICs to the ones used by this scenario
let ics = []
if (configs.length > 0){
@ -277,8 +267,7 @@ class Dashboard extends Component {
type: 'files/start-upload',
data: data,
token: this.state.sessionToken,
objectType: "widget",
objectID: widget.id,
scenarioID: this.state.dashboard.scenarioID,
});
}

View file

@ -54,7 +54,7 @@ class FileStore extends ArrayStore {
return state
case 'files/start-upload':
FilesDataManager.upload(action.data, action.token, action.progressCallback, action.finishedCallback, action.objectType, action.objectID);
FilesDataManager.upload(action.data, action.token, action.progressCallback, action.finishedCallback, action.scenarioID);
return state;
case 'files/uploaded':

View file

@ -24,8 +24,8 @@ class FilesDataManager extends RestDataManager {
super('file', '/files');
}
upload(file, token = null, progressCallback = null, finishedCallback = null, objectType, objectID) {
RestAPI.upload(this.makeURL(this.url), file, token, progressCallback, objectType, objectID).then(response => {
upload(file, token = null, progressCallback = null, finishedCallback = null, scenarioID) {
RestAPI.upload(this.makeURL(this.url), file, token, progressCallback, scenarioID).then(response => {
AppDispatcher.dispatch({
type: 'files/uploaded',
@ -34,7 +34,7 @@ class FilesDataManager extends RestDataManager {
// Trigger a files reload
AppDispatcher.dispatch({
type: 'files/start-load',
param: '?objectType=' + objectType + '&objectID=' + objectID,
param: '?scenarioID=' + scenarioID,
token: token
});

View file

@ -34,11 +34,9 @@ class SelectFile extends React.Component {
static calculateState(prevState, props) {
let files = FileStore.getState().filter((file) => {
return (file.configID === props.objectID)
return (file.scenarioID === props.scenarioID)
});
console.log("props.objectID=", props.objectID)
return {
files: files,
sessionToken: LoginStore.getState().token,
@ -83,8 +81,7 @@ class SelectFile extends React.Component {
token: this.state.sessionToken,
//progressCallback: this.updateUploadProgress,
//finishedCallback: this.clearProgress,
objectType: this.props.type,
objectID: this.props.objectID,
scenarioID: this.props.scenarioID,
});
};

Binary file not shown.

Before

Width:  |  Height:  |  Size: 193 KiB

After

Width:  |  Height:  |  Size: 192 KiB

View file

@ -65,8 +65,11 @@ class Scenario extends React.Component {
// obtain all component configurations of a scenario
let configs = ConfigStore.getState().filter(config => config.scenarioID === parseInt(props.match.params.scenario, 10));
// obtain all files of a scenario
let files = FileStore.getState().filter(file => file.scenarioID === parseInt(props.match.params.scenario, 10));
let signals = SignalStore.getState();
let files = FileStore.getState();
return {
@ -118,6 +121,13 @@ class Scenario extends React.Component {
param: '?scenarioID='+this.state.scenario.id,
});
// load files of selected scenario
AppDispatcher.dispatch({
type: 'files/start-load',
token: this.state.sessionToken,
param: '?scenarioID='+this.state.scenario.id,
});
// load ICs to enable that component configs and dashboards work with them
AppDispatcher.dispatch({
type: 'ics/start-load',

View file

@ -21,7 +21,7 @@ import EditWidgetTextControl from './edit-widget-text-control';
import EditWidgetNumberControl from './edit-widget-number-control';
import EditWidgetColorControl from './edit-widget-color-control';
import EditWidgetTimeControl from './edit-widget-time-control';
import EditImageWidgetControl from './edit-widget-image-control';
import EditFileWidgetControl from './edit-widget-file-control';
import EditWidgetSignalControl from './edit-widget-signal-control';
import EditWidgetSignalsControl from './edit-widget-signals-control';
import EditWidgetOrientation from './edit-widget-orientation';
@ -84,7 +84,7 @@ export default function CreateControls(widgetType = null, widget = null, session
// Restrict to only image file types (MIME)
//let imageControlFiles = files == null? [] : files.filter(file => file.type.includes('image'));
DialogControls.push(
<EditImageWidgetControl key={0} widget={widget} controlId={"customProperties.file"} sessionToken={sessionToken} files={files} handleChange={(e) => handleChange(e)} onUpload={(f,i) => onUpload(f,i)} />,
<EditFileWidgetControl key={0} widget={widget} controlId={"customProperties.file"} files={files} type={'image'} handleChange={(e) => handleChange(e)} onUpload={(f,i) => onUpload(f,i)} />,
<EditWidgetAspectControl key={1} widget={widget} controlId={"customProperties.lockAspect"} handleChange={e => handleChange(e)} />
);
break;
@ -149,7 +149,7 @@ export default function CreateControls(widgetType = null, widget = null, session
// Restrict to only xml files (MIME)
//let topologyControlFiles = files == null? [] : files.filter( file => file.type.includes('xml'));
DialogControls.push(
<EditImageWidgetControl key={0} widget={widget} controlId={"customProperties.file"} sessionToken={sessionToken} files={files} handleChange={(e) => handleChange(e)} />
<EditFileWidgetControl key={0} widget={widget} controlId={"customProperties.file"} files={files} type={'xml'} handleChange={(e) => handleChange(e) } onUpload={(f,i) => onUpload(f,i)} />
);
break;

View file

@ -18,15 +18,14 @@
import React from 'react';
import {FormGroup, FormControl, FormLabel, Button, ProgressBar} from 'react-bootstrap';
//import AppDispatcher from '../../common/app-dispatcher';
class EditImageWidgetControl extends React.Component {
class EditFileWidgetControl extends React.Component {
constructor(props) {
super(props);
this.state = {
widget: { },
files: [],
fileList: null,
progress: 0
};
@ -34,7 +33,8 @@ class EditImageWidgetControl extends React.Component {
static getDerivedStateFromProps(props, state){
return {
widget: props.widget
widget: props.widget,
files: props.files.filter(file => file.type.includes(props.type))
};
}
@ -47,19 +47,8 @@ class EditImageWidgetControl extends React.Component {
formData.append("file", this.state.fileList[key]);
}
}
this.props.onUpload(formData,this.props.widget);
// upload files
/* AppDispatcher.dispatch({
type: 'files/start-upload',
data: formData,
token: this.props.sessionToken,
progressCallback: this.uploadProgress,
finishedCallback: this.clearProgress,
objectType: "widget",
objectID: this.props.widget.id,
});*/
this.props.onUpload(formData,this.props.widget);
}
uploadProgress = (e) => {
@ -83,11 +72,11 @@ class EditImageWidgetControl extends React.Component {
}
let fileOptions = [];
if (this.props.files.length > 0){
if (this.state.files.length > 0){
fileOptions.push(
<option key = {0} default>Select image file</option>
)
fileOptions.push(this.props.files.map((file, index) => (
fileOptions.push(this.state.files.map((file, index) => (
<option key={index+1} value={file.id}>{file.name}</option>
)))
} else {
@ -114,4 +103,4 @@ class EditImageWidgetControl extends React.Component {
}
}
export default EditImageWidgetControl;
export default EditFileWidgetControl;

View file

@ -16,10 +16,7 @@
******************************************************************************/
import React from 'react';
//import { FormGroup, FormControl, FormLabel } from 'react-bootstrap';
import Dialog from '../../common/dialogs/dialog';
import CreateControls from './edit-widget-control-creator';
class EditWidgetDialog extends React.Component {
@ -110,11 +107,11 @@ class EditWidgetDialog extends React.Component {
// not a customProperty
customProperty = false;
}
if (parts[1] === 'lockAspect') {
//not a customProperty
customProperty ? changeObject[parts[0]][parts[1]] = e.target.checked : changeObject[e.target.id] = e.target.checked;
// correct image aspect if turned on
if (e.target.checked && (this.state.temporal.customProperties.file !== -1)) {
changeObject = this.assignAspectRatio(changeObject, this.state.temporal.customProperties.file);
@ -123,7 +120,7 @@ class EditWidgetDialog extends React.Component {
customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value;
// get file and update size (if it's an image)
// get file and update size (if it's an image)
if ((changeObject.customProperties.file !== -1)&&('lockAspect' in this.state.temporal && this.state.temporal.lockAspect)) {
// TODO this if condition requires changes to work!!!
changeObject = this.assignAspectRatio(changeObject, e.target.value);
@ -135,7 +132,7 @@ class EditWidgetDialog extends React.Component {
}else if(parts[1] === 'orientation'){
customProperty ? changeObject[parts[0]][parts[1]] = e.target.value : changeObject[e.target.id] = e.target.value ;
changeObject = this.setNewLockRestrictions(changeObject);
}
}
else if (e.target.type === 'number') {
customProperty ? changeObject[parts[0]][parts[1]] = Number(e.target.value) : changeObject[e.target.id] = Number(e.target.value);
} else if(e.target.id === 'name'){

View file

@ -29,7 +29,8 @@ class WidgetStore extends ArrayStore {
case 'widgets/loaded':
WidgetsDataManager.loadFiles(action.token, action.data);
//WidgetsDataManager.loadFiles(action.token, action.data);
// TODO make sure files of scenario are loaded
return super.reduce(state, action);
default:

View file

@ -88,27 +88,6 @@ class Widget extends React.Component {
};
}
componentDidMount() {
if (this.state.sessionToken == null) {
return;
}
/*AppDispatcher.dispatch({
type: 'files/start-load',
token: this.state.sessionToken,
param: '?objectID=1&objectType=widget'
});*/
// TODO no not load component congfigs here, since they are loaded via the scenario, pass them as props
/*
AppDispatcher.dispatch({
type: 'configs/start-load',
token: this.state.sessionToken,
param: '?scenarioID=1' // TODO do not hardcode scenarioID!
});
*/
}
inputDataChanged(widget, data) {
// The following assumes that a widget modifies/ uses exactly one signal
AppDispatcher.dispatch({

View file

@ -26,18 +26,6 @@ class WidgetsDataManager extends RestDataManager{
super('widget', '/widgets');
}
loadFiles(token, widgets){
for (let widget of widgets) {
// request files of widget
RestAPI.get(this.makeURL('/files?objectType=widget&objectID=' + widget.id), token).then(response => {
AppDispatcher.dispatch({
type: 'files/loaded',
data: response.files
});
});
}
}
}
export default new WidgetsDataManager()