diff --git a/src/dashboard/new-dashboard.js b/src/common/dialogs/new-dialog.js similarity index 68% rename from src/dashboard/new-dashboard.js rename to src/common/dialogs/new-dialog.js index 5cc8a3e..8c7b44f 100644 --- a/src/dashboard/new-dashboard.js +++ b/src/common/dialogs/new-dialog.js @@ -18,49 +18,47 @@ import React from 'react'; import { Form } from 'react-bootstrap'; -import Dialog from '../common/dialogs/dialog'; - -class NewDashboardDialog extends React.Component { - valid: false; +import Dialog from './dialog'; +class NewDialog extends React.Component { constructor(props) { super(props); this.state = { - name: '' + value: '' } } onClose(canceled) { if (canceled === false) { - if (this.valid) { - this.props.onClose(this.state); - } + this.props.onClose(this.state); } else { this.props.onClose(); } } handleChange(e) { + console.log(e) + this.setState({ [e.target.id]: e.target.value }); } resetState() { - this.setState({ name: '' }); + this.setState({ value: '' }); } validateForm(target) { // check all controls - var name = true; + var inputGiven = true; - if (this.state.name === '') { - name = false; + if (this.state.value === '') { + inputGiven = false; } - this.valid = name; + this.valid = inputGiven; // return state to control - if (target === 'name') return name ? "success" : "error"; + if (target === 'value') return inputGiven ? "success" : "error"; return "success"; } @@ -68,17 +66,18 @@ class NewDashboardDialog extends React.Component { render() { return ( this.onClose(c)} onReset={() => this.resetState()} valid={this.valid} >
- - Name - this.handleChange(e)} /> + + {this.props.inputLabel} + this.handleChange(e)} /> @@ -87,4 +86,4 @@ class NewDashboardDialog extends React.Component { } } -export default NewDashboardDialog; +export default NewDialog; diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index b86332a..abe8b50 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -15,11 +15,12 @@ * along with VILLASweb. If not, see . ******************************************************************************/ -import React, {Component} from "react"; +import React, { Component } from "react"; import FileSaver from 'file-saver'; import IconButton from "../common/icon-button"; import Table from "../common/table"; import TableColumn from "../common/table-column"; +import NewDialog from "../common/dialogs/new-dialog"; import DeleteDialog from "../common/dialogs/delete-dialog"; import AppDispatcher from "../common/app-dispatcher"; import NotificationsDataManager from "../common/data-managers/notifications-data-manager"; @@ -37,21 +38,21 @@ class ConfigTable extends Component { editConfigModal: false, modalConfigData: {}, modalConfigIndex: 0, + newConfigModal: false, deleteConfigModal: false, importConfigModal: false, - newConfig: false, selectedConfigs: [], ExternalICInUse: false, - editOutputSignalsModal: false, - editInputSignalsModal: false, + editOutputSignalsModal: false, + editInputSignalsModal: false, } } - static getDerivedStateFromProps(props, state){ + static getDerivedStateFromProps(props, state) { let ExternalICInUse = false - for (let config of props.configs){ + for (let config of props.configs) { for (let component of props.ics) { if ((config.icID === component.id) && (component.managedexternally === true)) { ExternalICInUse = true; @@ -65,26 +66,27 @@ class ConfigTable extends Component { }; } - addConfig() { - const config = { - scenarioID: this.props.scenario.id, - name: 'New Component Configuration', - icID: this.props.ics.length > 0 ? this.props.ics[0].id : null, - startParameters: {}, - }; + closeNewConfigModal(data) { + this.setState({ newConfigModal: false }); - AppDispatcher.dispatch({ - type: 'configs/start-add', - data: config, - token: this.props.sessionToken - }); - - this.setState({ newConfig: true }); + if (data) { + const config = { + scenarioID: this.props.scenario.id, + name: data.value, + icID: this.props.ics.length > 0 ? this.props.ics[0].id : null, + startParameters: {}, + }; + AppDispatcher.dispatch({ + type: 'configs/start-add', + data: config, + token: this.props.sessionToken + }); + } } closeEditConfigModal(data) { - this.setState({ editConfigModal: false, newConfig: false }); + this.setState({ editConfigModal: false }); if (data) { AppDispatcher.dispatch({ @@ -312,27 +314,27 @@ class ConfigTable extends Component { {/*Component Configurations table*/}

Component Configurations - this.addConfig()} - icon='plus' - disabled={this.props.locked} - hidetooltip={this.props.locked} - buttonStyle={buttonStyle} - iconStyle={iconStyle} - /> - this.setState({ importConfigModal: true })} - icon='upload' - disabled={this.props.locked} - hidetooltip={this.props.locked} - buttonStyle={buttonStyle} - iconStyle={iconStyle} - /> - + this.setState({ newConfigModal: true })} + icon='plus' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> + this.setState({ importConfigModal: true })} + icon='upload' + disabled={this.props.locked} + hidetooltip={this.props.locked} + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> +

this.copyConfig(index)} - token = {this.props.sessionToken} + selectedConfigs={this.state.selectedConfigs} + snapshotConfig={(index) => this.copyConfig(index)} + token={this.props.sessionToken} actions={[ { id: '0', title: 'Start', data: { action: 'start' } }, { id: '1', title: 'Stop', data: { action: 'stop' } }, @@ -432,6 +434,13 @@ class ConfigTable extends Component { onClose={data => this.importConfig(data)} ics={this.props.ics} /> + this.closeNewConfigModal(data)} + />
- this.closeNewDashboardModal(data)} /> + . - ******************************************************************************/ - -import React from 'react'; -import { Form } from 'react-bootstrap'; - -import Dialog from '../common/dialogs/dialog'; - -class NewResultDialog extends React.Component { - - constructor(props) { - super(props); - - this.state = { - ConfigSnapshots: '', - Description: '', - ResultFileIDs: [], - } - } - - onClose(canceled) { - if (canceled === false) { - this.props.onClose(this.state); - } else { - this.props.onClose(); - } - } - - handleChange(e) { - this.setState({ [e.target.id]: e.target.value }); - } - - resetState() { - this.setState({ - ConfigSnapshots: '', - Description: '', - ResultFileIDs: [], - }); - } - - render() { - return ( - this.onClose(c)} - onReset={() => this.resetState()} - valid={true} - > -
- - Description - this.handleChange(e)} /> - - -
-
- ); - } -} - -export default NewResultDialog; diff --git a/src/result/result-table.js b/src/result/result-table.js index 96dd765..f50707c 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -26,7 +26,7 @@ import TableColumn from "../common/table-column"; import DeleteDialog from "../common/dialogs/delete-dialog"; import EditResultDialog from "./edit-result"; import ResultConfigDialog from "./result-configs-dialog"; -import NewResultDialog from "./new-result"; +import NewDialog from "../common/dialogs/new-dialog"; class ResultTable extends Component { @@ -79,10 +79,13 @@ class ResultTable extends Component { closeNewResultModal(data) { this.setState({ newResultModal: false }); if (data) { - data["scenarioID"] = this.props.scenario.id; + let newResult = { ConfigSnapshots: '', ResultFileIDs: [] }; + newResult["scenarioID"] = this.props.scenario.id; + newResult["Description"] = data.value; + AppDispatcher.dispatch({ type: 'results/start-add', - data, + data: newResult, token: this.props.sessionToken, }); } @@ -245,8 +248,11 @@ class ResultTable extends Component { resultNo={this.state.modalResultConfigsIndex} onClose={this.closeResultConfigSnapshots.bind(this)} /> - this.closeNewResultModal(data)} /> diff --git a/src/user/users-to-scenario.js b/src/user/users-to-scenario.js new file mode 100644 index 0000000..81e4a19 --- /dev/null +++ b/src/user/users-to-scenario.js @@ -0,0 +1,71 @@ +/** + * This file is part of VILLASweb. + * + * VILLASweb is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * VILLASweb is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with VILLASweb. If not, see . + ******************************************************************************/ + +import React from 'react'; +import { Table } from 'react-bootstrap'; + +import Dialog from '../common/dialogs/dialog'; + +class UsersToScenarioDialog extends React.Component { + valid = true; + + onClose() { + if (this.props.onClose != null) { + this.props.onClose(); + } + }; + + renderRow(value, key) { + return ( + {key} + {value} + ); + } + + renderData() { + let arr = []; + this.props.users.forEach((value, key) => { + arr.push(this.renderRow(value,key)) + }) + return arr; + } + + render() { + return this.onClose()} + valid={true} + > + + + + + + + + + { this.renderData() } + +
IDName
+
; + } +} + +export default UsersToScenarioDialog; diff --git a/src/user/users.js b/src/user/users.js index d4cd584..3cf7721 100644 --- a/src/user/users.js +++ b/src/user/users.js @@ -20,13 +20,16 @@ import { Container } from 'flux/utils'; import AppDispatcher from '../common/app-dispatcher'; import UsersStore from './users-store'; +import ScenarioStore from '../scenario/scenario-store'; import Icon from '../common/icon'; import IconButton from '../common/icon-button'; +import { Dropdown, DropdownButton } from 'react-bootstrap'; import Table from '../common/table'; import TableColumn from '../common/table-column'; import NewUserDialog from './new-user'; import EditUserDialog from './edit-user'; +import UsersToScenarioDialog from './users-to-scenario'; import DeleteDialog from '../common/dialogs/delete-dialog'; import NotificationsDataManager from "../common/data-managers/notifications-data-manager"; @@ -34,25 +37,25 @@ import NotificationsFactory from "../common/data-managers/notifications-factory" class Users extends Component { static getStores() { - return [ UsersStore ]; + return [UsersStore, ScenarioStore]; } static calculateState(prevState, props) { - let token = localStorage.getItem("token"); - // If there is a token available and this method was called as a result of loading users - if (!prevState && token) { - AppDispatcher.dispatch({ - type: 'users/start-load', - token: token - }); + if (prevState == null) { + prevState = {}; } return { - token: token, + token: localStorage.getItem("token"), users: UsersStore.getState(), + scenarios: ScenarioStore.getState(), + usersToAdd: prevState.usersToAdd || new Map(), + selectedScenarioID: prevState.selectedScenarioID || null, + selectedScenario: prevState.selectedScenario || '', newModal: false, + addUsersModal: false, editModal: false, deleteModal: false, modalData: {}, @@ -60,6 +63,19 @@ class Users extends Component { }; } + componentDidMount() { + AppDispatcher.dispatch({ + type: 'scenarios/start-load', + token: this.state.token + }); + + AppDispatcher.dispatch({ + type: 'users/start-load', + token: this.state.token + }); + + } + closeNewModal(data) { this.setState({ newModal: false }); @@ -102,14 +118,37 @@ class Users extends Component { } } - onModalKeyPress = (event) => { - if (event.key === 'Enter') { - event.preventDefault(); - - this.confirmDeleteModal(); + onUserChecked(user) { + let temp = this.state.usersToAdd; + const found = temp.get(user.id); + if (!found) { + temp.set(user.id, user.username); + } else { + temp.delete(user.id) } + this.setState({ usersToAdd: temp }); + } + + setScenario(ID) { + + let scenarioID = parseInt(ID, 10) + let scenario = this.state.scenarios.find(s => s.id === scenarioID); + this.setState({ selectedScenarioID: scenario.id, selectedScenario: scenario.name, addUsersModal: true }) }; + closeAddUsersModal() { + this.state.usersToAdd.forEach((value, key) => { + AppDispatcher.dispatch({ + type: 'scenarios/add-user', + data: this.state.selectedScenarioID, + username: value, + token: this.state.token + }); + }) + + this.setState({ addUsersModal: false, selectedScenarioID: null }) + } + modifyActiveColumn(active) { return } @@ -125,65 +164,91 @@ class Users extends Component { } return
-

Users +

Users - this.setState({ newModal: true })} - icon='plus' - buttonStyle={buttonStyle} - iconStyle={iconStyle} - /> - -

+ this.setState({ newModal: true })} + icon='plus' + buttonStyle={buttonStyle} + iconStyle={iconStyle} + /> + + - - {this.state.currentUser.role === "Admin" ? - - : <> - } +
+ {this.state.currentUser.role === "Admin" ? + : <> + } + {this.state.currentUser.role === "Admin" ? this.onUserChecked(index, event)} + checkboxKey='checked' + width='30' /> - - this.modifyActiveColumn(active)} - /> - this.setState({ - editModal: true, - modalData: this.state.users[index] - })} - onDelete={index => this.setState({ - deleteModal: true, - modalData: this.state.users[index] - })} - /> -
+ : <> + } + + + + this.modifyActiveColumn(active)} + /> + this.setState({ + editModal: true, + modalData: this.state.users[index] + })} + onDelete={index => this.setState({ + deleteModal: true, + modalData: this.state.users[index] + })} + /> + + + this.setScenario(id)} + > + {this.state.scenarios.map(scenario => ( + {scenario.name} + ))} + + - this.closeNewModal(data)} /> - this.closeEditModal(data)} user={this.state.modalData} /> - this.closeDeleteModal(e)} /> -
; + this.closeAddUsersModal()} + /> + this.closeNewModal(data)} /> + this.closeEditModal(data)} user={this.state.modalData} /> + this.closeDeleteModal(e)} /> + ; } }