diff --git a/package-lock.json b/package-lock.json index fadde89b741a92aa92781327aef5cc55dd11c6e6..348a3895a2b400d953369316e26ff9c978fb7f32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7091,6 +7091,19 @@ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -7101,6 +7114,14 @@ "minimalistic-crypto-utils": "^1.0.1" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -10059,6 +10080,15 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, + "mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + } + }, "mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -12605,6 +12635,52 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz", "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, "react-scripts": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.0.tgz", @@ -13091,6 +13167,11 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -14825,6 +14906,16 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -15304,6 +15395,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -15412,6 +15508,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -15429,6 +15526,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -15459,6 +15557,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -15470,6 +15569,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -15516,6 +15616,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -15524,6 +15625,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -15533,12 +15635,14 @@ "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "optional": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -15594,6 +15698,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" diff --git a/package.json b/package.json index 218c7d3364fef4fdc97ebdbbb7e97eb655f6c699..54ff5ef0fb5fcc55943c50eec78a5394e06c02ee 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "react": "^17.0.1", "react-bootstrap": "1.4.0", "react-dom": "^17.0.1", + "react-router-dom": "5.2.0", "react-scripts": "4.0.0", "web-vitals": "^0.2.4" }, diff --git a/src/App.js b/src/App.js index 2fd6ddd33c2355cc4ba9775916c298fc58cee98a..0112328906569fd7578caf3e9e28c8e0f3905934 100644 --- a/src/App.js +++ b/src/App.js @@ -1,14 +1,16 @@ import React from "react"; -import experimentsService from "./services/proxy/experiments.js"; +import { HashRouter, Switch, Route } from "react-router-dom"; + +import ExperimentsService from "./services/proxy/experiments.js"; import EntryPage from "./components/entry-page/entry-page.js"; -import ExperimentContainer from "./components/experiment-list/experiment-list.js"; +import ExperimentList from "./components/experiment-list/experiment-list.js"; class App extends React.Component { async componentDidMount() { try { - const experiments = await experimentsService.getExperiments(); + const experiments = await ExperimentsService.getExperiments(); console.log(experiments); } catch (error) { console.error(`Failed to fetch the list of experiments. Error: ${error}`); @@ -17,10 +19,20 @@ class App extends React.Component { render() { return ( - <React.Fragment> + /*<React.Fragment> <EntryPage /> <ExperimentContainer /> - </React.Fragment> + </React.Fragment>*/ + <HashRouter> + <Switch> + <Route path="/experiments-overview"> + <ExperimentList /> + </Route> + <Route path="/"> + <EntryPage /> + </Route> + </Switch> + </HashRouter> ); } } diff --git a/src/components/entry-page/entry-page.js b/src/components/entry-page/entry-page.js index df6e9630a0be3c023308ce7bc1d4b67cf49e0cb2..3c6d1e5d60c2dce71f582c434bd32d218cc1e83c 100644 --- a/src/components/entry-page/entry-page.js +++ b/src/components/entry-page/entry-page.js @@ -1,17 +1,22 @@ -import React from 'react'; +import React from "react"; +import { Link } from "react-router-dom"; -import UserMenu from '../user-menu/user-menu.js'; +import UserMenu from "../user-menu/user-menu.js"; -import './entry-page.css'; -import PlaceholderImage from '../../assets/images/Artificial_Intelligence_2.jpg'; +import "./entry-page.css"; +import PlaceholderImage from "../../assets/images/Artificial_Intelligence_2.jpg"; export default class EntryPage extends React.Component { render() { return ( <div className="entry-page"> <header className="entry-page-header"> - <div>HOME</div> - <div>EXPERIMENTS</div> + <div> + <Link to="/">HOME</Link> + </div> + <div> + <Link to="/experiments-overview">EXPERIMENTS</Link> + </div> <a href="https://neurorobotics.net/" target="_blank" @@ -20,7 +25,7 @@ export default class EntryPage extends React.Component { > NEUROROBOTICS.AI </a> - <UserMenu user={this.user} /> + <UserMenu /> </header> <div className="entry-page-banner"> diff --git a/src/components/experiment-list/experiment-list-element.js b/src/components/experiment-list/experiment-list-element.js new file mode 100644 index 0000000000000000000000000000000000000000..23cf8dadc40aa26cc8238fd5db715cb74a8d148a --- /dev/null +++ b/src/components/experiment-list/experiment-list-element.js @@ -0,0 +1,11 @@ +import React from "react"; + +export default class ExperimentListElement extends React.Component { + render() { + return ( + <div className="experiment-box"> + {this.props.experiment && this.props.experiment.id} + </div> + ); + } +} diff --git a/src/components/experiment-list/experiment-list.js b/src/components/experiment-list/experiment-list.js index 4bb6ea96a4189e871a022f057cac1060133a8022..91ada29f48cee9e62fa06afc33c591966f10e1f9 100644 --- a/src/components/experiment-list/experiment-list.js +++ b/src/components/experiment-list/experiment-list.js @@ -1,68 +1,52 @@ -import React from 'react'; -import experimentsService from '../../services/proxy/experiments.js'; +import React from "react"; +import experimentsService from "../../services/proxy/experiments.js"; -class ExperimentBox extends React.Component { - render() { - return ( - <div className="experiment-box"> - {this.props.value} - </div> - ); - } -} +import ExperimentListElement from "./experiment-list-element.js"; -class ExperimentList extends React.Component { - constructor(props) { - super(props); - this.state = { - experiments : null, - } - } - async componentDidMount() { - // replace the token here with a token found in your database in ~/.opt/nrpStorage/FS_db/users for testing - try { - const experiments = await experimentsService.getExperiments('27f3988c-ccfe-4519-921c-b804a966d708'); - this.setState({ - experiments : experiments, - }); - } - catch (error) { - console.error(`Failed to fetch the list of experiments. Error: ${error}`); - } - } - renderExperiment(experiment) { - return ( - <li key={experiment.configuration.id}> - <ExperimentBox - value={experiment.configuration.name} - /> - </li> - ); - } - render() { - if (this.state.experiments){ - return(this.state.experiments.then(file => { - file.forEach(experiment => { - this.renderExperiment(experiment); - }) - }) - ); - } else { - return null; - } +export default class ExperimentList extends React.Component { + constructor(props) { + super(props); + this.state = { + experiments: [], + }; + } + + async componentDidMount() { + // replace the token here with a token found in your database in ~/.opt/nrpStorage/FS_db/users for testing + try { + const experiments = await experimentsService.getExperiments(); + this.setState({ + experiments: experiments, + }); + } catch (error) { + console.error(`Failed to fetch the list of experiments. Error: ${error}`); } + } + + render() { + /*if (this.state.experiments) { + return this.state.experiments.then((file) => { + file.forEach((experiment) => { + this.renderExperiment(experiment); + }); + }); + } else { + return null; + }*/ + return <ExperimentListElement experiment={this.state.experiments[0]} />; + } } -export default class ExperimentContainer extends React.Component { - render (){ - return( - <div className='experiment-container'> - <div className="experiment-list"> - <ol> - <ExperimentList/> - </ol> - </div> +/*export default class ExperimentContainer extends React.Component { + render() { + return ( + <div className="experiment-container"> + <div className="experiment-list"> + <ol> + <ExperimentList /> + </ol> </div> - ); - } -} \ No newline at end of file + </div> + ); + } +}*/ diff --git a/src/components/user-menu/user-menu.js b/src/components/user-menu/user-menu.js index bd16e533a10009b9f2441cf935957cf103dd9da0..fddf9b734b7887d623cad7711a31bd56e2170a19 100644 --- a/src/components/user-menu/user-menu.js +++ b/src/components/user-menu/user-menu.js @@ -1,31 +1,29 @@ -import React from 'react'; -import Dropdown from 'react-bootstrap/Dropdown'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import { faUserCircle, faSignOutAlt } from '@fortawesome/free-solid-svg-icons'; +import React from "react"; +import Dropdown from "react-bootstrap/Dropdown"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faUserCircle, faSignOutAlt } from "@fortawesome/free-solid-svg-icons"; -import NrpUserService from '../../services/proxy/nrp-user-service.js'; -import AuthenticationService from '../../services/authentication-service.js'; +import NrpUserService from "../../services/proxy/nrp-user-service.js"; +import AuthenticationService from "../../services/authentication-service.js"; -import './user-menu.css'; +import "./user-menu.css"; export default class UserMenu extends React.Component { constructor() { super(); this.state = { - user: null + user: null, }; } componentDidMount() { - this._userRequest = NrpUserService.getCurrentUser().then( - currentUser => { - this._userRequest = null; - this.setState(() => ({ - user: currentUser - })); - } - ); + this._userRequest = NrpUserService.getCurrentUser().then((currentUser) => { + this._userRequest = null; + this.setState(() => ({ + user: currentUser, + })); + }); } componentWillUnmount() { @@ -43,14 +41,24 @@ export default class UserMenu extends React.Component { return ( <div className="user-menu-wrapper"> <Dropdown> - <Dropdown.Toggle className="dropdown-toggle" variant="success" id="dropdown-basic"> + <Dropdown.Toggle + className="dropdown-toggle" + variant="success" + id="dropdown-basic" + > <FontAwesomeIcon icon={faUserCircle} className="user-icon" /> - <div className="user-name">{this.state.user ? this.state.user.displayName : 'pending ...'}</div> + <div className="user-name"> + {this.state.user ? this.state.user.displayName : "pending ..."} + </div> </Dropdown.Toggle> <Dropdown.Menu className="dropdown-menu"> - <Dropdown.Item className="dropdown-item" onClick={this.onClickLogout}> - <FontAwesomeIcon icon={faSignOutAlt} className="user-icon" />Logout + <Dropdown.Item + className="dropdown-item" + onClick={this.onClickLogout} + > + <FontAwesomeIcon icon={faSignOutAlt} className="user-icon" /> + Logout </Dropdown.Item> </Dropdown.Menu> </Dropdown>