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

manual merge of master

This commit is contained in:
irismarie 2021-03-25 11:47:39 +01:00
commit e0d7fe5538
10 changed files with 224 additions and 66 deletions

158
package-lock.json generated
View file

@ -3926,6 +3926,11 @@
"isarray": "^1.0.0"
}
},
"buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
@ -5775,6 +5780,14 @@
"safer-buffer": "^2.1.0"
}
},
"ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"requires": {
"safe-buffer": "^5.0.1"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@ -7114,6 +7127,14 @@
"resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
"integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="
},
"fibers": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/fibers/-/fibers-5.0.0.tgz",
"integrity": "sha512-UpGv/YAZp7mhKHxDvC1tColrroGRX90sSvh8RMZV9leo+e5+EkRVgCEZPlmXeo3BUNQTZxUaVdLskq1Q2FyCPg==",
"requires": {
"detect-libc": "^1.0.3"
}
},
"figgy-pudding": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz",
@ -8209,11 +8230,6 @@
"resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
"integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps="
},
"immer": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz",
"integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA=="
},
"immutable": {
"version": "3.8.2",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
@ -10701,6 +10717,30 @@
"universalify": "^2.0.0"
}
},
"jsonwebtoken": {
"version": "8.5.1",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
"integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
"requires": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^5.6.0"
},
"dependencies": {
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
}
}
},
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@ -10732,6 +10772,33 @@
"set-immediate-shim": "~1.0.1"
}
},
"jwa": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
"integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
"requires": {
"buffer-equal-constant-time": "1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"requires": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"keygrip": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
"integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
"requires": {
"tsscmp": "1.0.6"
}
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
@ -10884,11 +10951,46 @@
"resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz",
"integrity": "sha1-h79AKSuM+D5OjOGjrkIJ4gBxZ1o="
},
"lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8="
},
"lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY="
},
"lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M="
},
"lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w="
},
"lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
},
"lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE="
},
"lodash.memoize": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
"integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4="
},
"lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w="
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
@ -13883,24 +13985,21 @@
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="
},
"globby": {
"version": "11.0.1",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz",
"integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==",
"requires": {
"array-union": "^2.1.0",
"dir-glob": "^3.0.1",
"fast-glob": "^3.1.1",
"ignore": "^5.1.4",
"merge2": "^1.3.0",
"slash": "^3.0.0"
}
"immer": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/immer/-/immer-8.0.1.tgz",
"integrity": "sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA=="
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
},
"react-error-overlay": {
"version": "6.0.9",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@ -14000,11 +14099,6 @@
"prop-types": "^15.6.0"
}
},
"react-error-overlay": {
"version": "6.0.9",
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.9.tgz",
"integrity": "sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew=="
},
"react-fullscreenable": {
"version": "2.5.1-0",
"resolved": "https://registry.npmjs.org/react-fullscreenable/-/react-fullscreenable-2.5.1-0.tgz",
@ -16710,6 +16804,18 @@
"resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-2.0.12.tgz",
"integrity": "sha512-3IVX4nI6B5cc31/GFFE+i8ey/N2eA0CZDbo6n0yrz0zDX8ZJ8djmU1p+XRz7G3is0F3bB3pu2pAroFdAWQKU3w=="
},
"ts-node": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
"integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
"requires": {
"arg": "^4.1.0",
"diff": "^4.0.1",
"make-error": "^1.1.1",
"source-map-support": "^0.5.17",
"yn": "3.1.1"
}
},
"ts-pnp": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz",
@ -17092,6 +17198,14 @@
"use-isomorphic-layout-effect": "^1.0.0"
}
},
"utf-8-validate": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-5.0.3.tgz",
"integrity": "sha512-jtJM6fpGv8C1SoH4PtG22pGto6x+Y8uPprW0tw3//gGFhDDTiuksgradgFN6yRayDP4SyZZa6ZMGHLIa17+M8A==",
"requires": {
"use-isomorphic-layout-effect": "^1.0.0"
}
},
"util": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",

View file

