diff --git a/src/common/icon-button.js b/src/common/icon-button.js index a905dd1..1f9ed33 100644 --- a/src/common/icon-button.js +++ b/src/common/icon-button.js @@ -42,6 +42,7 @@ class IconButton extends React.Component { variant='light' onClick={this.props.onClick} style={altButtonStyle} + disabled={this.props.disabled} > child.props.onEdit(index)} - disabled={child.props.onEdit == null} > + disabled={child.props.onEdit == null || isLocked} > @@ -190,7 +192,7 @@ class CustomTable extends Component { @@ -206,7 +208,7 @@ class CustomTable extends Component { @@ -242,7 +244,7 @@ class CustomTable extends Component { diff --git a/src/componentconfig/config-table.js b/src/componentconfig/config-table.js index f18fb6d..476f680 100644 --- a/src/componentconfig/config-table.js +++ b/src/componentconfig/config-table.js @@ -308,12 +308,14 @@ class ConfigTable extends Component { tooltip='Add Component Configuration' onClick={() => this.addConfig()} icon='plus' + disabled={this.props.locked} /> this.setState({ importConfigModal: true })} icon='upload' + disabled={this.props.locked} /> @@ -343,6 +345,7 @@ class ConfigTable extends Component { editButton onEdit={index => this.setState({ editOutputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} width={150} + locked={this.props.locked} /> this.setState({ editInputSignalsModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} width={150} + locked={this.props.locked} /> this.setState({ deleteConfigModal: true, modalConfigData: this.props.configs[index], modalConfigIndex: index })} onExport={index => this.exportConfig(index)} onDuplicate={index => this.duplicateConfig(index)} + locked={this.props.locked} /> diff --git a/src/dashboard/dashboard-button-group.js b/src/dashboard/dashboard-button-group.js index be73aad..a2b7b5f 100644 --- a/src/dashboard/dashboard-button-group.js +++ b/src/dashboard/dashboard-button-group.js @@ -91,9 +91,10 @@ class DashboardButtonGroup extends React.Component { } if (this.props.fullscreen !== true) { + let filesTooltip = this.props.locked ? "View files of scenario" : "Add, edit or delete files of scenario"; buttons.push( Add, edit or delete files of scenario }> + overlay={{filesTooltip}}> @@ -120,7 +121,7 @@ class DashboardButtonGroup extends React.Component { buttons.push( Add widgets and edit layout }> - diff --git a/src/dashboard/dashboard-table.js b/src/dashboard/dashboard-table.js index cb96fdb..7728d78 100644 --- a/src/dashboard/dashboard-table.js +++ b/src/dashboard/dashboard-table.js @@ -148,12 +148,14 @@ class DashboardTable extends Component { tooltip='Add Dashboard' onClick={() => this.setState({newDashboardModal: true})} icon='plus' + disabled={this.props.locked} /> this.setState({importDashboardModal: true})} icon='upload' + disabled={this.props.locked} /> @@ -198,6 +200,7 @@ class DashboardTable extends Component { })} onExport={index => this.exportDashboard(index)} onDuplicate={index => this.duplicateDashboard(index)} + locked={this.props.locked} /> diff --git a/src/dashboard/dashboard.js b/src/dashboard/dashboard.js index 8ed06ac..a68363a 100644 --- a/src/dashboard/dashboard.js +++ b/src/dashboard/dashboard.js @@ -35,6 +35,8 @@ import WidgetStore from '../widget/widget-store'; import ICStore from '../ic/ic-store' import ConfigStore from '../componentconfig/config-store' import AppDispatcher from '../common/app-dispatcher'; +import ScenarioStore from '../scenario/scenario-store'; + import 'react-contexify/dist/ReactContexify.min.css'; import WidgetContainer from '../widget/widget-container'; @@ -45,7 +47,7 @@ class Dashboard extends Component { static lastWidgetKey = 0; static webSocketsOpened = false; static getStores() { - return [DashboardStore, FileStore, WidgetStore, SignalStore, ConfigStore, ICStore]; + return [DashboardStore, FileStore, WidgetStore, SignalStore, ConfigStore, ICStore, ScenarioStore]; } static calculateState(prevState, props) { @@ -80,9 +82,14 @@ class Dashboard extends Component { // filter component configurations to the ones that belong to this scenario let configs = []; let files = []; + let locked = false; if (dashboard !== undefined) { configs = ConfigStore.getState().filter(config => config.scenarioID === dashboard.scenarioID); files = FileStore.getState().filter(file => file.scenarioID === dashboard.scenarioID); + let scenario = ScenarioStore.getState().find(s => s.id === dashboard.scenarioID); + if (scenario) { + locked = scenario.isLocked; + } if (dashboard.height === 0) { dashboard.height = 400; } @@ -144,6 +151,7 @@ class Dashboard extends Component { widgetOrigIDs: prevState.widgetOrigIDs || [], maxWidgetHeight: maxHeight || null, + locked, }; } @@ -205,6 +213,13 @@ class Dashboard extends Component { param: '?scenarioID=' + this.state.dashboard.scenarioID, token: this.state.sessionToken }); + + // load scenario for 'isLocked' value + AppDispatcher.dispatch({ + type: 'scenarios/start-load', + data: this.state.dashboard.scenarioID, + token: this.state.sessionToken + }); } } @@ -482,6 +497,7 @@ class Dashboard extends Component { this.onClose()} blendOutCancel = {true} @@ -139,6 +141,7 @@ class EditFilesDialog extends React.Component { onDelete={(index) => this.deleteFile(index)} editButton onEdit={index => this.setState({ editModal: true, modalFile: this.props.files[index] })} + locked={this.props.locked} /> @@ -146,13 +149,17 @@ class EditFilesDialog extends React.Component {
Add file
- this.selectUploadFile(event)} /> + this.selectUploadFile(event)} + disabled={this.props.locked} + /> diff --git a/src/result/result-table.js b/src/result/result-table.js index 92b8b62..4b81427 100644 --- a/src/result/result-table.js +++ b/src/result/result-table.js @@ -165,6 +165,7 @@ class ResultTable extends Component { tooltip='Add Result' onClick={() => this.setState({ newResultModal: true })} icon='plus' + disabled={this.props.locked} /> @@ -208,6 +209,7 @@ class ResultTable extends Component { onEdit={index => this.setState({ editResultsModal: true, modalResultsIndex: index })} onDownloadAll={(index) => this.downloadResultData(this.props.results[index])} onDelete={(index) => this.setState({ deleteResultsModal: true, modalResultsData: this.props.results[index], modalResultsIndex: index })} + locked={this.props.locked} /> diff --git a/src/scenario/scenario-users-table.js b/src/scenario/scenario-users-table.js index c93b356..f6e7b7a 100644 --- a/src/scenario/scenario-users-table.js +++ b/src/scenario/scenario-users-table.js @@ -124,6 +124,7 @@ class ScenarioUsersTable extends Component { deleteUserName: this.props.scenario.users[index].username, modalUserIndex: index })} + locked={this.props.locked} /> @@ -145,6 +146,7 @@ class ScenarioUsersTable extends Component { variant='light' type="submit" style={altButtonStyle} + disabled={this.props.locked} onClick={() => this.addUser()}> diff --git a/src/scenario/scenario.js b/src/scenario/scenario.js index 1e1033c..066f24f 100644 --- a/src/scenario/scenario.js +++ b/src/scenario/scenario.js @@ -126,11 +126,13 @@ class Scenario extends React.Component { return

Loading Scenario...

; } + let tooltip = this.state.scenario.isLocked ? "View files of scenario" : "Add, edit or delete files of scenario"; + return
@@ -144,6 +146,7 @@ class Scenario extends React.Component { signals={this.state.signals} files={this.state.files} scenarioID={this.state.scenario.id} + locked={this.state.scenario.isLocked} />
diff --git a/src/scenario/scenarios.js b/src/scenario/scenarios.js index 9d81a74..1e9df38 100644 --- a/src/scenario/scenarios.js +++ b/src/scenario/scenarios.js @@ -73,7 +73,7 @@ class Scenarios extends Component { } closeNewModal(data) { - if(data) { + if (data) { AppDispatcher.dispatch({ type: 'scenarios/start-add', data: data, @@ -218,7 +218,7 @@ class Scenarios extends Component { jsonObj["configs"] = this.getConfigs(scenario.id); jsonObj["dashboards"] = this.getDashboards(scenario.id); - if(jsonObj) { + if (jsonObj) { AppDispatcher.dispatch({ type: 'scenarios/start-add', data: jsonObj, @@ -227,68 +227,85 @@ class Scenarios extends Component { } } - modifyRunningColumn(running){ - return + isLocked(index) { + return this.state.scenarios[index].isLocked; + } + + onLock(scenario) { + let data = {}; + data.id = scenario.id; + data.isLocked = !scenario.isLocked; + + AppDispatcher.dispatch({ + type: 'scenarios/start-edit', + data, + token: this.state.sessionToken + }); } render() { return
-

Scenarios +

Scenarios - this.setState({ newModal: true })} - icon='plus' - /> - this.setState({ importModal: true })} - icon='upload' - /> - -

- - - {this.state.currentUser.role === "Admin" ? - - : <> - } - this.setState({ newModal: true })} + icon='plus' /> - this.modifyRunningColumn(running)} + this.setState({ importModal: true })} + icon='upload' /> + + + +
+ {this.state.currentUser.role === "Admin" ? this.setState({ editModal: true, modalScenario: this.state.scenarios[index] })} - onDelete={index => this.setState({ deleteModal: true, modalScenario: this.state.scenarios[index] })} - onExport={index => this.exportScenario(index)} - onDuplicate={index => this.duplicateScenario(index)} + title='ID' + dataKey='id' /> -
+ : <> + } + + {this.state.currentUser.role === "Admin" ? + this.onLock(index)} + /> + : <> + } + this.setState({ editModal: true, modalScenario: this.state.scenarios[index] })} + onDelete={index => this.setState({ deleteModal: true, modalScenario: this.state.scenarios[index] })} + onExport={index => this.exportScenario(index)} + onDuplicate={index => this.duplicateScenario(index)} + isLocked={index => this.isLocked(index)} + /> + - this.closeNewModal(data)} /> - this.closeEditModal(data)} scenario={this.state.modalScenario} /> - this.closeImportModal(data)} nodes={this.state.nodes} /> + this.closeNewModal(data)} /> + this.closeEditModal(data)} scenario={this.state.modalScenario} /> + this.closeImportModal(data)} nodes={this.state.nodes} /> - this.closeDeleteModal(e)} /> -
; + this.closeDeleteModal(e)} /> +
; } }