diff --git a/src/app.js b/src/app.js index cd68009..92bb42c 100644 --- a/src/app.js +++ b/src/app.js @@ -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 {
- @@ -154,7 +152,6 @@ class App extends React.Component { -
diff --git a/src/common/api/rest-api.js b/src/common/api/rest-api.js index 78f5d52..bb92e10 100644 --- a/src/common/api/rest-api.js +++ b/src/common/api/rest-api.js @@ -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) { diff --git a/src/common/array-store.js b/src/common/array-store.js index 2bbdb1a..15a13ab 100644 --- a/src/common/array-store.js +++ b/src/common/array-store.js @@ -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; diff --git a/src/common/data-managers/rest-data-manager.js b/src/common/data-managers/rest-data-manager.js index e928804..559d404 100644 --- a/src/common/data-managers/rest-data-manager.js +++ b/src/common/data-managers/rest-data-manager.js @@ -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 { }); }); } - - + + }; diff --git a/src/common/menu-sidebar.js b/src/common/menu-sidebar.js index be42a68..5f43425 100644 --- a/src/common/menu-sidebar.js +++ b/src/common/menu-sidebar.js @@ -35,7 +35,6 @@ class SidebarMenu extends React.Component {
  • Home
  • Scenarios
  • Simulators
  • -
  • Example Dashboard
  • { this.props.currentRole === 'Admin' ?
  • User Management
  • : '' } diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 227a536..67bdbc7 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -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 { ))} - + ; } @@ -503,4 +503,4 @@ class Dashboard extends React.Component { let fluxContainerConverter = require('../common/FluxContainerConverter'); export default Fullscreenable()(Container.create(fluxContainerConverter.convert(Dashboard), { withProps: true })); // -//onEdit={this.startEditing} \ No newline at end of file +//onEdit={this.startEditing} diff --git a/src/dashboard/exdashboard.js b/src/dashboard/exdashboard.js deleted file mode 100644 index ee7a014..0000000 --- a/src/dashboard/exdashboard.js +++ /dev/null @@ -1,85 +0,0 @@ -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 ( - -
    - -

    Dashboards

    - - - - - -
    - -
    - -
    -
    - ); - } -} - - - - -let fluxContainerConverter = require('../common/FluxContainerConverter'); -export default Container.create(fluxContainerConverter.convert(ExDashboard)); diff --git a/src/dashboard/new-dashboard.js b/src/dashboard/new-dashboard.js index cbac2cb..b05fbad 100644 --- a/src/dashboard/new-dashboard.js +++ b/src/dashboard/new-dashboard.js @@ -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; diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 7de6e7d..85fee67 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -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, + simulationModels: simulationmodels, + dashboards: dashboards, + simulators: SimulatorStore.getState(), - deleteModal: false, - importModal: false, - modalData: {}, + deleteSimulationModelModal: false, + importSimulationModelModal: false, + modalSimulationModelData: {}, + selectedSimulationModels: [], - 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: 'dashboards/start-load', + token: this.state.sessionToken, + param: '?scenarioID='+this.state.scenario.id, + }); + + // load simulators to enable that simulation models work with them AppDispatcher.dispatch({ type: 'simulators/start-load', - token: this.state.sessionToken + token: this.state.sessionToken, }); - - //TODO users - - //TODO dashboards - - - - } 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 + }); + } + + closeImportDashboardModal(data) { + this.setState({ importDashboardModal: false }); + + if (data) { + AppDispatcher.dispatch({ + type: 'dashboards/start-add', + data, + token: this.state.sessionToken, + userid: this.state.sessionUserID + }); + } + } + getSimulatorName(simulatorId) { for (let simulator of this.state.simulators) { if (simulator.id === simulatorId) { @@ -184,14 +232,26 @@ class Scenario extends React.Component { // filter properties const model = Object.assign({}, this.state.simulationModels[index]); - delete model.simulator; - delete model.scenario; + //delete model.simulator; + //delete model.scenario; + // TODO get elements recursively // show save dialog const blob = new Blob([JSON.stringify(model, null, 2)], { type: 'application/json' }); FileSaver.saveAs(blob, 'simulation model - ' + model.name + '.json'); } + exportDashboard(index) { + // filter properties + const dashboard = Object.assign({}, this.state.dashboards[index]); + + // TODO get elements recursively + + // show save dialog + const blob = new Blob([JSON.stringify(dashboard, null, 2)], { type: 'application/json' }); + FileSaver.saveAs(blob, 'dashboard - ' + dashboard.name + '.json'); + } + onSimulationModelChecked(index, event) { const selectedSimulationModels = Object.assign([], this.state.selectedSimulationModels); for (let key in selectedSimulationModels) { @@ -250,20 +310,22 @@ class Scenario extends React.Component { }; return
    -

    {this.state.simulation.name}

    +

    {this.state.scenario.name}

    + {/*Simulation Model table*/} +

    Simulation Models

    this.onSimulationModelChecked(index, event)} width='30' /> - - this.getSimulatorName(simulator)} /> - - + + this.getSimulatorName(simulatorID)} /> + + this.setState({ deleteModal: true, modalData: this.state.simulationModels[index], modalIndex: index })} + onDelete={(index) => this.setState({ deleteSimulationModelModal: true, modalSimulationModelData: this.state.simulationModels[index], modalSimulationModelIndex: index })} onExport={index => this.exportModel(index)} />
    @@ -282,14 +344,43 @@ class Scenario extends React.Component {
    - +
    - + + + + + {/*Dashboard table*/} +

    Dashboards

    + + + + this.setState({ deleteDashboardModal: true, modalDashboardData: this.state.dashboards[index], modalDashboardIndex: index })} + onExport={index => this.exportDashboard(index)} + /> +
    + +
    + + +
    + +
    + + this.closeNewDashboardModal(data)}/> + this.closeImportDashboardModal(data)} /> + + this.closeDeleteDashboardModal(e)}/> + -
    ; } } diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 5789e31..912abe5 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -178,8 +178,8 @@ class Scenarios extends Component { - - + + { // search action for (let action of this.props.actions) { @@ -56,11 +56,13 @@ class SimulatorAction extends React.Component { )); return
    + - {actionList} + {actionList} - + +
    ; } }