Commit 7fc0ed2d authored by Sonja Happ's avatar Sonja Happ
Browse files

Merge branch 'add-scenario-frame' into example-dashboard

# Conflicts:
#	src/dashboard/dashboard.js
parents a7fa55f3 04265d31
......@@ -51,7 +51,6 @@ import Scenario from './scenario/scenario';
import SimulationModel from './simulationmodel/simulation-model';
import Users from './user/users';
import User from './user/user';
import ExDashboard from './dashboard/exdashboard';
import './styles/app.css';
......@@ -146,7 +145,6 @@ class App extends React.Component {
<div className={`app-content app-content-margin-left`}>
<Route exact path="/" component={Home} />
<Route path="/home" component={Home} />
<Route path="/exdashboard/:dashboard" component={Dashboard} />
<Route path="/dashboards/:dashboard" component={Dashboard} />
<Route exact path="/scenarios" component={Scenarios} />
<Route path="/scenarios/:scenario" component={Scenario} />
......@@ -154,7 +152,6 @@ class App extends React.Component {
<Route path="/simulators" component={Simulators} />
<Route path="/user" component={User} />
<Route path="/users" component={Users} />
<Route path="/exdashboard" component={ExDashboard} />
</div>
</div>
......
......@@ -37,7 +37,7 @@ const REQUEST_TIMEOUT_NOTIFICATION = {
level: 'error'
};
// Check if the error was due to network failure, timeouts, etc.
// Check if the error was due to network failure, timeouts, etc.
// Can be used for the rest of requests
function isNetworkError(err) {
let result = false;
......@@ -45,7 +45,7 @@ function isNetworkError(err) {
// If not status nor response fields, it is a network error. TODO: Handle timeouts
if (err.status == null || err.response == null) {
result = true;
let notification = err.timeout? REQUEST_TIMEOUT_NOTIFICATION : SERVER_NOT_REACHABLE_NOTIFICATION;
NotificationsDataManager.addNotification(notification);
}
......@@ -54,7 +54,6 @@ function isNetworkError(err) {
class RestAPI {
get(url, token) {
console.log(url);
return new Promise(function (resolve, reject) {
var req = request.get(url);
......@@ -74,14 +73,13 @@ class RestAPI {
}
post(url, body, token) {
console.log(url);
return new Promise(function (resolve, reject) {
var req = request.post(url).send(body).timeout({ response: 5000 }); // Simple response start timeout (3s)
if (token != null) {
req.set('Authorization', "Bearer " + token);
}
req.end(function (error, res) {
if (res == null || res.status !== 200) {
......
......@@ -79,30 +79,30 @@ class ArrayStore extends ReduceStore {
case this.type + '/loaded':
if (Array.isArray(action.data)) {
console.log(" loaded Array: ");
console.log(action.data);
console.log(state);
console.log("####### loaded array of type " + this.type);
//console.log(action.data);
//console.log(state);
return this.updateElements(state, action.data);
} else {
console.log("loaded single object: ");
console.log([action.data]);
console.log(state);
console.log("####### loaded single object of type " + this.type);
//console.log([action.data]);
//console.log(state);
return this.updateElements(state, [action.data]);
}
case this.type + '/load-error':
if (action.error && !action.error.handled && action.error.response) {
const USER_LOAD_ERROR_NOTIFICATION = {
title: 'Failed to load',
message: action.error.response.body.message,
level: 'error'
};
NotificationsDataManager.addNotification(USER_LOAD_ERROR_NOTIFICATION);
}
return super.reduce(state, action);
case this.type + '/start-add':
this.dataManager.add(action.data, action.token,action.param);
return state;
......@@ -111,7 +111,7 @@ class ArrayStore extends ReduceStore {
return this.updateElements(state, [action.data]);
case this.type + '/add-error':
return state;
......@@ -133,10 +133,10 @@ class ArrayStore extends ReduceStore {
level: 'error'
};
NotificationsDataManager.addNotification(USER_REMOVE_ERROR_NOTIFICATION);
}
return super.reduce(state, action);
case this.type + '/start-edit':
this.dataManager.update(action.data, action.token,action.param);
return state;
......
......@@ -57,7 +57,6 @@ class RestDataManager {
case 'load/add':
if (param === null){
if(id != null){
console.log("id != 0");
return this.makeURL(this.url + '/' + id);
}
else {
......@@ -66,10 +65,10 @@ class RestDataManager {
}
else{
if(id != null){
return this.makeURL(this.url + '/' + id + '?' + param);
return this.makeURL(this.url + '/' + id + param);
}
else {
return this.makeURL(this.url + '?' + param)
return this.makeURL(this.url + param)
}
}
case 'remove/update':
......@@ -77,7 +76,7 @@ class RestDataManager {
return this.makeURL(this.url + '/' + object.id);
}
else{
return this.makeURL(this.url + '/' + object.id + '?' + param);
return this.makeURL(this.url + '/' + object.id + param);
}
default:
console.log("something went wrong");
......@@ -87,11 +86,10 @@ class RestDataManager {
load(id, token = null,param = null) {
if (id != null) {
console.log("rdm load was called");
// load single object
RestAPI.get(this.requestURL('load/add',id,param), token).then(response => {
const data = this.filterKeys(response[this.type]);
AppDispatcher.dispatch({
type: this.type + 's/loaded',
data: data
......@@ -129,7 +127,7 @@ class RestDataManager {
});
}
}
add(object, token = null, param = null) {
var obj = {};
......@@ -162,7 +160,7 @@ class RestDataManager {
});
});
}
update(object, token = null, param = null) {
var obj = {};
obj[this.type] = this.filterKeys(object);
......@@ -179,8 +177,8 @@ class RestDataManager {
});
});
}
};
......
......@@ -35,7 +35,6 @@ class SidebarMenu extends React.Component {
<li><NavLink to="/home" activeClassName="active" title="Home">Home</NavLink></li>
<li><NavLink to="/scenarios" activeClassName="active" title="Scenarios">Scenarios</NavLink></li>
<li><NavLink to="/simulators" activeClassName="active" title="Simulators">Simulators</NavLink></li>
<li><NavLink to="/exdashboard" activeClassName="active" title="Example Dashboard">Example Dashboard</NavLink></li>
{ this.props.currentRole === 'Admin' ?
<li><NavLink to="/users" activeClassName="active" title="User Management">User Management</NavLink></li> : ''
}
......
......@@ -61,24 +61,24 @@ class Dashboard extends React.Component {
console.log("dashboard calculate state was called: " + props.match.params.dashboard);
let dashboards = DashboardStore.getState()
let rawDashboard = dashboards[props.match.params.dashboard - 1];
let str = JSON.stringify(rawDashboard, null, 4);
console.log(str);
if (rawDashboard != null) {
dashboard = Map(rawDashboard);
console.log("dashboard: " + dashboard);
// convert widgets list to a dictionary to be able to reference widgets
// convert widgets list to a dictionary to be able to reference widgets
//let widgets = {};
let rawWidgets = WidgetStore.getState();
if(rawWidgets.length === 0){
AppDispatcher.dispatch({
type: 'widgets/start-load',
token: sessionToken,
param: 'dashboardID=1'
param: '?dashboardID=1'
});
}
......@@ -92,14 +92,14 @@ class Dashboard extends React.Component {
});
}
console.log("here are the widgets: ");
console.log(rawWidgets);
dashboard = dashboard.set('widgets', rawWidgets);
console.log("")
/* for(let widget of dashboard.get('widgets')){
console.log("load files got called")
console.log(widget);
......@@ -110,9 +110,9 @@ class Dashboard extends React.Component {
});
}
*/
//ist das überhaupt nötiG??
/* if (this.state.dashboard.has('id') === false) {
AppDispatcher.dispatch({
......@@ -122,14 +122,14 @@ class Dashboard extends React.Component {
});
}
*/
/*if(Object.keys(widgets).length !== 0 ){
this.computeHeightWithWidgets(widgets);
}
let selectedDashboards = dashboard;
let selectedDashboards = dashboard;
/* this.setState({ dashboard: selectedDashboards, project: null });
......@@ -151,10 +151,10 @@ class Dashboard extends React.Component {
console.log("!! the widget key: "+ widgetKey);
let thisWidget = widgets[widgetKey];
let thisWidgetHeight = thisWidget.y + thisWidget.height;
return thisWidgetHeight > maxHeightSoFar? thisWidgetHeight : maxHeightSoFar;
}, 0);
console.log("now the object keys: ");
console.log(Object.keys(widgets));
let simulationModels = [];
......@@ -208,7 +208,7 @@ class Dashboard extends React.Component {
}
}
componentWillUnmount() {
//document.removeEventListener('keydown', this.handleKeydown.bind(this));
......@@ -261,7 +261,7 @@ class Dashboard extends React.Component {
default:
}
}
}
/*
* Adapt the area's height with the position of the new widget.
......@@ -494,7 +494,7 @@ class Dashboard extends React.Component {
<WidgetContextMenu key={widgetKey} index={parseInt(widgetKey,10)} widget={widgets[widgetKey]} onEdit={this.editWidget} onDelete={this.deleteWidget} onChange={this.widgetChange} />
))}
</div>
</div>;
}
......@@ -503,4 +503,4 @@ class Dashboard extends React.Component {
let fluxContainerConverter = require('../common/FluxContainerConverter');
export default Fullscreenable()(Container.create(fluxContainerConverter.convert(Dashboard), { withProps: true }));
//<EditWidget sessionToken={this.state.sessionToken} show={this.state.editModal} onClose={this.closeEdit} widget={this.state.modalData} simulationModels={this.state.simulationModels} files={this.state.files} />
//onEdit={this.startEditing}
\ No newline at end of file
//onEdit={this.startEditing}
import React, { Component } from 'react';
import { Container } from 'flux/utils';
import DashboardStore from './dashboard-store';
import AppDispatcher from '../common/app-dispatcher';
import Table from '../common/table';
import TableColumn from '../common/table-column';
import UserStore from '../user/user-store';
import { Button } from 'react-bootstrap';
import Icon from '../common/icon';
class ExDashboard extends Component {
static getStores() {
return [ DashboardStore ];
}
static calculateState(prevState, props) {
prevState = prevState || {};
console.log("calculateState has been called");
const dashboards = DashboardStore.getState();
let tokenState = UserStore.getState().token;
console.log(dashboards);
return{
dashboards,
tokenState
}
}
componentDidMount() {
AppDispatcher.dispatch({
type: 'dashboards/start-load',
token: this.state.tokenState,
param: 'scenarioID=1'
});
}
loadDash(){
console.log('bis hierhin gekommen');
AppDispatcher.dispatch({
type: 'dashboards/start-load',
token: this.state.tokenState,
param: 'scenarioID=1'
});
}
render() {
const buttonStyle = {
marginLeft: '10px'
};
return (
<div className='section'>
<h1>Dashboards</h1>
<Table data={this.state.dashboards}>
<TableColumn title='Name' dataKey='name' link='/exdashboard/' linkKey='id' />
<TableColumn title='Grid' dataKey='grid' link='/edashboard/' linkKey='id' />
<TableColumn title='ScenarioID' dataKey='scenarioID' link='/exdashboard/' linkKey='id' />
</Table>
<div style={{ float: 'right' }}>
<Button onClick={() => this.loadDash} style={buttonStyle}><Icon icon="plus" /> Add</Button>
</div>
</div>
);
}
}
let fluxContainerConverter = require('../common/FluxContainerConverter');
export default Container.create(fluxContainerConverter.convert(ExDashboard));
......@@ -24,7 +24,7 @@ import { FormGroup, FormControl, FormLabel } from 'react-bootstrap';
import Dialog from '../common/dialogs/dialog';
class NewVisualzationDialog extends React.Component {
class NewDashboardDialog extends React.Component {
valid: false;
constructor(props) {
......@@ -84,4 +84,4 @@ class NewVisualzationDialog extends React.Component {
}
}
export default NewVisualzationDialog;
export default NewDashboardDialog;
......@@ -27,6 +27,7 @@ import _ from 'lodash';
import ScenarioStore from './scenario-store';
import SimulatorStore from '../simulator/simulator-store';
import DashboardStore from '../dashboard/dashboard-store';
import SimulationModelStore from '../simulationmodel/simulation-model-store';
import UserStore from '../user/user-store';
import AppDispatcher from '../common/app-dispatcher';
......@@ -35,75 +36,83 @@ import Icon from '../common/icon';
import Table from '../common/table';
import TableColumn from '../common/table-column';
import ImportSimulationModelDialog from '../simulationmodel/import-simulation-model';
import ImportDashboardDialog from "../dashboard/import-dashboard";
import NewDashboardDialog from "../dashboard/new-dashboard";
import SimulatorAction from '../simulator/simulator-action';
import DeleteDialog from '../common/dialogs/delete-dialog';
class Scenario extends React.Component {
static getStores() {
return [ ScenarioStore, SimulatorStore, SimulationModelStore, UserStore ];
return [ ScenarioStore, SimulationModelStore, DashboardStore, SimulatorStore];
}
static calculateState(prevState, props) {
// get selected scenario
const sessionToken = UserStore.getState().token;
let scenario = ScenarioStore.getState().find(s => s.id === props.match.params.scenario);
const scenario = ScenarioStore.getState().find(s => s.id === parseInt(props.match.params.scenario, 10));
if (scenario == null) {
AppDispatcher.dispatch({
type: 'scenarios/start-load',
data: props.match.params.scenario,
token: sessionToken
});
scenario = {};
console.log(scenario);
}
// load models
let simulationModels = [];
if (scenario.simulationModels != null) {
simulationModels = SimulationModelStore.getState().filter(m => m != null && scenario.simulationModels.includes(m.id));
}
// obtain all dashboards of a scenario
let dashboards = DashboardStore.getState().filter(dashb => dashb.scenarioID === parseInt(props.match.params.scenario, 10));
// obtain all simulation models of a scenario
let simulationmodels = SimulationModelStore.getState().filter(simmodel => simmodel.scenarioID === parseInt(props.match.params.scenario, 10));
return {
simulationModels,
scenario,
//simulators: SimulatorStore.getState(),
sessionToken,
deleteModal: false,
importModal: false,
modalData: {},
selectedSimulationModels: []
simulationModels: simulationmodels,
dashboards: dashboards,
simulators: SimulatorStore.getState(),
deleteSimulationModelModal: false,
importSimulationModelModal: false,
modalSimulationModelData: {},
selectedSimulationModels: [],
newDashboardModal: false,
deleteDashboardModal: false,
importDashboardModal: false,
modalDashboardData: {},
}
}
componentWillMount() {
//load selected scenario
AppDispatcher.dispatch({
type: 'scenarios/start-load',
data: this.state.scenario.id,
token: this.state.sessionToken
});
// load simulation models for selected scenario
AppDispatcher.dispatch({
type: 'simulationModels/start-load',
token: this.state.sessionToken
token: this.state.sessionToken,
param: '?scenarioID='+this.state.scenario.id,
});
// load dashboards of selected scenario
AppDispatcher.dispatch({
type: 'simulators/start-load',
token: this.state.sessionToken
type: 'dashboards/start-load',
token: this.state.sessionToken,
param: '?scenarioID='+this.state.scenario.id,
});
//TODO users
//TODO dashboards
// load simulators to enable that simulation models work with them
AppDispatcher.dispatch({
type: 'simulators/start-load',
token: this.state.sessionToken,
});
}
addSimulationModel = () => {
......@@ -132,8 +141,8 @@ class Scenario extends React.Component {
});
}
closeDeleteModal = confirmDelete => {
this.setState({ deleteModal: false });
closeDeleteSimulationModelModal = confirmDelete => {
this.setState({ deleteSimulationModelModal: false });
if (confirmDelete === false) {
return;
......@@ -141,13 +150,13 @@ class Scenario extends React.Component {
AppDispatcher.dispatch({
type: 'simulationModels/start-remove',
data: this.state.modalData,
data: this.state.modalSimulationModelData,
token: this.state.sessionToken
});
}
importSimulationModel = simulationModel => {
this.setState({ importModal: false });
this.setState({ importSimulationModelModal: false });
if (simulationModel == null) {
return;
......@@ -155,8 +164,6 @@ class Scenario extends React.Component {
simulationModel.scenario = this.state.scenario.id;
console.log(simulationModel);
AppDispatcher.dispatch({
type: 'simulationModels/start-add',
data: simulationModel,
......@@ -172,6 +179,47 @@ class Scenario extends React.Component {
});
}
closeNewDashboardModal(data) {
this.setState({ newDashboardModal : false });
if (data) {
AppDispatcher.dispatch({
type: 'dashboards/start-add',
data,
token: this.state.sessionToken,
userid: this.state.sessionUserID
});
}
}
closeDeleteDashboardModal(confirmDelete){
this.setState({ deleteDashboardModal: false });
if (confirmDelete === false) {
return;
}
AppDispatcher.dispatch({
type: 'dashboards/start-remove',
data: this.state.modalDashboardData,
token: this.state.sessionToken,
userid: this.state.sessionUserID
});
}