@ -21,9 +21,10 @@
"file-saver": "^2.0.5",
"flux": "^3.1.3",
"gaugeJS": "^1.3.7",
"handlebars": "^4.7.7",
"jquery": "^3.6.0",
"jszip": "^3.6.0",
"handlebars": "^4.7.6",
"jquery": "^3.5.1",
"jsonwebtoken": "^8.5.1",
"jszip": "^3.5.0",
"libcimsvg": "git+https://git.rwth-aachen.de/acs/public/cim/pintura-npm-package.git",
"lodash": "^4.17.21",
"moment": "^2.29.1",
@ -41,6 +42,7 @@
"react-dnd-html5-backend": "^10.0.2",
"react-dom": "^16.14.0",
"react-fullscreenable": "^2.5.1-0",
"react-grid-system": "^7.1.1",
"react-json-view": "^1.21.3",
"react-notification-system": "^0.4.0",
"react-rnd": "^10.2.4",

View file

@ -20,6 +20,7 @@ import { DndProvider } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import NotificationSystem from 'react-notification-system';
import { Redirect, Route } from 'react-router-dom';
import jwt from 'jsonwebtoken'
import AppDispatcher from './common/app-dispatcher';
import NotificationsDataManager from './common/data-managers/notifications-data-manager';
@ -36,6 +37,7 @@ import Users from './user/users';
import User from './user/user';
import APIBrowser from './common/api-browser';
import './styles/app.css';
import branding from './branding/branding';
@ -59,22 +61,37 @@ class App extends React.Component {
// if token stored locally, we are already logged-in
let token = localStorage.getItem("token");
if (token != null && token !== '') {
let currentUser = JSON.parse(localStorage.getItem("currentUser"));
console.log("Already logged-in")
AppDispatcher.dispatch({
type: 'users/logged-in',
token: token,
currentUser: currentUser
});
let isExpired = this.tokenIsExpired(token);
if (isExpired) {
console.log("Token expired")
AppDispatcher.dispatch({
type: 'users/logout'
});
} else {
let currentUser = JSON.parse(localStorage.getItem("currentUser"));
console.log("Already logged-in")
AppDispatcher.dispatch({
type: 'users/logged-in',
token: token,
currentUser: currentUser
});
}
}
}
tokenIsExpired(token){
let decodedToken = jwt.decode(token);
let timeNow = (new Date().getTime() + 1) / 1000;
return decodedToken.exp < timeNow;
}
render() {
let token = localStorage.getItem("token");
let currentUserRaw = localStorage.getItem("currentUser");
if (token == null || token === "" || currentUserRaw == null || currentUserRaw === "") {
if ((token == null || token === "" || currentUserRaw == null || currentUserRaw === "") || this.tokenIsExpired(token)) {
console.log("APP redirecting to logout/ login")
return (<Redirect to="/logout" />);
}

View file

@ -21,7 +21,7 @@ import Fullscreenable from 'react-fullscreenable';
import classNames from 'classnames';
import EditWidget from '../widget/edit-widget/edit-widget';
import EditFiles from '../file/edit-files';
import EditFilesDialog from '../file/edit-files';
import EditSignalMappingDialog from "../signal/edit-signal-mapping";
import WidgetContextMenu from '../widget/widget-context-menu';
import WidgetToolbox from '../widget/widget-toolbox';
@ -560,7 +560,7 @@ class Dashboard extends Component {
ics={this.state.ics}
/>
<EditFiles
<EditFilesDialog
sessionToken={this.state.sessionToken}
show={this.state.filesEditModal}
onClose={this.closeEditFiles.bind(this)}

View file

@ -16,7 +16,7 @@
******************************************************************************/
import React from 'react';
import { Form, Button, Col, ProgressBar } from 'react-bootstrap';
import {Form, Button, Col, ProgressBar, Row} from 'react-bootstrap';
import Dialog from '../common/dialogs/dialog';
import AppDispatcher from "../common/app-dispatcher";
import Table from "../common/table";
@ -142,24 +142,26 @@ class EditFilesDialog extends React.Component {
/>
</Table>
<Form.Group as={Col} >
<Form.Control
disabled={this.props.disabled}
type='file'
onChange={(event) => this.selectUploadFile(event)}
/>
</Form.Group>
<Form.Group as={Col} >
<div style={{ float: 'center' }}>
<h5>Add file</h5>
<Row>
<Col xs lg="4">
<Form.Control type='file' onChange={(event) => this.selectUploadFile(event)} />
</Col>
<Col xs lg="2">
<span className='solid-button'>
<Button
variant='secondary'
disabled={this.state.uploadFile === null}
onClick={() => this.startFileUpload()}>
Upload
</Button>
</Button>
</span>
</Form.Group>
</Col>
</Row>
</div>
<br />
<Form.Group as={Col} >
<ProgressBar
@ -167,7 +169,6 @@ class EditFilesDialog extends React.Component {
animated={true}
now={this.state.uploadProgress}
label={this.state.uploadProgress + '%'}
style={progressBarStyle}
/>
</Form.Group>

View file

@ -74,14 +74,14 @@ class ICAction extends React.Component {
* see: https://villas.fein-aachen.org/doc/controller-protocol.html
*/
if (newAction.action == "create" || newAction.action === "delete") {
if (newAction.action === "create" || newAction.action === "delete") {
// prepare parameters for delete incl. correct IC id
newAction["parameters"] = {};
if (newAction.action == "delete") {
if (newAction.action === "delete") {
newAction.parameters["uuid"] = ic.uuid;
}
else if (newAction.action == "create") {
else if (newAction.action === "create") {
newAction.parameters = ic.statusupdateraw.properties;
}

View file

@ -88,14 +88,14 @@ class InfrastructureComponentStore extends ArrayStore {
// adapt URL for newly created result ID
a.results.url = a.results.url.replace("RESULTID", action.data.result.id);
a.results.url = ICsDataManager.makeURL(a.results.url);
a.results.url = window.location.host + a.results.url;
a.results.url = 'https://' + window.location.host + a.results.url;
}
if (a.model !== undefined && a.model != null && JSON.stringify(a.model) !== JSON.stringify({})) {
// adapt URL(s) for model file
let modelURLs = []
for (let url of a.model.url){
let modifiedURL = ICsDataManager.makeURL(url);
modifiedURL = window.location.host + modifiedURL;
modifiedURL = 'https://' + window.location.host + modifiedURL;
modelURLs.push(modifiedURL)
}
a.model.url = modelURLs

View file

@ -154,11 +154,13 @@ class EditResultDialog extends React.Component {
<Form.Control.Feedback />
</Col>
<Col xs lg="2">
<span className='solid-button'>
<Button
type="submit"
onClick={() => this.submitDescription()}>
Save
</Button>
</span>
</Col>
</Row>
</Form.Group>
@ -194,11 +196,14 @@ class EditResultDialog extends React.Component {
<Form.Control type='file' onChange={(event) => this.selectUploadFile(event)} />
</Col>
<Col xs lg="2">
<span className='solid-button'>
<Button
variant='secondary'
disabled={this.state.uploadFile === null}
onClick={() => this.startFileUpload()}>
Upload
</Button>
</span>
</Col>
</Row>
</div>

View file

@ -36,7 +36,7 @@ import ImportConfigDialog from '../componentconfig/import-config';
import ImportDashboardDialog from "../dashboard/import-dashboard";
import NewDashboardDialog from "../dashboard/new-dashboard";
import EditDashboardDialog from '../dashboard/edit-dashboard';
import EditFiles from '../file/edit-files'
import EditFilesDialog from '../file/edit-files'
import NewResultDialog from '../result/new-result';
import EditResultDialog from '../result/edit-result';
import ResultConfigDialog from '../result/result-configs-dialog';
@ -168,7 +168,7 @@ class Scenario extends React.Component {
componentDidUpdate(prevProps, prevState) {
// check whether file data has been loaded
if (this.state.filesToDownload && this.state.filesToDownload.length > 0) {
if (this.state.files != prevState.files) {
if (this.state.files !== prevState.files) {
if (!this.state.zipfiles) {
let fileToDownload = FileStore.getState().filter(file => file.id === this.state.filesToDownload[0])
if (fileToDownload.length === 1 && fileToDownload[0].data) {
@ -746,7 +746,7 @@ class Scenario extends React.Component {
</div>
<h1>{this.state.scenario.name}</h1>
<EditFiles
<EditFilesDialog
sessionToken={this.state.sessionToken}
show={this.state.filesEditModal}
onClose={this.closeEditFiles.bind(this)}
@ -777,44 +777,50 @@ class Scenario extends React.Component {
checkbox
checkboxDisabled={(index) => !this.usesExternalIC(index)}
onChecked={(index, event) => this.onConfigChecked(index, event)}
width='30'
width={20}
/>
{this.state.currentUser.role === "Admin" ?
<TableColumn
title='ID'
dataKey='id'
width={70}
/>
: <></>
}
<TableColumn
title='Name'
dataKey='name'
width={300}
/>
<TableColumn
title='# Output Signals'
dataKey='outputLength'
editButton
onEdit={index => this.setState({ editOutputSignalsModal: true, modalConfigData: this.state.configs[index], modalConfigIndex: index })}
width={150}
/>
<TableColumn
title='# Input Signals'
dataKey='inputLength'
editButton
onEdit={index => this.setState({ editInputSignalsModal: true, modalConfigData: this.state.configs[index], modalConfigIndex: index })}
width={150}
/>
<TableColumn
title='Import Signals'
exportButton
onExport={(index) => this.signalsAutoConf(index)}
width={150}
/>
<TableColumn
title='Infrastructure Component'
dataKey='icID'
modifier={(icID) => this.getICName(icID)}
width={300}
/>
<TableColumn
title=''
width='200'
width={200}
align='right'
editButton
deleteButton
@ -905,6 +911,7 @@ class Scenario extends React.Component {
<TableColumn
title='ID'
dataKey='id'
width={70}
/>
: <></>
}
@ -913,13 +920,17 @@ class Scenario extends React.Component {
dataKey='name'
link='/dashboards/'
linkKey='id'
width={300}
/>
<TableColumn
title='Grid'
dataKey='grid' />
dataKey='grid'
width={100}
/>
<TableColumn
title=''
width='200'
width={200}
align='right'
editButton
deleteButton
@ -969,18 +980,22 @@ class Scenario extends React.Component {
title='ID'
dataKey='id'
modifier={(id, result) => this.modifyResultNoColumn(id, result)}
width={70}
/>
<TableColumn
title='Description'
dataKey='description'
width={300}
/>
<TableColumn
title='Created at'
dataKey='createdAt'
width={200}
/>
<TableColumn
title='Last update'
dataKey='updatedAt'
width={200}
/>
<TableColumn
title='Files'
@ -988,9 +1003,10 @@ class Scenario extends React.Component {
linkKey='filebuttons'
data={this.state.files}
onDownload={(index) => this.downloadResultData(index)}
width={300}
/>
<TableColumn
width='200'
width={200}
align='right'
editButton
downloadAllButton
@ -1034,20 +1050,23 @@ class Scenario extends React.Component {
<TableColumn
title='ID'
dataKey='id'
width={70}
/>
: <></>
}
<TableColumn
title='Name'
dataKey='username'
width={300}
/>
<TableColumn
title='Role'
dataKey='role'
width={100}
/>
<TableColumn
title=''
width='200'
width={30}
align='right'
deleteButton
onDelete={(index) => this.setState({

View file

@ -69,7 +69,7 @@ class LoginComplete extends React.Component {
}
startTimer() {
if (this.timer == 0 && this.state.secondsToWait > 0) {
if (this.timer === 0 && this.state.secondsToWait > 0) {
// call function 'countDown' every 1000ms
this.timer = setInterval(this.countDown, 1000);
}
@ -80,7 +80,7 @@ class LoginComplete extends React.Component {
this.setState({secondsToWait: seconds});
// waiting time over, stop counting down
if (seconds == 0) {
if (seconds === 0) {
clearInterval(this.timer);
}
}
@ -90,11 +90,11 @@ class LoginComplete extends React.Component {
this.stopTimer();
return (<Redirect to="/home" />);
}
else if (this.state.secondsToWait == 0) {
else if (this.state.secondsToWait === 0) {
this.stopTimer();
return (<Redirect to="/login" />);
} else {
return <div class="verticalhorizontal">
return <div className="verticalhorizontal">
<img
style={{height: 300}}
src={require('../img/dog-waiting-bw.jpg').default}