From 4397a959e806bf476be4c81bc804616adf58b969 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 12 May 2021 22:42:12 +0200 Subject: ui: Migrate from CRA to Next.js This change updates the web frontend to use Next.js instead of Create React App (CRA). Next.js enables the possibility of rendering pages on the server side (which reduces the time to first frame) and overall provides a better development experience. Future commits will try to futher optimize the implementation for Next.js. --- .../app/sidebars/project/ScenarioListComponent.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js') diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js index e775a663..4efa99ef 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types' import React from 'react' import Shapes from '../../../../shapes' -import { Link } from 'react-router-dom' +import Link from 'next/link' import FontAwesome from 'react-fontawesome' class ScenarioListComponent extends React.Component { @@ -34,10 +34,13 @@ class ScenarioListComponent extends React.Component {
this.props.onChooseScenario(scenario.portfolioId, scenario._id)} - /> + href={`/projects/${this.props.currentProjectId}/portfolios/${scenario.portfolioId}/scenarios/${scenario._id}`} + > + this.props.onChooseScenario(scenario.portfolioId, scenario._id)} + /> + (idx !== 0 ? this.onDelete(scenario._id) : undefined)} -- cgit v1.2.3 From 24147cba0f5723be3525e8f40d1954144841629b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 13 May 2021 13:00:00 +0200 Subject: ui: Address technical dept in frontend --- .../app/sidebars/project/ScenarioListComponent.js | 105 ++++++++++----------- 1 file changed, 52 insertions(+), 53 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js') diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js index 4efa99ef..26543d12 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js @@ -1,65 +1,64 @@ import PropTypes from 'prop-types' import React from 'react' -import Shapes from '../../../../shapes' +import { Scenario } from '../../../../shapes' import Link from 'next/link' import FontAwesome from 'react-fontawesome' -class ScenarioListComponent extends React.Component { - static propTypes = { - scenarios: PropTypes.arrayOf(Shapes.Scenario), - portfolioId: PropTypes.string, - currentProjectId: PropTypes.string.isRequired, - currentScenarioId: PropTypes.string, - onNewScenario: PropTypes.func.isRequired, - onChooseScenario: PropTypes.func.isRequired, - onDeleteScenario: PropTypes.func.isRequired, - } - - onDelete(id) { - this.props.onDeleteScenario(id) - } - - render() { - return ( - <> - {this.props.scenarios.map((scenario, idx) => ( -
-
- {scenario.name} -
-
- - this.props.onChooseScenario(scenario.portfolioId, scenario._id)} - /> - - (idx !== 0 ? this.onDelete(scenario._id) : undefined)} - /> -
-
- ))} -
+function ScenarioListComponent({ + scenarios, + portfolioId, + currentProjectId, + currentScenarioId, + onNewScenario, + onChooseScenario, + onDeleteScenario, +}) { + return ( + <> + {scenarios.map((scenario, idx) => ( +
this.props.onNewScenario(this.props.portfolioId)} + className={ + 'col-7 pl-5 align-self-center ' + + (scenario._id === currentScenarioId ? 'font-weight-bold' : '') + } > - - New scenario + {scenario.name}
+
+ + onChooseScenario(scenario.portfolioId, scenario._id)} + /> + + (idx !== 0 ? onDeleteScenario(scenario._id) : undefined)} + /> +
+
+ ))} +
+
onNewScenario(this.props.portfolioId)}> + + New scenario
- - ) - } +
+ + ) +} + +ScenarioListComponent.propTypes = { + scenarios: PropTypes.arrayOf(Scenario), + portfolioId: PropTypes.string, + currentProjectId: PropTypes.string.isRequired, + currentScenarioId: PropTypes.string, + onNewScenario: PropTypes.func.isRequired, + onChooseScenario: PropTypes.func.isRequired, + onDeleteScenario: PropTypes.func.isRequired, } export default ScenarioListComponent -- cgit v1.2.3 From 1edbae1a0224e30bafb98638f419e1f967a9286f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 13 May 2021 17:42:53 +0200 Subject: ui: Move modal state outside of Redux This change updates the frontend so that the modal state is not stored inside Redux but instead is stored using the useState hook. This simplifies the design of the modal components. --- .../app/sidebars/project/ScenarioListComponent.js | 40 +++++++++++++--------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js') diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js index 26543d12..168b8e02 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js @@ -3,6 +3,8 @@ import React from 'react' import { Scenario } from '../../../../shapes' import Link from 'next/link' import FontAwesome from 'react-fontawesome' +import { Button, Col, Row } from 'reactstrap' +import classNames from 'classnames' function ScenarioListComponent({ scenarios, @@ -16,36 +18,42 @@ function ScenarioListComponent({ return ( <> {scenarios.map((scenario, idx) => ( -
-
+ {scenario.name} -
-
+ + - onChooseScenario(scenario.portfolioId, scenario._id)} /> - (idx !== 0 ? onDeleteScenario(scenario._id) : undefined)} /> -
-
+ + ))}
-
onNewScenario(this.props.portfolioId)}> +
+
) -- cgit v1.2.3 From 53623fad76274e39206b8e073e371775ea96946b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 17 May 2021 12:16:10 +0200 Subject: ui: Migrate to FontAwesome 5 React library This change updates the frontend to use the FontAwesome 5 React library that renders SVG icons as opposed to CSS icon fonts. This migration resolves a couple of issues we had with server-side rendering of the previous FontAwesome icons. --- .../app/sidebars/project/ScenarioListComponent.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js') diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js index 168b8e02..131a00b5 100644 --- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js @@ -2,9 +2,10 @@ import PropTypes from 'prop-types' import React from 'react' import { Scenario } from '../../../../shapes' import Link from 'next/link' -import FontAwesome from 'react-fontawesome' import { Button, Col, Row } from 'reactstrap' import classNames from 'classnames' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faPlus, faPlay, faTrash } from '@fortawesome/free-solid-svg-icons' function ScenarioListComponent({ scenarios, @@ -35,23 +36,26 @@ function ScenarioListComponent({ color="primary" outline disabled - className="mr-1 fa fa-play" + className="mr-1" onClick={() => onChooseScenario(scenario.portfolioId, scenario._id)} - /> + > + + ))}
-- cgit v1.2.3