summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-ui/src')
-rw-r--r--opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js29
-rw-r--r--opendc-web/opendc-web-ui/src/components/home/ContactSection.js44
-rw-r--r--opendc-web/opendc-web-ui/src/components/home/ContentSection.js13
-rw-r--r--opendc-web/opendc-web-ui/src/components/home/IntroSection.js21
-rw-r--r--opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js13
-rw-r--r--opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js18
-rw-r--r--opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js21
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js13
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js33
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js44
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js20
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js27
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js29
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js19
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js14
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js19
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js13
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js45
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js63
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js43
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js42
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js9
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js68
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js74
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js23
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js16
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js20
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js20
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js16
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js13
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js21
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js14
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js21
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js13
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js13
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js32
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js31
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js20
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/auth/Login.js64
-rw-r--r--opendc-web/opendc-web-ui/src/containers/auth/Logout.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js13
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js43
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js42
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js44
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js43
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js57
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js51
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js40
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js31
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js85
-rw-r--r--opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js70
-rw-r--r--opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js14
-rw-r--r--opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js18
-rw-r--r--opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js12
-rw-r--r--opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js17
-rw-r--r--opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js26
-rw-r--r--opendc-web/opendc-web-ui/src/pages/App.js168
-rw-r--r--opendc-web/opendc-web-ui/src/pages/Home.js4
-rw-r--r--opendc-web/opendc-web-ui/src/pages/NotFound.js11
-rw-r--r--opendc-web/opendc-web-ui/src/pages/Profile.js22
-rw-r--r--opendc-web/opendc-web-ui/src/pages/Projects.js49
-rw-r--r--opendc-web/opendc-web-ui/src/shortcuts/keymap.js10
-rw-r--r--opendc-web/opendc-web-ui/src/util/hooks.js29
74 files changed, 979 insertions, 1135 deletions
diff --git a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js
index 2cd0ed6e..7ca10792 100644
--- a/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js
+++ b/opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js
@@ -1,6 +1,6 @@
import React from 'react'
+import { HotKeys } from 'react-hotkeys'
import { Stage } from 'react-konva'
-import { Shortcuts } from 'react-shortcuts'
import MapLayer from '../../../containers/app/map/layers/MapLayer'
import ObjectHoverLayer from '../../../containers/app/map/layers/ObjectHoverLayer'
import RoomHoverLayer from '../../../containers/app/map/layers/RoomHoverLayer'
@@ -46,7 +46,6 @@ class MapStageComponent extends React.Component {
}
updateScale(e) {
- e.preventDefault()
this.props.zoomInOnPosition(e.deltaY < 0, this.state.mouseX, this.state.mouseY)
}
@@ -55,23 +54,11 @@ class MapStageComponent extends React.Component {
this.setState({ mouseX: mousePos.x, mouseY: mousePos.y })
}
- handleShortcuts(action) {
- switch (action) {
- case 'MOVE_LEFT':
- this.moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0)
- break
- case 'MOVE_RIGHT':
- this.moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0)
- break
- case 'MOVE_UP':
- this.moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT)
- break
- case 'MOVE_DOWN':
- this.moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT)
- break
- default:
- break
- }
+ handlers = {
+ MOVE_LEFT: () => this.moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0),
+ MOVE_RIGHT: () => this.moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0),
+ MOVE_UP: () => this.moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT),
+ MOVE_DOWN: () => this.moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT),
}
moveWithDelta(deltaX, deltaY) {
@@ -80,7 +67,7 @@ class MapStageComponent extends React.Component {
render() {
return (
- <Shortcuts name="MAP" handler={this.handleShortcuts.bind(this)} targetNodeSelector="body">
+ <HotKeys handlers={this.handlers}>
<Stage
ref={(stage) => {
this.stage = stage
@@ -95,7 +82,7 @@ class MapStageComponent extends React.Component {
<ObjectHoverLayer mouseX={this.state.mouseX} mouseY={this.state.mouseY} />
</Provider>
</Stage>
- </Shortcuts>
+ </HotKeys>
)
}
}
diff --git a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js
index d5c6e55f..d25a1bc4 100644
--- a/opendc-web/opendc-web-ui/src/components/home/ContactSection.js
+++ b/opendc-web/opendc-web-ui/src/components/home/ContactSection.js
@@ -1,42 +1,44 @@
import React from 'react'
import FontAwesome from 'react-fontawesome'
-import './ContactSection.sass'
+import { Row, Col } from 'reactstrap'
import ContentSection from './ContentSection'
+import './ContactSection.sass'
+
const ContactSection = () => (
- <ContentSection name="contact" title="Contact">
- <div className="row justify-content-center">
- <div className="col-4">
+ <ContentSection name="contact" title="Contact" className="contact-section">
+ <Row className="justify-content-center">
+ <Col md="4">
<a href="https://github.com/atlarge-research/opendc">
<FontAwesome name="github" size="3x" className="mb-2" />
<div className="w-100" />
atlarge-research/opendc
</a>
- </div>
- <div className="col-4">
+ </Col>
+ <Col md="4">
<a href="mailto:opendc@atlarge-research.com">
<FontAwesome name="envelope" size="3x" className="mb-2" />
<div className="w-100" />
opendc@atlarge-research.com
</a>
- </div>
- </div>
- <div className="row">
- <div className="col text-center">
- <img src="img/tudelft-icon.png" className="img-fluid tudelft-icon" alt="TU Delft" />
- </div>
- </div>
- <div className="row">
- <div className="col text-center">
+ </Col>
+ </Row>
+ <Row>
+ <Col className="text-center">
+ <img src="img/tudelft-icon.png" className="img-fluid tudelft-icon" height="100" alt="TU Delft" />
+ </Col>
+ </Row>
+ <Row>
+ <Col className="text-center">
A project by the &nbsp;
<a href="http://atlarge.science" target="_blank" rel="noopener noreferrer">
<strong>@Large Research Group</strong>
</a>
.
- </div>
- </div>
- <div className="row">
- <div className="col text-center disclaimer mt-5 small">
+ </Col>
+ </Row>
+ <Row>
+ <Col className="text-center disclaimer mt-5 small">
<FontAwesome name="exclamation-triangle" size="2x" className="mr-2" />
<br />
<strong>Disclaimer: </strong>
@@ -47,8 +49,8 @@ const ContactSection = () => (
<a href="https://github.com/atlarge-research/opendc/blob/master/LICENSE.txt">license</a>
</strong>
). Sorry for the inconvenience.
- </div>
- </div>
+ </Col>
+ </Row>
</ContentSection>
)
diff --git a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js
index 9d4832d9..3a8960d9 100644
--- a/opendc-web/opendc-web-ui/src/components/home/ContentSection.js
+++ b/opendc-web/opendc-web-ui/src/components/home/ContentSection.js
@@ -1,15 +1,16 @@
+import React from 'react'
import classNames from 'classnames'
+import { Container } from 'reactstrap'
import PropTypes from 'prop-types'
-import React from 'react'
import './ContentSection.sass'
-const ContentSection = ({ name, title, children }) => (
- <div id={name} className={classNames(name + '-section', 'content-section')}>
- <div className="container">
+const ContentSection = ({ name, title, children, className }) => (
+ <section id={name} className={classNames(className, name + '-section', 'content-section')}>
+ <Container>
<h1>{title}</h1>
{children}
- </div>
- </div>
+ </Container>
+ </section>
)
ContentSection.propTypes = {
diff --git a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js
index a799272a..bc6ee83b 100644
--- a/opendc-web/opendc-web-ui/src/components/home/IntroSection.js
+++ b/opendc-web/opendc-web-ui/src/components/home/IntroSection.js
@@ -1,18 +1,19 @@
import React from 'react'
+import { Container, Row, Col } from 'reactstrap'
const IntroSection = () => (
<section id="intro" className="intro-section">
- <div className="container pt-5 pb-3">
- <div className="row justify-content-center">
- <div className="col-xl-4 col-lg-4 col-md-4 col-sm-8 col-8">
+ <Container className="pt-5 pb-3">
+ <Row className="justify-content-center">
+ <Col xl="4" lg="4" md="4" sm="8">
<h4>The datacenter (DC) industry...</h4>
<ul>
<li>Is worth over $15 bn, and growing</li>
<li>Has many hard-to-grasp concepts</li>
<li>Needs to become accessible to many</li>
</ul>
- </div>
- <div className="col-xl-4 col-lg-4 col-md-4 col-sm-8 col-8">
+ </Col>
+ <Col xl="4" lg="4" md="4" sm="8">
<img
src="img/datacenter-drawing.png"
className="col-12 img-fluid"
@@ -23,17 +24,17 @@ const IntroSection = () => (
Image source
</a>
</p>
- </div>
- <div className="col-xl-4 col-lg-4 col-md-4 col-sm-8 col-8">
+ </Col>
+ <Col xl="4" lg="4" md="4" sm="8">
<h4>OpenDC provides...</h4>
<ul>
<li>Collaborative online DC modeling</li>
<li>Diverse and effective DC simulation</li>
<li>Exploratory DC performance feedback</li>
</ul>
- </div>
- </div>
- </div>
+ </Col>
+ </Row>
+ </Container>
</section>
)
diff --git a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js
index 263590d5..33aab17f 100644
--- a/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js
+++ b/opendc-web/opendc-web-ui/src/components/home/ScreenshotSection.js
@@ -1,4 +1,3 @@
-import classNames from 'classnames'
import React from 'react'
import { Row, Col } from 'reactstrap'
import ContentSection from './ContentSection'
@@ -7,20 +6,12 @@ import './ScreenshotSection.sass'
const ScreenshotSection = ({ name, title, imageUrl, caption, imageIsRight, children }) => (
<ContentSection name={name} title={title}>
<Row>
- <Col
- xl="5"
- lg="5"
- md="5"
- sm="!2"
- className={classNames('text-left my-auto', {
- 'order-1': !imageIsRight,
- })}
- >
+ <Col xl="5" lg="5" md="5" sm="12" className={`text-left ${!imageIsRight ? 'order-1' : ''}`}>
{children}
</Col>
<Col xl="7" lg="7" md="7" sm="12">
<img src={imageUrl} className="col-12 screenshot" alt={caption} />
- <Row className="text-muted justify-content-center">{caption}</Row>
+ <div className="row text-muted justify-content-center">{caption}</div>
</Col>
</Row>
</ContentSection>
diff --git a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js
index e5ed9683..1624b4d2 100644
--- a/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js
+++ b/opendc-web/opendc-web-ui/src/components/home/StakeholderSection.js
@@ -1,29 +1,35 @@
import React from 'react'
+import { Row, Col } from 'reactstrap'
import ContentSection from './ContentSection'
const Stakeholder = ({ name, title, subtitle }) => (
- <div className="col-xl-4 col-lg-4 col-md-4 col-sm-6 col-6">
- <img
+ <Col xl="4" lg="4" md="4" sm="6">
+ <Col
+ tag="img"
+ xl="3"
+ lg="3"
+ md="4"
+ sm="4"
src={'img/stakeholders/' + name + '.png'}
- className="col-xl-3 col-lg-4 col-md-4 col-sm-4 col-4 img-fluid"
+ className="img-fluid"
alt={title}
/>
<div className="text-center mt-2">
<h4>{title}</h4>
<p>{subtitle}</p>
</div>
- </div>
+ </Col>
)
const StakeholderSection = () => (
<ContentSection name="stakeholders" title="Stakeholders">
- <div className="row justify-content-center">
+ <Row className="justify-content-center">
<Stakeholder name="Manager" title="Managers" subtitle="Seeing is deciding" />
<Stakeholder name="Sales" title="Sales" subtitle="Demo concepts" />
<Stakeholder name="Developer" title="DevOps" subtitle="Develop & tune" />
<Stakeholder name="Researcher" title="Researchers" subtitle="Understand & design" />
<Stakeholder name="Student" title="Students" subtitle="Grasp complex concepts" />
- </div>
+ </Row>
</ContentSection>
)
diff --git a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js
index c6013c71..efd77edf 100644
--- a/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js
+++ b/opendc-web/opendc-web-ui/src/components/home/TechnologiesSection.js
@@ -1,39 +1,40 @@
import React from 'react'
import FontAwesome from 'react-fontawesome'
+import { ListGroup, ListGroupItem } from 'reactstrap'
import ContentSection from './ContentSection'
const TechnologiesSection = () => (
<ContentSection name="technologies" title="Technologies">
- <ul className="list-group text-left">
- <li className="d-flex list-group-item justify-content-between align-items-center list-group-item-primary">
+ <ListGroup className="list-group text-left">
+ <ListGroupItem color="primary" className="d-flex justify-content-between align-items-center">
<span style={{ minWidth: 100 }}>
<FontAwesome name="window-maximize" className="mr-2" />
<strong className="">Browser</strong>
</span>
<span className="text-right">JavaScript, React, Redux, Konva</span>
- </li>
- <li className="d-flex list-group-item justify-content-between align-items-center list-group-item-warning">
+ </ListGroupItem>
+ <ListGroupItem color="warning" className="d-flex justify-content-between align-items-center">
<span style={{ minWidth: 100 }}>
<FontAwesome name="television" className="mr-2" />
<strong>Server</strong>
</span>
<span className="text-right">Python, Flask, FlaskSocketIO, OpenAPI</span>
- </li>
- <li className="d-flex list-group-item justify-content-between align-items-center list-group-item-success">
+ </ListGroupItem>
+ <ListGroupItem color="success" className="d-flex justify-content-between align-items-center">
<span style={{ minWidth: 100 }}>
<FontAwesome name="database" className="mr-2" />
<strong>Database</strong>
</span>
<span className="text-right">MongoDB</span>
- </li>
- <li className="d-flex list-group-item justify-content-between align-items-center list-group-item-danger">
+ </ListGroupItem>
+ <ListGroupItem color="danger" className="d-flex justify-content-between align-items-center">
<span style={{ minWidth: 100 }}>
<FontAwesome name="cogs" className="mr-2" />
<strong>Simulator</strong>
</span>
<span className="text-right">Kotlin</span>
- </li>
- </ul>
+ </ListGroupItem>
+ </ListGroup>
</ContentSection>
)
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js
index 9e4a6969..651b3459 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js
@@ -1,13 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { goDownOneInteractionLevel } from '../../../actions/interaction-level'
import GrayLayer from '../../../components/app/map/elements/GrayLayer'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(goDownOneInteractionLevel()),
- }
+const GrayContainer = () => {
+ const dispatch = useDispatch()
+ const onClick = () => dispatch(goDownOneInteractionLevel())
+ return <GrayLayer onClick={onClick} />
}
-const GrayContainer = connect(undefined, mapDispatchToProps)(GrayLayer)
-
export default GrayContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js
index 23c920b6..61d123e8 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js
@@ -1,22 +1,23 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../actions/map'
import MapStageComponent from '../../../components/app/map/MapStageComponent'
-const mapStateToProps = (state) => {
- return {
- mapPosition: state.map.position,
- mapDimensions: state.map.dimensions,
- }
+const MapStage = () => {
+ const { position, dimensions } = useSelector((state) => state.map)
+ const dispatch = useDispatch()
+ const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y))
+ const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y))
+ const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height))
+ return (
+ <MapStageComponent
+ mapPosition={position}
+ mapDimensions={dimensions}
+ zoomInOnPosition={zoomInOnPositionA}
+ setMapPositionWithBoundsCheck={setMapPositionWithBoundsCheckA}
+ setMapDimensions={setMapDimensionsA}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- zoomInOnPosition: (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)),
- setMapPositionWithBoundsCheck: (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)),
- setMapDimensions: (width, height) => dispatch(setMapDimensions(width, height)),
- }
-}
-
-const MapStage = connect(mapStateToProps, mapDispatchToProps)(MapStageComponent)
-
export default MapStage
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js
index 40077608..e5af5117 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js
@@ -1,12 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import RackGroup from '../../../components/app/map/groups/RackGroup'
-const mapStateToProps = (state) => {
- return {
- interactionLevel: state.interactionLevel,
- }
+const RackContainer = ({ tile }) => {
+ const interactionLevel = useSelector((state) => state.interactionLevel)
+ return <RackGroup interactionLeve={interactionLevel} tile={tile} />
}
-const RackContainer = connect(mapStateToProps)(RackGroup)
-
export default RackContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js
index 53746271..00d3152f 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js
@@ -1,26 +1,32 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import RackFillBar from '../../../components/app/map/elements/RackFillBar'
-const mapStateToProps = (state, ownProps) => {
- let energyConsumptionTotal = 0
- const rack = state.objects.rack[state.objects.tile[ownProps.tileId].rackId]
- const machineIds = rack.machineIds
- machineIds.forEach((machineId) => {
- if (machineId !== null) {
- const machine = state.objects.machine[machineId]
- machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW))
- machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW))
- machine.memoryIds.forEach((id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW))
- machine.storageIds.forEach((id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW))
+const RackSpaceFillContainer = (props) => {
+ const state = useSelector((state) => {
+ let energyConsumptionTotal = 0
+ const rack = state.objects.rack[state.objects.tile[props.tileId].rackId]
+ const machineIds = rack.machineIds
+ machineIds.forEach((machineId) => {
+ if (machineId !== null) {
+ const machine = state.objects.machine[machineId]
+ machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW))
+ machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW))
+ machine.memoryIds.forEach(
+ (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW)
+ )
+ machine.storageIds.forEach(
+ (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW)
+ )
+ }
+ })
+
+ return {
+ type: 'energy',
+ fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW),
}
})
-
- return {
- type: 'energy',
- fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW),
- }
+ return <RackFillBar {...props} {...state} />
}
-const RackSpaceFillContainer = connect(mapStateToProps)(RackFillBar)
-
export default RackSpaceFillContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js
index 0509a5a5..dc5119fd 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js
@@ -1,14 +1,16 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import RackFillBar from '../../../components/app/map/elements/RackFillBar'
-const mapStateToProps = (state, ownProps) => {
- const machineIds = state.objects.rack[state.objects.tile[ownProps.tileId].rackId].machineIds
- return {
- type: 'space',
- fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length,
- }
+const RackSpaceFillContainer = (props) => {
+ const state = useSelector((state) => {
+ const machineIds = state.objects.rack[state.objects.tile[props.tileId].rackId].machineIds
+ return {
+ type: 'space',
+ fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length,
+ }
+ })
+ return <RackFillBar {...props} {...state} />
}
-const RackSpaceFillContainer = connect(mapStateToProps)(RackFillBar)
-
export default RackSpaceFillContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js
index 91bf4e5d..877233fc 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js
@@ -1,21 +1,18 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { goFromBuildingToRoom } from '../../../actions/interaction-level'
import RoomGroup from '../../../components/app/map/groups/RoomGroup'
-const mapStateToProps = (state, ownProps) => {
- return {
- interactionLevel: state.interactionLevel,
- currentRoomInConstruction: state.construction.currentRoomInConstruction,
- room: state.objects.room[ownProps.roomId],
- }
+const RoomContainer = (props) => {
+ const state = useSelector((state) => {
+ return {
+ interactionLevel: state.interactionLevel,
+ currentRoomInConstruction: state.construction.currentRoomInConstruction,
+ room: state.objects.room[props.roomId],
+ }
+ })
+ const dispatch = useDispatch()
+ return <RoomGroup {...props} {...state} onClick={() => dispatch(goFromBuildingToRoom(props.roomId))} />
}
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onClick: () => dispatch(goFromBuildingToRoom(ownProps.roomId)),
- }
-}
-
-const RoomContainer = connect(mapStateToProps, mapDispatchToProps)(RoomGroup)
-
export default RoomContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js
index 04d6c8d6..ad7301a7 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js
@@ -1,26 +1,19 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { goFromRoomToRack } from '../../../actions/interaction-level'
import TileGroup from '../../../components/app/map/groups/TileGroup'
-const mapStateToProps = (state, ownProps) => {
- const tile = state.objects.tile[ownProps.tileId]
+const TileContainer = (props) => {
+ const interactionLevel = useSelector((state) => state.interactionLevel)
+ const tile = useSelector((state) => state.objects.tile[props.tileId])
- return {
- interactionLevel: state.interactionLevel,
- tile,
+ const dispatch = useDispatch()
+ const onClick = (tile) => {
+ if (tile.rackId) {
+ dispatch(goFromRoomToRack(tile._id))
+ }
}
+ return <TileGroup {...props} onClick={onClick} tile={tile} interactionLevel={interactionLevel} />
}
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: (tile) => {
- if (tile.rackId) {
- dispatch(goFromRoomToRack(tile._id))
- }
- },
- }
-}
-
-const TileContainer = connect(mapStateToProps, mapDispatchToProps)(TileGroup)
-
export default TileContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js
index de43a151..612ca41c 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js
@@ -1,17 +1,14 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import TopologyGroup from '../../../components/app/map/groups/TopologyGroup'
-const mapStateToProps = (state) => {
- if (state.currentTopologyId === '-1') {
- return {}
- }
+const TopologyContainer = () => {
+ const topology = useSelector(
+ (state) => state.currentTopologyId !== '-1' && state.objects.topology[state.currentTopologyId]
+ )
+ const interactionLevel = useSelector((state) => state.interactionLevel)
- return {
- topology: state.objects.topology[state.currentTopologyId],
- interactionLevel: state.interactionLevel,
- }
+ return <TopologyGroup topology={topology} interactionLevel={interactionLevel} />
}
-const TopologyContainer = connect(mapStateToProps)(TopologyGroup)
-
export default TopologyContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js
index 67f8a242..2a469860 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js
@@ -1,12 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import WallGroup from '../../../components/app/map/groups/WallGroup'
-const mapStateToProps = (state, ownProps) => {
- return {
- tiles: state.objects.room[ownProps.roomId].tileIds.map((tileId) => state.objects.tile[tileId]),
- }
+const WallContainer = (props) => {
+ const tiles = useSelector((state) =>
+ state.objects.room[props.roomId].tileIds.map((tileId) => state.objects.tile[tileId])
+ )
+ return <WallGroup {...props} tiles={tiles} />
}
-const WallContainer = connect(mapStateToProps)(WallGroup)
-
export default WallContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js
index fa3b9d22..e9d58b9f 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js
@@ -1,12 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent'
-const mapStateToProps = (state) => {
- return {
- scale: state.map.scale,
- }
+const ScaleIndicatorContainer = (props) => {
+ const scale = useSelector((state) => state.map.scale)
+ return <ScaleIndicatorComponent {...props} scale={scale} />
}
-const ScaleIndicatorContainer = connect(mapStateToProps)(ScaleIndicatorComponent)
-
export default ScaleIndicatorContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js
index ddc68cc7..a18dfd5b 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js
@@ -1,19 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { zoomInOnCenter } from '../../../../actions/map'
import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent'
-const mapStateToProps = (state) => {
- return {
- mapScale: state.map.scale,
- }
+const ZoomControlContainer = () => {
+ const dispatch = useDispatch()
+ const scale = useSelector((state) => state.map.scale)
+ return <ZoomControlComponent mapScale={scale} zoomInOnCenter={(zoomIn) => dispatch(zoomInOnCenter(zoomIn))} />
}
-const mapDispatchToProps = (dispatch) => {
- return {
- zoomInOnCenter: (zoomIn) => dispatch(zoomInOnCenter(zoomIn)),
- }
-}
-
-const ZoomControlContainer = connect(mapStateToProps, mapDispatchToProps)(ZoomControlComponent)
-
export default ZoomControlContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js
index 8596cb9c..5f701b4b 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js
@@ -1,13 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent'
-const mapStateToProps = (state) => {
- return {
- mapPosition: state.map.position,
- mapScale: state.map.scale,
- }
+const MapLayer = (props) => {
+ const { position, scale } = useSelector((state) => state.map)
+ return <MapLayerComponent {...props} mapPosition={position} mapScale={scale} />
}
-const MapLayer = connect(mapStateToProps)(MapLayerComponent)
-
export default MapLayer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js
index a4927862..cefdf35c 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js
@@ -1,33 +1,32 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { addRackToTile } from '../../../../actions/topology/room'
import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent'
import { findTileWithPosition } from '../../../../util/tile-calculations'
-const mapStateToProps = (state) => {
- return {
- mapPosition: state.map.position,
- mapScale: state.map.scale,
- isEnabled: () => state.construction.inRackConstructionMode,
- isValid: (x, y) => {
- if (state.interactionLevel.mode !== 'ROOM') {
- return false
- }
+const ObjectHoverLayer = (props) => {
+ const state = useSelector((state) => {
+ return {
+ mapPosition: state.map.position,
+ mapScale: state.map.scale,
+ isEnabled: () => state.construction.inRackConstructionMode,
+ isValid: (x, y) => {
+ if (state.interactionLevel.mode !== 'ROOM') {
+ return false
+ }
- const currentRoom = state.objects.room[state.interactionLevel.roomId]
- const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId])
- const tile = findTileWithPosition(tiles, x, y)
+ const currentRoom = state.objects.room[state.interactionLevel.roomId]
+ const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId])
+ const tile = findTileWithPosition(tiles, x, y)
- return !(tile === null || tile.rackId)
- },
- }
-}
+ return !(tile === null || tile.rackId)
+ },
+ }
+ })
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: (x, y) => dispatch(addRackToTile(x, y)),
- }
+ const dispatch = useDispatch()
+ const onClick = (x, y) => dispatch(addRackToTile(x, y))
+ return <ObjectHoverLayerComponent {...props} {...state} onClick={onClick} />
}
-const ObjectHoverLayer = connect(mapStateToProps, mapDispatchToProps)(ObjectHoverLayerComponent)
-
export default ObjectHoverLayer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js
index 66404f9e..2717d890 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js
@@ -1,4 +1,5 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { toggleTileAtLocation } from '../../../../actions/topology/building'
import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent'
import {
@@ -7,40 +8,38 @@ import {
findPositionInRooms,
} from '../../../../util/tile-calculations'
-const mapStateToProps = (state) => {
- return {
- mapPosition: state.map.position,
- mapScale: state.map.scale,
- isEnabled: () => state.construction.currentRoomInConstruction !== '-1',
- isValid: (x, y) => {
- const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction])
- const oldRooms = Object.keys(state.objects.room)
- .map((id) => Object.assign({}, state.objects.room[id]))
- .filter(
- (room) =>
- state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 &&
- room._id !== state.construction.currentRoomInConstruction
- )
+const RoomHoverLayer = (props) => {
+ const dispatch = useDispatch()
+ const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y))
- ;[...oldRooms, newRoom].forEach((room) => {
- room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId])
- })
- if (newRoom.tileIds.length === 0) {
- return findPositionInRooms(oldRooms, x, y) === -1
- }
+ const state = useSelector((state) => {
+ return {
+ mapPosition: state.map.position,
+ mapScale: state.map.scale,
+ isEnabled: () => state.construction.currentRoomInConstruction !== '-1',
+ isValid: (x, y) => {
+ const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction])
+ const oldRooms = Object.keys(state.objects.room)
+ .map((id) => Object.assign({}, state.objects.room[id]))
+ .filter(
+ (room) =>
+ state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 &&
+ room._id !== state.construction.currentRoomInConstruction
+ )
- const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles)
- return findPositionInPositions(validNextPositions, x, y) !== -1
- },
- }
-}
+ ;[...oldRooms, newRoom].forEach((room) => {
+ room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId])
+ })
+ if (newRoom.tileIds.length === 0) {
+ return findPositionInRooms(oldRooms, x, y) === -1
+ }
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: (x, y) => dispatch(toggleTileAtLocation(x, y)),
- }
+ const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles)
+ return findPositionInPositions(validNextPositions, x, y) !== -1
+ },
+ }
+ })
+ return <RoomHoverLayerComponent onClick={onClick} {...props} {...state} />
}
-const RoomHoverLayer = connect(mapStateToProps, mapDispatchToProps)(RoomHoverLayerComponent)
-
export default RoomHoverLayer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js
index 4b430e54..e60abe18 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js
@@ -1,28 +1,31 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent'
-const mapStateToProps = (state) => {
- if (
- state.currentPortfolioId === '-1' ||
- !state.objects.portfolio[state.currentPortfolioId] ||
- state.objects.portfolio[state.currentPortfolioId].scenarioIds
- .map((scenarioId) => state.objects.scenario[scenarioId])
- .some((s) => s === undefined)
- ) {
+const PortfolioResultsContainer = (props) => {
+ const { scenarios, portfolio } = useSelector((state) => {
+ if (
+ state.currentPortfolioId === '-1' ||
+ !state.objects.portfolio[state.currentPortfolioId] ||
+ state.objects.portfolio[state.currentPortfolioId].scenarioIds
+ .map((scenarioId) => state.objects.scenario[scenarioId])
+ .some((s) => s === undefined)
+ ) {
+ return {
+ portfolio: undefined,
+ scenarios: [],
+ }
+ }
+
return {
- portfolio: undefined,
- scenarios: [],
+ portfolio: state.objects.portfolio[state.currentPortfolioId],
+ scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map(
+ (scenarioId) => state.objects.scenario[scenarioId]
+ ),
}
- }
+ })
- return {
- portfolio: state.objects.portfolio[state.currentPortfolioId],
- scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map(
- (scenarioId) => state.objects.scenario[scenarioId]
- ),
- }
+ return <PortfolioResultsComponent {...props} scenarios={scenarios} portfolio={portfolio} />
}
-const PortfolioResultsContainer = connect(mapStateToProps)(PortfolioResultsComponent)
-
export default PortfolioResultsContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js
index b32c8b1d..86f465b6 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js
@@ -1,28 +1,31 @@
-import { connect } from 'react-redux'
-import { withRouter } from 'react-router-dom'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+import { useHistory } from 'react-router-dom'
import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent'
import { deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios'
import { openNewPortfolioModal } from '../../../../actions/modals/portfolios'
import { getState } from '../../../../util/state-utils'
import { setCurrentTopology } from '../../../../actions/topology/building'
-const mapStateToProps = (state) => {
- let portfolios = state.objects.project[state.currentProjectId]
- ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t])
- : []
- if (portfolios.filter((t) => !t).length > 0) {
- portfolios = []
- }
+const PortfolioListContainer = (props) => {
+ const state = useSelector((state) => {
+ let portfolios = state.objects.project[state.currentProjectId]
+ ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t])
+ : []
+ if (portfolios.filter((t) => !t).length > 0) {
+ portfolios = []
+ }
- return {
- currentProjectId: state.currentProjectId,
- currentPortfolioId: state.currentPortfolioId,
- portfolios,
- }
-}
+ return {
+ currentProjectId: state.currentProjectId,
+ currentPortfolioId: state.currentPortfolioId,
+ portfolios,
+ }
+ })
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
+ const dispatch = useDispatch()
+ const history = useHistory()
+ const actions = {
onNewPortfolio: () => {
dispatch(openNewPortfolioModal())
},
@@ -34,12 +37,11 @@ const mapDispatchToProps = (dispatch, ownProps) => {
const state = await getState(dispatch)
dispatch(deletePortfolio(id))
dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0]))
- ownProps.history.push(`/projects/${state.currentProjectId}`)
+ history.push(`/projects/${state.currentProjectId}`)
}
},
}
+ return <PortfolioListComponent {...props} {...state} {...actions} />
}
-const PortfolioListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(PortfolioListComponent))
-
export default PortfolioListContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js
index 49001099..35e6c52b 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js
@@ -1,10 +1,11 @@
import React from 'react'
-import { withRouter } from 'react-router-dom'
+import { useLocation } from 'react-router-dom'
import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent'
import { isCollapsible } from '../../../../util/sidebar-space'
-const ProjectSidebarContainer = withRouter(({ location, ...props }) => (
- <ProjectSidebarComponent collapsible={isCollapsible(location)} {...props} />
-))
+const ProjectSidebarContainer = (props) => {
+ const location = useLocation()
+ return <ProjectSidebarComponent collapsible={isCollapsible(location)} {...props} />
+}
export default ProjectSidebarContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js
index 415e2792..18d0735e 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js
@@ -1,41 +1,49 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent'
import { openNewScenarioModal } from '../../../../actions/modals/scenarios'
import { deleteScenario, setCurrentScenario } from '../../../../actions/scenarios'
import { setCurrentPortfolio } from '../../../../actions/portfolios'
-const mapStateToProps = (state, ownProps) => {
- let scenarios = state.objects.portfolio[ownProps.portfolioId]
- ? state.objects.portfolio[ownProps.portfolioId].scenarioIds.map((t) => state.objects.scenario[t])
- : []
- if (scenarios.filter((t) => !t).length > 0) {
- scenarios = []
- }
+const ScenarioListContainer = ({ portfolioId, children }) => {
+ const currentProjectId = useSelector((state) => state.currentProjectId)
+ const currentScenarioId = useSelector((state) => state.currentScenarioId)
+ const scenarios = useSelector((state) => {
+ let scenarios = state.objects.portfolio[portfolioId]
+ ? state.objects.portfolio[portfolioId].scenarioIds.map((t) => state.objects.scenario[t])
+ : []
+ if (scenarios.filter((t) => !t).length > 0) {
+ scenarios = []
+ }
- return {
- currentProjectId: state.currentProjectId,
- currentScenarioId: state.currentScenarioId,
- scenarios,
- }
-}
+ return scenarios
+ })
-const mapDispatchToProps = (dispatch) => {
- return {
- onNewScenario: (currentPortfolioId) => {
- dispatch(setCurrentPortfolio(currentPortfolioId))
- dispatch(openNewScenarioModal())
- },
- onChooseScenario: (portfolioId, scenarioId) => {
- dispatch(setCurrentScenario(portfolioId, scenarioId))
- },
- onDeleteScenario: (id) => {
- if (id) {
- dispatch(deleteScenario(id))
- }
- },
+ const dispatch = useDispatch()
+ const onNewScenario = (currentPortfolioId) => {
+ dispatch(setCurrentPortfolio(currentPortfolioId))
+ dispatch(openNewScenarioModal())
+ }
+ const onChooseScenario = (portfolioId, scenarioId) => {
+ dispatch(setCurrentScenario(portfolioId, scenarioId))
+ }
+ const onDeleteScenario = (id) => {
+ if (id) {
+ dispatch(deleteScenario(id))
+ }
}
-}
-const ScenarioListContainer = connect(mapStateToProps, mapDispatchToProps)(ScenarioListComponent)
+ return (
+ <ScenarioListComponent
+ portfolioId={portfolioId}
+ currentProjectId={currentProjectId}
+ currentScenarioId={currentScenarioId}
+ scenarios={scenarios}
+ onNewScenario={onNewScenario}
+ onChooseScenario={onChooseScenario}
+ onDeleteScenario={onDeleteScenario}
+ />
+ )
+}
export default ScenarioListContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js
index e1de18f9..954284a6 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js
@@ -1,46 +1,54 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent'
import { setCurrentTopology } from '../../../../actions/topology/building'
import { openNewTopologyModal } from '../../../../actions/modals/topology'
-import { withRouter } from 'react-router-dom'
+import { useHistory } from 'react-router-dom'
import { getState } from '../../../../util/state-utils'
import { deleteTopology } from '../../../../actions/topologies'
-const mapStateToProps = (state) => {
- let topologies = state.objects.project[state.currentProjectId]
- ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t])
- : []
- if (topologies.filter((t) => !t).length > 0) {
- topologies = []
- }
+const TopologyListContainer = () => {
+ const dispatch = useDispatch()
+ const history = useHistory()
- return {
- currentTopologyId: state.currentTopologyId,
- topologies,
- }
-}
+ const topologies = useSelector((state) => {
+ let topologies = state.objects.project[state.currentProjectId]
+ ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t])
+ : []
+ if (topologies.filter((t) => !t).length > 0) {
+ topologies = []
+ }
+
+ return topologies
+ })
+ const currentTopologyId = useSelector((state) => state.currentTopologyId)
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onChooseTopology: async (id) => {
- dispatch(setCurrentTopology(id))
+ const onChooseTopology = async (id) => {
+ dispatch(setCurrentTopology(id))
+ const state = await getState(dispatch)
+ history.push(`/projects/${state.currentProjectId}`)
+ }
+ const onNewTopology = () => {
+ dispatch(openNewTopologyModal())
+ }
+ const onDeleteTopology = async (id) => {
+ if (id) {
const state = await getState(dispatch)
- ownProps.history.push(`/projects/${state.currentProjectId}`)
- },
- onNewTopology: () => {
- dispatch(openNewTopologyModal())
- },
- onDeleteTopology: async (id) => {
- if (id) {
- const state = await getState(dispatch)
- dispatch(deleteTopology(id))
- dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0]))
- ownProps.history.push(`/projects/${state.currentProjectId}`)
- }
- },
+ dispatch(deleteTopology(id))
+ dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0]))
+ history.push(`/projects/${state.currentProjectId}`)
+ }
}
-}
-const TopologyListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(TopologyListComponent))
+ return (
+ <TopologyListComponent
+ topologies={topologies}
+ currentTopologyId={currentTopologyId}
+ onChooseTopology={onChooseTopology}
+ onNewTopology={onNewTopology}
+ onDeleteTopology={onDeleteTopology}
+ />
+ )
+}
export default TopologyListContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js
index fe7c02fd..42c81c65 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js
@@ -1,12 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import TopologySidebarComponent from '../../../../components/app/sidebars/topology/TopologySidebarComponent'
-const mapStateToProps = (state) => {
- return {
- interactionLevel: state.interactionLevel,
- }
+const TopologySidebarContainer = (props) => {
+ const interactionLevel = useSelector((state) => state.interactionLevel)
+ return <TopologySidebarComponent {...props} interactionLevel={interactionLevel} />
}
-const TopologySidebarContainer = connect(mapStateToProps)(TopologySidebarComponent)
-
export default TopologySidebarContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js
index ea9e9e60..ea36539c 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js
@@ -1,4 +1,5 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import {
cancelNewRoomConstruction,
finishNewRoomConstruction,
@@ -6,20 +7,22 @@ import {
} from '../../../../../actions/topology/building'
import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent'
-const mapStateToProps = (state) => {
- return {
- currentRoomInConstruction: state.construction.currentRoomInConstruction,
- }
-}
+const NewRoomConstructionButton = (props) => {
+ const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction)
-const mapDispatchToProps = (dispatch) => {
- return {
+ const dispatch = useDispatch()
+ const actions = {
onStart: () => dispatch(startNewRoomConstruction()),
onFinish: () => dispatch(finishNewRoomConstruction()),
onCancel: () => dispatch(cancelNewRoomConstruction()),
}
+ return (
+ <StartNewRoomConstructionComponent
+ {...props}
+ {...actions}
+ currentRoomInConstruction={currentRoomInConstruction}
+ />
+ )
}
-const NewRoomConstructionButton = connect(mapStateToProps, mapDispatchToProps)(StartNewRoomConstructionComponent)
-
export default NewRoomConstructionButton
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js
index 24287ab0..46862472 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level'
import BackToRackComponent from '../../../../../components/app/sidebars/topology/machine/BackToRackComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(goDownOneInteractionLevel()),
- }
+const BackToRackContainer = (props) => {
+ const dispatch = useDispatch()
+ return <BackToRackComponent {...props} onClick={() => dispatch(goDownOneInteractionLevel())} />
}
-const BackToRackContainer = connect(undefined, mapDispatchToProps)(BackToRackComponent)
-
export default BackToRackContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
index 65e683e6..1510a436 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { openDeleteMachineModal } from '../../../../../actions/modals/topology'
import DeleteMachineComponent from '../../../../../components/app/sidebars/topology/machine/DeleteMachineComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(openDeleteMachineModal()),
- }
+const DeleteMachineContainer = (props) => {
+ const dispatch = useDispatch()
+ return <DeleteMachineComponent {...props} onClick={() => dispatch(openDeleteMachineModal())} />
}
-const DeleteMachineContainer = connect(undefined, mapDispatchToProps)(DeleteMachineComponent)
-
export default DeleteMachineContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
index 1cf35b05..6f4285b2 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
@@ -1,12 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import MachineNameComponent from '../../../../../components/app/sidebars/topology/machine/MachineNameComponent'
-const mapStateToProps = (state) => {
- return {
- position: state.interactionLevel.position,
- }
+const MachineNameContainer = (props) => {
+ const position = useSelector((state) => state.interactionLevel.position)
+ return <MachineNameComponent {...props} position={position} />
}
-const MachineNameContainer = connect(mapStateToProps)(MachineNameComponent)
-
export default MachineNameContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js
index b04e3118..cb7ec8f9 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js
@@ -1,15 +1,15 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import MachineSidebarComponent from '../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent'
-const mapStateToProps = (state) => {
- return {
- machineId:
+const MachineSidebarContainer = (props) => {
+ const machineId = useSelector(
+ (state) =>
state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[
state.interactionLevel.position - 1
- ],
- }
+ ]
+ )
+ return <MachineSidebarComponent {...props} machineId={machineId} />
}
-const MachineSidebarContainer = connect(mapStateToProps)(MachineSidebarComponent)
-
export default MachineSidebarContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js
index 29e48016..3795cdff 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js
@@ -1,19 +1,15 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { addUnit } from '../../../../../actions/topology/machine'
import UnitAddComponent from '../../../../../components/app/sidebars/topology/machine/UnitAddComponent'
-const mapStateToProps = (state, ownProps) => {
- return {
- units: Object.values(state.objects[ownProps.unitType]),
- }
-}
+const UnitAddContainer = (props) => {
+ const units = useSelector((state) => Object.values(state.objects[props.unitType]))
+ const dispatch = useDispatch()
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onAdd: (id) => dispatch(addUnit(ownProps.unitType, id)),
- }
-}
+ const onAdd = (id) => dispatch(addUnit(props.unitType, id))
-const UnitAddContainer = connect(mapStateToProps, mapDispatchToProps)(UnitAddComponent)
+ return <UnitAddComponent {...props} onAdd={onAdd} units={units} />
+}
export default UnitAddContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js
index f334f9f2..3d24859e 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js
@@ -1,20 +1,14 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { deleteUnit } from '../../../../../actions/topology/machine'
import UnitComponent from '../../../../../components/app/sidebars/topology/machine/UnitComponent'
-const mapStateToProps = (state, ownProps) => {
- return {
- unit: state.objects[ownProps.unitType][ownProps.unitId],
- index: ownProps.unitId,
- }
-}
+const UnitContainer = ({ unitId, unitType }) => {
+ const dispatch = useDispatch()
+ const unit = useSelector((state) => state.objects[unitType][unitId])
+ const onDelete = () => dispatch(deleteUnit(unitType, unitId))
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onDelete: () => dispatch(deleteUnit(ownProps.unitType, ownProps.index)),
- }
+ return <UnitComponent index={unitId} unit={unit} unitType={unitType} onDelete={onDelete} />
}
-const UnitContainer = connect(mapStateToProps, mapDispatchToProps)(UnitComponent)
-
export default UnitContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js
index f382ff74..c5c9444d 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js
@@ -1,17 +1,17 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent'
-const mapStateToProps = (state, ownProps) => {
- return {
- unitIds:
+const UnitListContainer = (props) => {
+ const unitIds = useSelector(
+ (state) =>
state.objects.machine[
state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[
state.interactionLevel.position - 1
]
- ][ownProps.unitType + 'Ids'],
- }
+ ][props.unitType + 'Ids']
+ )
+ return <UnitListComponent {...props} unitIds={unitIds} />
}
-const UnitListContainer = connect(mapStateToProps)(UnitListComponent)
-
export default UnitListContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js
index c941e745..3708e33e 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { addPrefab } from '../../../../../actions/prefabs'
import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(addPrefab('name')),
- }
+const AddPrefabContainer = (props) => {
+ const dispatch = useDispatch()
+ return <AddPrefabComponent {...props} onClick={() => dispatch(addPrefab('name'))} />
}
-const AddPrefabContainer = connect(undefined, mapDispatchToProps)(AddPrefabComponent)
-
export default AddPrefabContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js
index 58c3b082..93bb749f 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level'
import BackToRoomComponent from '../../../../../components/app/sidebars/topology/rack/BackToRoomComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(goDownOneInteractionLevel()),
- }
+const BackToRoomContainer = (props) => {
+ const dispatch = useDispatch()
+ return <BackToRoomComponent {...props} onClick={() => dispatch(goDownOneInteractionLevel())} />
}
-const BackToRoomContainer = connect(undefined, mapDispatchToProps)(BackToRoomComponent)
-
export default BackToRoomContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
index 8229a359..de46e491 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { openDeleteRackModal } from '../../../../../actions/modals/topology'
import DeleteRackComponent from '../../../../../components/app/sidebars/topology/rack/DeleteRackComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(openDeleteRackModal()),
- }
+const DeleteRackContainer = (props) => {
+ const dispatch = useDispatch()
+ return <DeleteRackComponent {...props} onClick={() => dispatch(openDeleteRackModal())} />
}
-const DeleteRackContainer = connect(undefined, mapDispatchToProps)(DeleteRackComponent)
-
export default DeleteRackContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js
index cf341da9..5bb2c784 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js
@@ -1,13 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { addMachine } from '../../../../../actions/topology/rack'
import EmptySlotComponent from '../../../../../components/app/sidebars/topology/rack/EmptySlotComponent'
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onAdd: () => dispatch(addMachine(ownProps.position)),
- }
+const EmptySlotContainer = (props) => {
+ const dispatch = useDispatch()
+ const onAdd = () => dispatch(addMachine(props.position))
+ return <EmptySlotComponent {...props} onAdd={onAdd} />
}
-const EmptySlotContainer = connect(undefined, mapDispatchToProps)(EmptySlotComponent)
-
export default EmptySlotContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js
index fe12827d..149b4d18 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js
@@ -1,19 +1,14 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { goFromRackToMachine } from '../../../../../actions/interaction-level'
import MachineComponent from '../../../../../components/app/sidebars/topology/rack/MachineComponent'
-const mapStateToProps = (state, ownProps) => {
- return {
- machine: state.objects.machine[ownProps.machineId],
- }
+const MachineContainer = (props) => {
+ const machine = useSelector((state) => state.objects.machine[props.machineId])
+ const dispatch = useDispatch()
+ return (
+ <MachineComponent {...props} onClick={() => dispatch(goFromRackToMachine(props.position))} machine={machine} />
+ )
}
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onClick: () => dispatch(goFromRackToMachine(ownProps.position)),
- }
-}
-
-const MachineContainer = connect(mapStateToProps, mapDispatchToProps)(MachineComponent)
-
export default MachineContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js
index bc5a285a..b45300fc 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js
@@ -1,12 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import MachineListComponent from '../../../../../components/app/sidebars/topology/rack/MachineListComponent'
-const mapStateToProps = (state) => {
- return {
- machineIds: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds,
- }
+const MachineListContainer = (props) => {
+ const machineIds = useSelector(
+ (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds
+ )
+ return <MachineListComponent {...props} machineIds={machineIds} />
}
-const MachineListContainer = connect(mapStateToProps)(MachineListComponent)
-
export default MachineListContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js
index 504dbc61..7dfdb473 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js
@@ -1,19 +1,14 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { openEditRackNameModal } from '../../../../../actions/modals/topology'
import RackNameComponent from '../../../../../components/app/sidebars/topology/rack/RackNameComponent'
-const mapStateToProps = (state) => {
- return {
- rackName: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name,
- }
+const RackNameContainer = (props) => {
+ const rackName = useSelector(
+ (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name
+ )
+ const dispatch = useDispatch()
+ return <RackNameComponent {...props} rackName={rackName} onEdit={() => dispatch(openEditRackNameModal())} />
}
-const mapDispatchToProps = (dispatch) => {
- return {
- onEdit: () => dispatch(openEditRackNameModal()),
- }
-}
-
-const RackNameContainer = connect(mapStateToProps, mapDispatchToProps)(RackNameComponent)
-
export default RackNameContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js
index 453d7e41..b8fc3bfb 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js
@@ -1,12 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import RackSidebarComponent from '../../../../../components/app/sidebars/topology/rack/RackSidebarComponent'
-const mapStateToProps = (state) => {
- return {
- rackId: state.objects.tile[state.interactionLevel.tileId].rackId,
- }
+const RackSidebarContainer = (props) => {
+ const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rackId)
+ return <RackSidebarComponent {...props} rackId={rackId} />
}
-const RackSidebarContainer = connect(mapStateToProps)(RackSidebarComponent)
-
export default RackSidebarContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js
index 4c1ab99d..a48bf0a7 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js
@@ -1,13 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level'
import BackToBuildingComponent from '../../../../../components/app/sidebars/topology/room/BackToBuildingComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(goDownOneInteractionLevel()),
- }
+const BackToBuildingContainer = () => {
+ const dispatch = useDispatch()
+ const onClick = () => dispatch(goDownOneInteractionLevel())
+ return <BackToBuildingComponent onClick={onClick} />
}
-const BackToBuildingContainer = connect(undefined, mapDispatchToProps)(BackToBuildingComponent)
-
export default BackToBuildingContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
index 636fa5c5..6a80e9b0 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
@@ -1,13 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { openDeleteRoomModal } from '../../../../../actions/modals/topology'
import DeleteRoomComponent from '../../../../../components/app/sidebars/topology/room/DeleteRoomComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(openDeleteRoomModal()),
- }
+const DeleteRoomContainer = (props) => {
+ const dispatch = useDispatch()
+ const onClick = () => dispatch(openDeleteRoomModal())
+ return <DeleteRoomComponent {...props} onClick={onClick} />
}
-const DeleteRoomContainer = connect(undefined, mapDispatchToProps)(DeleteRoomComponent)
-
export default DeleteRoomContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js
index d17a45d1..37027fc5 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js
@@ -1,21 +1,25 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { finishRoomEdit, startRoomEdit } from '../../../../../actions/topology/building'
import EditRoomComponent from '../../../../../components/app/sidebars/topology/room/EditRoomComponent'
-const mapStateToProps = (state) => {
- return {
- isEditing: state.construction.currentRoomInConstruction !== '-1',
- isInRackConstructionMode: state.construction.inRackConstructionMode,
- }
-}
+const EditRoomContainer = (props) => {
+ const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1')
+ const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode)
-const mapDispatchToProps = (dispatch) => {
- return {
- onEdit: () => dispatch(startRoomEdit()),
- onFinish: () => dispatch(finishRoomEdit()),
- }
-}
+ const dispatch = useDispatch()
+ const onEdit = () => dispatch(startRoomEdit())
+ const onFinish = () => dispatch(finishRoomEdit())
-const EditRoomContainer = connect(mapStateToProps, mapDispatchToProps)(EditRoomComponent)
+ return (
+ <EditRoomComponent
+ {...props}
+ onEdit={onEdit}
+ onFinish={onFinish}
+ isEditing={isEditing}
+ isInRackConstructionMode={isInRackConstructionMode}
+ />
+ )
+}
export default EditRoomContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js
index cd8319de..726e9d37 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js
@@ -1,21 +1,24 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { startRackConstruction, stopRackConstruction } from '../../../../../actions/topology/room'
import RackConstructionComponent from '../../../../../components/app/sidebars/topology/room/RackConstructionComponent'
-const mapStateToProps = (state) => {
- return {
- inRackConstructionMode: state.construction.inRackConstructionMode,
- isEditingRoom: state.construction.currentRoomInConstruction !== '-1',
- }
-}
+const RackConstructionContainer = (props) => {
+ const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode)
+ const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1')
-const mapDispatchToProps = (dispatch) => {
- return {
- onStart: () => dispatch(startRackConstruction()),
- onStop: () => dispatch(stopRackConstruction()),
- }
+ const dispatch = useDispatch()
+ const onStart = () => dispatch(startRackConstruction())
+ const onStop = () => dispatch(stopRackConstruction())
+ return (
+ <RackConstructionComponent
+ {...props}
+ inRackConstructionMode={isRackConstructionMode}
+ isEditingRoom={isEditingRoom}
+ onStart={onStart}
+ onStop={onStop}
+ />
+ )
}
-const RackConstructionContainer = connect(mapStateToProps, mapDispatchToProps)(RackConstructionComponent)
-
export default RackConstructionContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js
index cab16016..1f53aeb6 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js
@@ -1,19 +1,13 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { openEditRoomNameModal } from '../../../../../actions/modals/topology'
import RoomNameComponent from '../../../../../components/app/sidebars/topology/room/RoomNameComponent'
-const mapStateToProps = (state) => {
- return {
- roomName: state.objects.room[state.interactionLevel.roomId].name,
- }
+const RoomNameContainer = (props) => {
+ const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name)
+ const dispatch = useDispatch()
+ const onEdit = () => dispatch(openEditRoomNameModal())
+ return <RoomNameComponent {...props} onEdit={onEdit} roomName={roomName} />
}
-const mapDispatchToProps = (dispatch) => {
- return {
- onEdit: () => dispatch(openEditRoomNameModal()),
- }
-}
-
-const RoomNameContainer = connect(mapStateToProps, mapDispatchToProps)(RoomNameComponent)
-
export default RoomNameContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js
index 8c3ca8ab..252881a0 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js
@@ -1,12 +1,10 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import RoomSidebarComponent from '../../../../../components/app/sidebars/topology/room/RoomSidebarComponent'
-const mapStateToProps = (state) => {
- return {
- roomId: state.interactionLevel.roomId,
- }
+const RoomSidebarContainer = (props) => {
+ const roomId = useSelector((state) => state.interactionLevel.roomId)
+ return <RoomSidebarComponent {...props} roomId={roomId} />
}
-const RoomSidebarContainer = connect(mapStateToProps)(RoomSidebarComponent)
-
export default RoomSidebarContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js
index bebe015c..54605775 100644
--- a/opendc-web/opendc-web-ui/src/containers/auth/Login.js
+++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js
@@ -1,18 +1,16 @@
-import PropTypes from 'prop-types'
import React from 'react'
import GoogleLogin from 'react-google-login'
-import { connect } from 'react-redux'
+import { useDispatch } from 'react-redux'
import { logIn } from '../../actions/auth'
import config from '../../config'
-class LoginContainer extends React.Component {
- static propTypes = {
- visible: PropTypes.bool.isRequired,
- onLogin: PropTypes.func.isRequired,
- }
+const Login = (props) => {
+ const { visible } = props
+ const dispatch = useDispatch()
- onAuthResponse(response) {
- this.props.onLogin({
+ const onLogin = (payload) => dispatch(logIn(payload))
+ const onAuthResponse = (response) => {
+ onLogin({
email: response.getBasicProfile().getEmail(),
givenName: response.getBasicProfile().getGivenName(),
familyName: response.getBasicProfile().getFamilyName(),
@@ -21,43 +19,27 @@ class LoginContainer extends React.Component {
expiresAt: response.getAuthResponse().expires_at,
})
}
-
- onAuthFailure(error) {
+ const onAuthFailure = (error) => {
+ // TODO Show error alert
console.error(error)
}
- render() {
- if (!this.props.visible) {
- return <span />
- }
-
- return (
- <GoogleLogin
- clientId={config['OAUTH_CLIENT_ID']}
- onSuccess={this.onAuthResponse.bind(this)}
- onFailure={this.onAuthFailure.bind(this)}
- render={(renderProps) => (
- <span onClick={renderProps.onClick} className="login btn btn-primary">
- <span className="fa fa-google" /> Login with Google
- </span>
- )}
- />
- )
+ if (!visible) {
+ return <span />
}
-}
-const mapStateToProps = (state, ownProps) => {
- return {
- visible: ownProps.visible,
- }
+ return (
+ <GoogleLogin
+ clientId={config.OAUTH_CLIENT_ID}
+ onSuccess={onAuthResponse}
+ onFailure={onAuthFailure}
+ render={(renderProps) => (
+ <span onClick={renderProps.onClick} className="login btn btn-primary">
+ <span className="fa fa-google" /> Login with Google
+ </span>
+ )}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- onLogin: (payload) => dispatch(logIn(payload)),
- }
-}
-
-const Login = connect(mapStateToProps, mapDispatchToProps)(LoginContainer)
-
export default Login
diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js
index 22400381..66f0f6db 100644
--- a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js
+++ b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { logOut } from '../../actions/auth'
import LogoutButton from '../../components/navigation/LogoutButton'
-const mapDispatchToProps = (dispatch) => {
- return {
- onLogout: () => dispatch(logOut()),
- }
+const Logout = (props) => {
+ const dispatch = useDispatch()
+ return <LogoutButton {...props} onLogout={() => dispatch(logOut())} />
}
-const Logout = connect(undefined, mapDispatchToProps)(LogoutButton)
-
export default Logout
diff --git a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js
index 06da75ab..291c0068 100644
--- a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js
+++ b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js
@@ -1,14 +1,9 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useSelector } from 'react-redux'
-const mapStateToProps = (state) => {
- return {
- text: state.auth.givenName + ' ' + state.auth.familyName,
- }
+function ProfileName() {
+ const name = useSelector((state) => `${state.auth.givenName} ${state.auth.familyName}`)
+ return <span>{name}</span>
}
-const SpanElement = ({ text }) => <span>{text}</span>
-
-const ProfileName = connect(mapStateToProps)(SpanElement)
-
export default ProfileName
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js
index f30febdb..33b2612f 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js
@@ -1,35 +1,26 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeDeleteMachineModal } from '../../actions/modals/topology'
import { deleteMachine } from '../../actions/topology/machine'
import ConfirmationModal from '../../components/modals/ConfirmationModal'
-const DeleteMachineModalComponent = ({ visible, callback }) => (
- <ConfirmationModal
- title="Delete this machine"
- message="Are you sure you want to delete this machine?"
- show={visible}
- callback={callback}
- />
-)
-
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.deleteMachineModalVisible,
+const DeleteMachineModal = () => {
+ const dispatch = useDispatch()
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteMachine())
+ }
+ dispatch(closeDeleteMachineModal())
}
+ const visible = useSelector((state) => state.modals.deleteMachineModalVisible)
+ return (
+ <ConfirmationModal
+ title="Delete this machine"
+ message="Are you sure you want to delete this machine?"
+ show={visible}
+ callback={callback}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (isConfirmed) => {
- if (isConfirmed) {
- dispatch(deleteMachine())
- }
- dispatch(closeDeleteMachineModal())
- },
- }
-}
-
-const DeleteMachineModal = connect(mapStateToProps, mapDispatchToProps)(DeleteMachineModalComponent)
-
export default DeleteMachineModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js
index e7c4014d..93a38642 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js
@@ -1,35 +1,27 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeDeleteProfileModal } from '../../actions/modals/profile'
import { deleteCurrentUser } from '../../actions/users'
import ConfirmationModal from '../../components/modals/ConfirmationModal'
-const DeleteProfileModalComponent = ({ visible, callback }) => (
- <ConfirmationModal
- title="Delete my account"
- message="Are you sure you want to delete your OpenDC account?"
- show={visible}
- callback={callback}
- />
-)
+const DeleteProfileModal = () => {
+ const visible = useSelector((state) => state.modals.deleteProfileModalVisible)
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.deleteProfileModalVisible,
+ const dispatch = useDispatch()
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteCurrentUser())
+ }
+ dispatch(closeDeleteProfileModal())
}
+ return (
+ <ConfirmationModal
+ title="Delete my account"
+ message="Are you sure you want to delete your OpenDC account?"
+ show={visible}
+ callback={callback}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (isConfirmed) => {
- if (isConfirmed) {
- dispatch(deleteCurrentUser())
- }
- dispatch(closeDeleteProfileModal())
- },
- }
-}
-
-const DeleteProfileModal = connect(mapStateToProps, mapDispatchToProps)(DeleteProfileModalComponent)
-
export default DeleteProfileModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js
index 0cb22a7e..ca76fd04 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js
@@ -1,35 +1,27 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeDeleteRackModal } from '../../actions/modals/topology'
import { deleteRack } from '../../actions/topology/rack'
import ConfirmationModal from '../../components/modals/ConfirmationModal'
-const DeleteRackModalComponent = ({ visible, callback }) => (
- <ConfirmationModal
- title="Delete this rack"
- message="Are you sure you want to delete this rack?"
- show={visible}
- callback={callback}
- />
-)
-
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.deleteRackModalVisible,
+const DeleteRackModal = (props) => {
+ const visible = useSelector((state) => state.modals.deleteRackModalVisible)
+ const dispatch = useDispatch()
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteRack())
+ }
+ dispatch(closeDeleteRackModal())
}
+ return (
+ <ConfirmationModal
+ title="Delete this rack"
+ message="Are you sure you want to delete this rack?"
+ show={visible}
+ callback={callback}
+ {...props}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (isConfirmed) => {
- if (isConfirmed) {
- dispatch(deleteRack())
- }
- dispatch(closeDeleteRackModal())
- },
- }
-}
-
-const DeleteRackModal = connect(mapStateToProps, mapDispatchToProps)(DeleteRackModalComponent)
-
export default DeleteRackModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js
index 1f6eef92..9a7be6a6 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js
@@ -1,35 +1,28 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeDeleteRoomModal } from '../../actions/modals/topology'
import { deleteRoom } from '../../actions/topology/room'
import ConfirmationModal from '../../components/modals/ConfirmationModal'
-const DeleteRoomModalComponent = ({ visible, callback }) => (
- <ConfirmationModal
- title="Delete this room"
- message="Are you sure you want to delete this room?"
- show={visible}
- callback={callback}
- />
-)
+const DeleteRoomModal = (props) => {
+ const visible = useSelector((state) => state.modals.deleteRoomModalVisible)
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.deleteRoomModalVisible,
+ const dispatch = useDispatch()
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteRoom())
+ }
+ dispatch(closeDeleteRoomModal())
}
+ return (
+ <ConfirmationModal
+ title="Delete this room"
+ message="Are you sure you want to delete this room?"
+ show={visible}
+ callback={callback}
+ {...props}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (isConfirmed) => {
- if (isConfirmed) {
- dispatch(deleteRoom())
- }
- dispatch(closeDeleteRoomModal())
- },
- }
-}
-
-const DeleteRoomModal = connect(mapStateToProps, mapDispatchToProps)(DeleteRoomModalComponent)
-
export default DeleteRoomModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js b/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js
index 9128f449..edb57217 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js
@@ -1,40 +1,37 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeEditRackNameModal } from '../../actions/modals/topology'
import { editRackName } from '../../actions/topology/rack'
import TextInputModal from '../../components/modals/TextInputModal'
-const EditRackNameModalComponent = ({ visible, previousName, callback }) => (
- <TextInputModal
- title="Edit rack name"
- label="Rack name"
- show={visible}
- initialValue={previousName}
- callback={callback}
- />
-)
+const EditRackNameModal = (props) => {
+ const { visible, previousName } = useSelector((state) => {
+ return {
+ visible: state.modals.editRackNameModalVisible,
+ previousName:
+ state.interactionLevel.mode === 'RACK'
+ ? state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name
+ : '',
+ }
+ })
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.editRackNameModalVisible,
- previousName:
- state.interactionLevel.mode === 'RACK'
- ? state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name
- : '',
+ const dispatch = useDispatch()
+ const callback = (name) => {
+ if (name) {
+ dispatch(editRackName(name))
+ }
+ dispatch(closeEditRackNameModal())
}
+ return (
+ <TextInputModal
+ title="Edit rack name"
+ label="Rack name"
+ show={visible}
+ initialValue={previousName}
+ callback={callback}
+ {...props}
+ />
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (name) => {
- if (name) {
- dispatch(editRackName(name))
- }
- dispatch(closeEditRackNameModal())
- },
- }
-}
-
-const EditRackNameModal = connect(mapStateToProps, mapDispatchToProps)(EditRackNameModalComponent)
-
export default EditRackNameModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js b/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js
index 8032a5d1..a804c0b0 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js
@@ -1,38 +1,31 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeEditRoomNameModal } from '../../actions/modals/topology'
import { editRoomName } from '../../actions/topology/room'
import TextInputModal from '../../components/modals/TextInputModal'
-const EditRoomNameModalComponent = ({ visible, previousName, callback }) => (
- <TextInputModal
- title="Edit room name"
- label="Room name"
- show={visible}
- initialValue={previousName}
- callback={callback}
- />
-)
+const EditRoomNameModal = (props) => {
+ const visible = useSelector((state) => state.modals.editRoomNameModalVisible)
+ const previousName = useSelector((state) =>
+ state.interactionLevel.mode === 'ROOM' ? state.objects.room[state.interactionLevel.roomId].name : ''
+ )
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.editRoomNameModalVisible,
- previousName:
- state.interactionLevel.mode === 'ROOM' ? state.objects.room[state.interactionLevel.roomId].name : '',
+ const dispatch = useDispatch()
+ const callback = (name) => {
+ if (name) {
+ dispatch(editRoomName(name))
+ }
+ dispatch(closeEditRoomNameModal())
}
+ return (
+ <TextInputModal
+ title="Edit room name"
+ label="Room name"
+ show={visible}
+ initialValue={previousName}
+ callback={callback}
+ {...props}
+ />
+ )
}
-
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (name) => {
- if (name) {
- dispatch(editRoomName(name))
- }
- dispatch(closeEditRoomNameModal())
- },
- }
-}
-
-const EditRoomNameModal = connect(mapStateToProps, mapDispatchToProps)(EditRoomNameModalComponent)
-
export default EditRoomNameModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js
index 6cf12d8e..b364ed4c 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js
@@ -1,30 +1,24 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
+import { closeNewPortfolioModal } from '../../actions/modals/portfolios'
import NewPortfolioModalComponent from '../../components/modals/custom-components/NewPortfolioModalComponent'
import { addPortfolio } from '../../actions/portfolios'
-import { closeNewPortfolioModal } from '../../actions/modals/portfolios'
-
-const mapStateToProps = (state) => {
- return {
- show: state.modals.newPortfolioModalVisible,
- }
-}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (name, targets) => {
- if (name) {
- dispatch(
- addPortfolio({
- name,
- targets,
- })
- )
- }
- dispatch(closeNewPortfolioModal())
- },
+const NewPortfolioModal = (props) => {
+ const show = useSelector((state) => state.modals.newPortfolioModalVisible)
+ const dispatch = useDispatch()
+ const callback = (name, targets) => {
+ if (name) {
+ dispatch(
+ addPortfolio({
+ name,
+ targets,
+ })
+ )
+ }
+ dispatch(closeNewPortfolioModal())
}
+ return <NewPortfolioModalComponent {...props} callback={callback} show={show} />
}
-const NewPortfolioModal = connect(mapStateToProps, mapDispatchToProps)(NewPortfolioModalComponent)
-
export default NewPortfolioModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js
index d306dc45..e63ba76b 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js
@@ -1,30 +1,19 @@
import React from 'react'
-import { connect } from 'react-redux'
+import { useDispatch, useSelector } from 'react-redux'
import { closeNewProjectModal } from '../../actions/modals/projects'
import { addProject } from '../../actions/projects'
import TextInputModal from '../../components/modals/TextInputModal'
-const NewProjectModalComponent = ({ visible, callback }) => (
- <TextInputModal title="New Project" label="Project title" show={visible} callback={callback} />
-)
-
-const mapStateToProps = (state) => {
- return {
- visible: state.modals.newProjectModalVisible,
+const NewProjectModal = (props) => {
+ const visible = useSelector((state) => state.modals.newProjectModalVisible)
+ const dispatch = useDispatch()
+ const callback = (text) => {
+ if (text) {
+ dispatch(addProject(text))
+ }
+ dispatch(closeNewProjectModal())
}
+ return <TextInputModal title="New Project" label="Project title" show={visible} callback={callback} {...props} />
}
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (text) => {
- if (text) {
- dispatch(addProject(text))
- }
- dispatch(closeNewProjectModal())
- },
- }
-}
-
-const NewProjectModal = connect(mapStateToProps, mapDispatchToProps)(NewProjectModalComponent)
-
export default NewProjectModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js
index 7d774fa4..b588b4bc 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js
@@ -1,50 +1,55 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import NewScenarioModalComponent from '../../components/modals/custom-components/NewScenarioModalComponent'
import { addScenario } from '../../actions/scenarios'
import { closeNewScenarioModal } from '../../actions/modals/scenarios'
-const mapStateToProps = (state) => {
- let topologies =
- state.currentProjectId !== '-1'
- ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t])
- : []
- if (topologies.filter((t) => !t).length > 0) {
- topologies = []
- }
+const NewScenarioModal = (props) => {
+ const topologies = useSelector(({ currentProjectId, objects }) => {
+ console.log(currentProjectId, objects)
- return {
- show: state.modals.newScenarioModalVisible,
- currentPortfolioId: state.currentPortfolioId,
- currentPortfolioScenarioIds:
- state.currentPortfolioId !== '-1' && state.objects.portfolio[state.currentPortfolioId]
- ? state.objects.portfolio[state.currentPortfolioId].scenarioIds
- : [],
- traces: Object.values(state.objects.trace),
- topologies,
- schedulers: Object.values(state.objects.scheduler),
- }
-}
+ if (currentProjectId === '-1' || !objects.project[currentProjectId]) {
+ return []
+ }
+
+ const topologies = objects.project[currentProjectId].topologyIds.map((t) => objects.topology[t])
-const mapDispatchToProps = (dispatch) => {
- return {
- callback: (name, portfolioId, trace, topology, operational) => {
- if (name) {
- dispatch(
- addScenario({
- portfolioId,
- name,
- trace,
- topology,
- operational,
- })
- )
- }
-
- dispatch(closeNewScenarioModal())
- },
+ if (topologies.filter((t) => !t).length > 0) {
+ return []
+ }
+
+ return topologies
+ })
+ const state = useSelector((state) => {
+ return {
+ show: state.modals.newScenarioModalVisible,
+ currentPortfolioId: state.currentPortfolioId,
+ currentPortfolioScenarioIds:
+ state.currentPortfolioId !== '-1' && state.objects.portfolio[state.currentPortfolioId]
+ ? state.objects.portfolio[state.currentPortfolioId].scenarioIds
+ : [],
+ traces: Object.values(state.objects.trace),
+ schedulers: Object.values(state.objects.scheduler),
+ }
+ })
+
+ const dispatch = useDispatch()
+ const callback = (name, portfolioId, trace, topology, operational) => {
+ if (name) {
+ dispatch(
+ addScenario({
+ portfolioId,
+ name,
+ trace,
+ topology,
+ operational,
+ })
+ )
+ }
+ dispatch(closeNewScenarioModal())
}
-}
-const NewScenarioModal = connect(mapStateToProps, mapDispatchToProps)(NewScenarioModalComponent)
+ return <NewScenarioModalComponent {...props} {...state} topologies={topologies} callback={callback} />
+}
export default NewScenarioModal
diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js
index 0acf6cf2..2f81706e 100644
--- a/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js
+++ b/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js
@@ -1,42 +1,48 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import NewTopologyModalComponent from '../../components/modals/custom-components/NewTopologyModalComponent'
import { closeNewTopologyModal } from '../../actions/modals/topology'
import { addTopology } from '../../actions/topologies'
-const mapStateToProps = (state) => {
- let topologies = state.objects.project[state.currentProjectId]
- ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t])
- : []
- if (topologies.filter((t) => !t).length > 0) {
- topologies = []
- }
+const NewTopologyModal = () => {
+ const show = useSelector((state) => state.modals.changeTopologyModalVisible)
+ const topologies = useSelector((state) => {
+ let topologies = state.objects.project[state.currentProjectId]
+ ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t])
+ : []
+ if (topologies.filter((t) => !t).length > 0) {
+ topologies = []
+ }
- return {
- show: state.modals.changeTopologyModalVisible,
- topologies,
- }
-}
+ return topologies
+ })
-const mapDispatchToProps = (dispatch) => {
- return {
- onCreateTopology: (name) => {
- if (name) {
- dispatch(addTopology(name, undefined))
- }
- dispatch(closeNewTopologyModal())
- },
- onDuplicateTopology: (name, id) => {
- if (name) {
- dispatch(addTopology(name, id))
- }
- dispatch(closeNewTopologyModal())
- },
- onCancel: () => {
- dispatch(closeNewTopologyModal())
- },
+ const dispatch = useDispatch()
+ const onCreateTopology = (name) => {
+ if (name) {
+ dispatch(addTopology(name, undefined))
+ }
+ dispatch(closeNewTopologyModal())
+ }
+ const onDuplicateTopology = (name, id) => {
+ if (name) {
+ dispatch(addTopology(name, id))
+ }
+ dispatch(closeNewTopologyModal())
+ }
+ const onCancel = () => {
+ dispatch(closeNewTopologyModal())
}
-}
-const NewTopologyModal = connect(mapStateToProps, mapDispatchToProps)(NewTopologyModalComponent)
+ return (
+ <NewTopologyModalComponent
+ show={show}
+ topologies={topologies}
+ onCreateTopology={onCreateTopology}
+ onDuplicateTopology={onDuplicateTopology}
+ onCancel={onCancel}
+ />
+ )
+}
export default NewTopologyModal
diff --git a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js
index 845d54e1..42a44345 100644
--- a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js
@@ -1,12 +1,12 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import AppNavbarComponent from '../../components/navigation/AppNavbarComponent'
-const mapStateToProps = (state) => {
- return {
- project: state.currentProjectId !== '-1' ? state.objects.project[state.currentProjectId] : undefined,
- }
+const AppNavbarContainer = (props) => {
+ const project = useSelector((state) =>
+ state.currentProjectId !== '-1' ? state.objects.project[state.currentProjectId] : undefined
+ )
+ return <AppNavbarComponent {...props} project={project} />
}
-const AppNavbarContainer = connect(mapStateToProps)(AppNavbarComponent)
-
export default AppNavbarContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js
index dfd6affe..26f95c55 100644
--- a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js
+++ b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js
@@ -1,19 +1,13 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch, useSelector } from 'react-redux'
import { setAuthVisibilityFilter } from '../../actions/projects'
import FilterButton from '../../components/projects/FilterButton'
-const mapStateToProps = (state, ownProps) => {
- return {
- active: state.projectList.authVisibilityFilter === ownProps.filter,
- }
-}
+const FilterLink = (props) => {
+ const active = useSelector((state) => state.projectList.authVisibilityFilter === props.filter)
+ const dispatch = useDispatch()
-const mapDispatchToProps = (dispatch, ownProps) => {
- return {
- onClick: () => dispatch(setAuthVisibilityFilter(ownProps.filter)),
- }
+ return <FilterButton {...props} onClick={() => dispatch(setAuthVisibilityFilter(props.filter))} active={active} />
}
-const FilterLink = connect(mapStateToProps, mapDispatchToProps)(FilterButton)
-
export default FilterLink
diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js
index ffd4a4a3..b8f6fef5 100644
--- a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js
@@ -1,13 +1,11 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { openNewProjectModal } from '../../actions/modals/projects'
import NewProjectButtonComponent from '../../components/projects/NewProjectButtonComponent'
-const mapDispatchToProps = (dispatch) => {
- return {
- onClick: () => dispatch(openNewProjectModal()),
- }
+const NewProjectButtonContainer = (props) => {
+ const dispatch = useDispatch()
+ return <NewProjectButtonComponent {...props} onClick={() => dispatch(openNewProjectModal())} />
}
-const NewProjectButtonContainer = connect(undefined, mapDispatchToProps)(NewProjectButtonComponent)
-
export default NewProjectButtonContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js
index 8bcbb7fd..a13034e9 100644
--- a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js
+++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js
@@ -1,20 +1,15 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useDispatch } from 'react-redux'
import { deleteProject } from '../../actions/projects'
import ProjectActionButtons from '../../components/projects/ProjectActionButtons'
-const mapStateToProps = (state, ownProps) => {
- return {
- projectId: ownProps.projectId,
- }
-}
-
-const mapDispatchToProps = (dispatch) => {
- return {
+const ProjectActions = (props) => {
+ const dispatch = useDispatch()
+ const actions = {
onViewUsers: (id) => {}, // TODO implement user viewing
onDelete: (id) => dispatch(deleteProject(id)),
}
+ return <ProjectActionButtons {...props} {...actions} />
}
-const ProjectActions = connect(mapStateToProps, mapDispatchToProps)(ProjectActionButtons)
-
export default ProjectActions
diff --git a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js
index f0010540..b869775c 100644
--- a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js
+++ b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js
@@ -1,4 +1,5 @@
-import { connect } from 'react-redux'
+import React from 'react'
+import { useSelector } from 'react-redux'
import ProjectList from '../../components/projects/ProjectAuthList'
const getVisibleProjectAuths = (projectAuths, filter) => {
@@ -14,19 +15,18 @@ const getVisibleProjectAuths = (projectAuths, filter) => {
}
}
-const mapStateToProps = (state) => {
- const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => {
- const authorization = state.objects.authorization[authorizationIds]
- authorization.user = state.objects.user[authorization.userId]
- authorization.project = state.objects.project[authorization.projectId]
- return authorization
- })
+const VisibleProjectAuthList = (props) => {
+ const authorizations = useSelector((state) => {
+ const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => {
+ const authorization = state.objects.authorization[authorizationIds]
+ authorization.user = state.objects.user[authorization.userId]
+ authorization.project = state.objects.project[authorization.projectId]
+ return authorization
+ })
- return {
- authorizations: getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter),
- }
+ return getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter)
+ })
+ return <ProjectList {...props} authorizations={authorizations} />
}
-const VisibleProjectAuthList = connect(mapStateToProps)(ProjectList)
-
export default VisibleProjectAuthList
diff --git a/opendc-web/opendc-web-ui/src/pages/App.js b/opendc-web/opendc-web-ui/src/pages/App.js
index cbc805b8..ea62e8dc 100644
--- a/opendc-web/opendc-web-ui/src/pages/App.js
+++ b/opendc-web/opendc-web-ui/src/pages/App.js
@@ -1,8 +1,7 @@
import PropTypes from 'prop-types'
-import React from 'react'
-import DocumentTitle from 'react-document-title'
-import { connect } from 'react-redux'
-import { ShortcutManager } from 'react-shortcuts'
+import React, { useEffect } from 'react'
+import { HotKeys } from 'react-hotkeys'
+import { useDispatch, useSelector } from 'react-redux'
import { openPortfolioSucceeded } from '../actions/portfolios'
import { openProjectSucceeded } from '../actions/projects'
import ToolPanelComponent from '../components/app/map/controls/ToolPanelComponent'
@@ -15,7 +14,6 @@ import DeleteRackModal from '../containers/modals/DeleteRackModal'
import DeleteRoomModal from '../containers/modals/DeleteRoomModal'
import EditRackNameModal from '../containers/modals/EditRackNameModal'
import EditRoomNameModal from '../containers/modals/EditRoomNameModal'
-import KeymapConfiguration from '../shortcuts/keymap'
import NewTopologyModal from '../containers/modals/NewTopologyModal'
import AppNavbarContainer from '../containers/navigation/AppNavbarContainer'
import ProjectSidebarContainer from '../containers/app/sidebars/project/ProjectSidebarContainer'
@@ -23,115 +21,83 @@ import { openScenarioSucceeded } from '../actions/scenarios'
import NewPortfolioModal from '../containers/modals/NewPortfolioModal'
import NewScenarioModal from '../containers/modals/NewScenarioModal'
import PortfolioResultsContainer from '../containers/app/results/PortfolioResultsContainer'
+import KeymapConfiguration from '../shortcuts/keymap'
+import { useDocumentTitle } from '../util/hooks'
-const shortcutManager = new ShortcutManager(KeymapConfiguration)
-
-class AppComponent extends React.Component {
- static propTypes = {
- projectId: PropTypes.string.isRequired,
- portfolioId: PropTypes.string,
- scenarioId: PropTypes.string,
- projectName: PropTypes.string,
- }
- static childContextTypes = {
- shortcuts: PropTypes.object.isRequired,
- }
+const App = ({ projectId, portfolioId, scenarioId }) => {
+ const projectName = useSelector(
+ (state) =>
+ state.currentProjectId !== '-1' &&
+ state.objects.project[state.currentProjectId] &&
+ state.objects.project[state.currentProjectId].name
+ )
+ const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1')
- componentDidMount() {
- if (this.props.scenarioId) {
- this.props.openScenarioSucceeded(this.props.projectId, this.props.portfolioId, this.props.scenarioId)
- } else if (this.props.portfolioId) {
- this.props.openPortfolioSucceeded(this.props.projectId, this.props.portfolioId)
+ const dispatch = useDispatch()
+ useEffect(() => {
+ if (scenarioId) {
+ dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId))
+ } else if (portfolioId) {
+ dispatch(openPortfolioSucceeded(projectId, portfolioId))
} else {
- this.props.openProjectSucceeded(this.props.projectId)
- }
- }
-
- getChildContext() {
- return {
- shortcuts: shortcutManager,
+ dispatch(openProjectSucceeded(projectId))
}
- }
+ }, [projectId, portfolioId, scenarioId, dispatch])
- render() {
- const constructionElements = this.props.topologyIsLoading ? (
- <div className="full-height d-flex align-items-center justify-content-center">
- <LoadingScreen />
- </div>
- ) : (
- <div className="full-height">
- <MapStage />
- <ScaleIndicatorContainer />
- <ToolPanelComponent />
- <ProjectSidebarContainer />
- <TopologySidebarContainer />
- </div>
- )
+ const constructionElements = topologyIsLoading ? (
+ <div className="full-height d-flex align-items-center justify-content-center">
+ <LoadingScreen />
+ </div>
+ ) : (
+ <div className="full-height">
+ <MapStage />
+ <ScaleIndicatorContainer />
+ <ToolPanelComponent />
+ <ProjectSidebarContainer />
+ <TopologySidebarContainer />
+ </div>
+ )
- const portfolioElements = (
- <div className="full-height app-page-container">
- <ProjectSidebarContainer />
- <div className="container-fluid full-height">
- <PortfolioResultsContainer />
- </div>
+ const portfolioElements = (
+ <div className="full-height app-page-container">
+ <ProjectSidebarContainer />
+ <div className="container-fluid full-height">
+ <PortfolioResultsContainer />
</div>
- )
+ </div>
+ )
- const scenarioElements = (
- <div className="full-height app-page-container">
- <ProjectSidebarContainer />
- <div className="container-fluid full-height">
- <h2>Scenario loading</h2>
- </div>
+ const scenarioElements = (
+ <div className="full-height app-page-container">
+ <ProjectSidebarContainer />
+ <div className="container-fluid full-height">
+ <h2>Scenario loading</h2>
</div>
- )
+ </div>
+ )
- return (
- <DocumentTitle
- title={this.props.projectName ? this.props.projectName + ' - OpenDC' : 'Simulation - OpenDC'}
- >
- <div className="page-container full-height">
- <AppNavbarContainer fullWidth={true} />
- {this.props.scenarioId
- ? scenarioElements
- : this.props.portfolioId
- ? portfolioElements
- : constructionElements}
- <NewTopologyModal />
- <NewPortfolioModal />
- <NewScenarioModal />
- <EditRoomNameModal />
- <DeleteRoomModal />
- <EditRackNameModal />
- <DeleteRackModal />
- <DeleteMachineModal />
- </div>
- </DocumentTitle>
- )
- }
-}
+ useDocumentTitle(projectName ? projectName + ' - OpenDC' : 'Simulation - OpenDC')
-const mapStateToProps = (state) => {
- let projectName = undefined
- if (state.currentProjectId !== '-1' && state.objects.project[state.currentProjectId]) {
- projectName = state.objects.project[state.currentProjectId].name
- }
-
- return {
- topologyIsLoading: state.currentTopologyId === '-1',
- projectName,
- }
+ return (
+ <HotKeys keyMap={KeymapConfiguration} className="page-container full-height">
+ <AppNavbarContainer fullWidth={true} />
+ {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements}
+ <NewTopologyModal />
+ <NewPortfolioModal />
+ <NewScenarioModal />
+ <EditRoomNameModal />
+ <DeleteRoomModal />
+ <EditRackNameModal />
+ <DeleteRackModal />
+ <DeleteMachineModal />
+ </HotKeys>
+ )
}
-const mapDispatchToProps = (dispatch) => {
- return {
- openProjectSucceeded: (projectId) => dispatch(openProjectSucceeded(projectId)),
- openPortfolioSucceeded: (projectId, portfolioId) => dispatch(openPortfolioSucceeded(projectId, portfolioId)),
- openScenarioSucceeded: (projectId, portfolioId, scenarioId) =>
- dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)),
- }
+App.propTypes = {
+ projectId: PropTypes.string.isRequired,
+ portfolioId: PropTypes.string,
+ scenarioId: PropTypes.string,
}
-const App = connect(mapStateToProps, mapDispatchToProps)(AppComponent)
-
export default App
diff --git a/opendc-web/opendc-web-ui/src/pages/Home.js b/opendc-web/opendc-web-ui/src/pages/Home.js
index 6fc940c0..fb383426 100644
--- a/opendc-web/opendc-web-ui/src/pages/Home.js
+++ b/opendc-web/opendc-web-ui/src/pages/Home.js
@@ -1,5 +1,4 @@
import React from 'react'
-import DocumentTitle from 'react-document-title'
import ContactSection from '../components/home/ContactSection'
import IntroSection from '../components/home/IntroSection'
import JumbotronHeader from '../components/home/JumbotronHeader'
@@ -10,8 +9,10 @@ import TeamSection from '../components/home/TeamSection'
import TechnologiesSection from '../components/home/TechnologiesSection'
import HomeNavbar from '../components/navigation/HomeNavbar'
import './Home.sass'
+import { useDocumentTitle } from '../util/hooks'
function Home() {
+ useDocumentTitle('OpenDC')
return (
<div>
<HomeNavbar />
@@ -24,7 +25,6 @@ function Home() {
<TechnologiesSection />
<TeamSection />
<ContactSection />
- <DocumentTitle title="OpenDC" />
</div>
</div>
)
diff --git a/opendc-web/opendc-web-ui/src/pages/NotFound.js b/opendc-web/opendc-web-ui/src/pages/NotFound.js
index 72be7342..b933ffa5 100644
--- a/opendc-web/opendc-web-ui/src/pages/NotFound.js
+++ b/opendc-web/opendc-web-ui/src/pages/NotFound.js
@@ -1,14 +1,15 @@
import React from 'react'
-import DocumentTitle from 'react-document-title'
import TerminalWindow from '../components/not-found/TerminalWindow'
import './NotFound.sass'
+import { useDocumentTitle } from '../util/hooks'
-const NotFound = () => (
- <DocumentTitle title="Page Not Found - OpenDC">
+const NotFound = () => {
+ useDocumentTitle('Page Not Found - OpenDC')
+ return (
<div className="not-found-backdrop">
<TerminalWindow />
</div>
- </DocumentTitle>
-)
+ )
+}
export default NotFound
diff --git a/opendc-web/opendc-web-ui/src/pages/Profile.js b/opendc-web/opendc-web-ui/src/pages/Profile.js
index 0d94b519..ea781686 100644
--- a/opendc-web/opendc-web-ui/src/pages/Profile.js
+++ b/opendc-web/opendc-web-ui/src/pages/Profile.js
@@ -1,12 +1,16 @@
import React from 'react'
-import DocumentTitle from 'react-document-title'
-import { connect } from 'react-redux'
+import { useDispatch } from 'react-redux'
import { openDeleteProfileModal } from '../actions/modals/profile'
import DeleteProfileModal from '../containers/modals/DeleteProfileModal'
import AppNavbarContainer from '../containers/navigation/AppNavbarContainer'
+import { useDocumentTitle } from '../util/hooks'
-const ProfileContainer = ({ onDelete }) => (
- <DocumentTitle title="My Profile - OpenDC">
+const Profile = () => {
+ const dispatch = useDispatch()
+ const onDelete = () => dispatch(openDeleteProfileModal())
+
+ useDocumentTitle('My Profile - OpenDC')
+ return (
<div className="full-height">
<AppNavbarContainer fullWidth={false} />
<div className="container text-page-container full-height">
@@ -21,15 +25,7 @@ const ProfileContainer = ({ onDelete }) => (
</div>
<DeleteProfileModal />
</div>
- </DocumentTitle>
-)
-
-const mapDispatchToProps = (dispatch) => {
- return {
- onDelete: () => dispatch(openDeleteProfileModal()),
- }
+ )
}
-const Profile = connect(undefined, mapDispatchToProps)(ProfileContainer)
-
export default Profile
diff --git a/opendc-web/opendc-web-ui/src/pages/Projects.js b/opendc-web/opendc-web-ui/src/pages/Projects.js
index bb54aaa5..5e642a03 100644
--- a/opendc-web/opendc-web-ui/src/pages/Projects.js
+++ b/opendc-web/opendc-web-ui/src/pages/Projects.js
@@ -1,43 +1,30 @@
-import React from 'react'
-import DocumentTitle from 'react-document-title'
-import { connect } from 'react-redux'
-import { openNewProjectModal } from '../actions/modals/projects'
+import React, { useEffect } from 'react'
+import { useDispatch } from 'react-redux'
import { fetchAuthorizationsOfCurrentUser } from '../actions/users'
import ProjectFilterPanel from '../components/projects/FilterPanel'
import NewProjectModal from '../containers/modals/NewProjectModal'
import NewProjectButtonContainer from '../containers/projects/NewProjectButtonContainer'
import VisibleProjectList from '../containers/projects/VisibleProjectAuthList'
import AppNavbarContainer from '../containers/navigation/AppNavbarContainer'
+import { useDocumentTitle } from '../util/hooks'
-class ProjectsContainer extends React.Component {
- componentDidMount() {
- this.props.fetchAuthorizationsOfCurrentUser()
- }
+function Projects() {
+ const dispatch = useDispatch()
- render() {
- return (
- <DocumentTitle title="My Projects - OpenDC">
- <div className="full-height">
- <AppNavbarContainer fullWidth={false} />
- <div className="container text-page-container full-height">
- <ProjectFilterPanel />
- <VisibleProjectList />
- <NewProjectButtonContainer />
- </div>
- <NewProjectModal />
- </div>
- </DocumentTitle>
- )
- }
-}
+ useEffect(() => dispatch(fetchAuthorizationsOfCurrentUser()))
+ useDocumentTitle('My Projects - OpenDC')
-const mapDispatchToProps = (dispatch) => {
- return {
- fetchAuthorizationsOfCurrentUser: () => dispatch(fetchAuthorizationsOfCurrentUser()),
- openNewProjectModal: () => dispatch(openNewProjectModal()),
- }
+ return (
+ <div className="full-height">
+ <AppNavbarContainer fullWidth={false} />
+ <div className="container text-page-container full-height">
+ <ProjectFilterPanel />
+ <VisibleProjectList />
+ <NewProjectButtonContainer />
+ </div>
+ <NewProjectModal />
+ </div>
+ )
}
-const Projects = connect(undefined, mapDispatchToProps)(ProjectsContainer)
-
export default Projects
diff --git a/opendc-web/opendc-web-ui/src/shortcuts/keymap.js b/opendc-web/opendc-web-ui/src/shortcuts/keymap.js
index 797340d7..8260ace2 100644
--- a/opendc-web/opendc-web-ui/src/shortcuts/keymap.js
+++ b/opendc-web/opendc-web-ui/src/shortcuts/keymap.js
@@ -1,10 +1,8 @@
const KeymapConfiguration = {
- MAP: {
- MOVE_LEFT: ['a', 'left'],
- MOVE_RIGHT: ['d', 'right'],
- MOVE_UP: ['w', 'up'],
- MOVE_DOWN: ['s', 'down'],
- },
+ MOVE_LEFT: ['a', 'left'],
+ MOVE_RIGHT: ['d', 'right'],
+ MOVE_UP: ['w', 'up'],
+ MOVE_DOWN: ['s', 'down'],
}
export default KeymapConfiguration
diff --git a/opendc-web/opendc-web-ui/src/util/hooks.js b/opendc-web/opendc-web-ui/src/util/hooks.js
new file mode 100644
index 00000000..7780a778
--- /dev/null
+++ b/opendc-web/opendc-web-ui/src/util/hooks.js
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2021 AtLarge Research
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+import { useEffect } from 'react'
+
+export function useDocumentTitle(title) {
+ useEffect(() => {
+ document.title = title
+ }, [title])
+}