summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-ui/src/components')
-rw-r--r--opendc-web/opendc-web-ui/src/components/app/map/MapStageComponent.js118
-rw-r--r--opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js13
-rw-r--r--opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js13
-rw-r--r--opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js48
-rw-r--r--opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js20
-rw-r--r--opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js3
-rw-r--r--opendc-web/opendc-web-ui/src/components/navigation/Navbar.js47
-rw-r--r--opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js8
-rw-r--r--opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js8
9 files changed, 142 insertions, 136 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 7ca10792..dd32927f 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,4 +1,4 @@
-import React from 'react'
+import React, { useEffect, useMemo, useRef, useState } from 'react'
import { HotKeys } from 'react-hotkeys'
import { Stage } from 'react-konva'
import MapLayer from '../../../containers/app/map/layers/MapLayer'
@@ -6,85 +6,75 @@ import ObjectHoverLayer from '../../../containers/app/map/layers/ObjectHoverLaye
import RoomHoverLayer from '../../../containers/app/map/layers/RoomHoverLayer'
import { NAVBAR_HEIGHT } from '../../navigation/Navbar'
import { MAP_MOVE_PIXELS_PER_EVENT } from './MapConstants'
-import { Provider } from 'react-redux'
-import { store } from '../../../store/configure-store'
+import { Provider, useStore } from 'react-redux'
-class MapStageComponent extends React.Component {
- state = {
- mouseX: 0,
- mouseY: 0,
+function MapStageComponent({
+ mapDimensions,
+ mapPosition,
+ setMapDimensions,
+ setMapPositionWithBoundsCheck,
+ zoomInOnPosition,
+}) {
+ const [pos, setPos] = useState([0, 0])
+ const stage = useRef(null)
+ const [x, y] = pos
+ const handlers = {
+ MOVE_LEFT: () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0),
+ MOVE_RIGHT: () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0),
+ MOVE_UP: () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT),
+ MOVE_DOWN: () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT),
}
- constructor(props) {
- super(props)
+ const moveWithDelta = (deltaX, deltaY) =>
+ setMapPositionWithBoundsCheck(mapPosition.x + deltaX, mapPosition.y + deltaY)
+ const updateMousePosition = () => {
+ if (!stage.current) {
+ return
+ }
- this.updateDimensions = this.updateDimensions.bind(this)
- this.updateScale = this.updateScale.bind(this)
+ const mousePos = stage.current.getStage().getPointerPosition()
+ setPos([mousePos.x, mousePos.y])
}
+ const updateDimensions = () => setMapDimensions(window.innerWidth, window.innerHeight - NAVBAR_HEIGHT)
+ const updateScale = (e) => zoomInOnPosition(e.deltaY < 0, x, y)
- componentDidMount() {
- this.updateDimensions()
+ useEffect(() => {
+ updateDimensions()
- window.addEventListener('resize', this.updateDimensions)
- window.addEventListener('wheel', this.updateScale)
+ window.addEventListener('resize', updateDimensions)
+ window.addEventListener('wheel', updateScale)
window['exportCanvasToImage'] = () => {
const download = document.createElement('a')
- download.href = this.stage.getStage().toDataURL()
+ download.href = stage.current.getStage().toDataURL()
download.download = 'opendc-canvas-export-' + Date.now() + '.png'
download.click()
}
- }
-
- componentWillUnmount() {
- window.removeEventListener('resize', this.updateDimensions)
- window.removeEventListener('wheel', this.updateScale)
- }
-
- updateDimensions() {
- this.props.setMapDimensions(window.innerWidth, window.innerHeight - NAVBAR_HEIGHT)
- }
-
- updateScale(e) {
- this.props.zoomInOnPosition(e.deltaY < 0, this.state.mouseX, this.state.mouseY)
- }
-
- updateMousePosition() {
- const mousePos = this.stage.getStage().getPointerPosition()
- this.setState({ mouseX: mousePos.x, mouseY: mousePos.y })
- }
- 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),
- }
+ return () => {
+ window.removeEventListener('resize', updateDimensions)
+ window.removeEventListener('wheel', updateScale)
+ }
+ }, [])
- moveWithDelta(deltaX, deltaY) {
- this.props.setMapPositionWithBoundsCheck(this.props.mapPosition.x + deltaX, this.props.mapPosition.y + deltaY)
- }
+ const store = useStore()
- render() {
- return (
- <HotKeys handlers={this.handlers}>
- <Stage
- ref={(stage) => {
- this.stage = stage
- }}
- width={this.props.mapDimensions.width}
- height={this.props.mapDimensions.height}
- onMouseMove={this.updateMousePosition.bind(this)}
- >
- <Provider store={store}>
- <MapLayer />
- <RoomHoverLayer mouseX={this.state.mouseX} mouseY={this.state.mouseY} />
- <ObjectHoverLayer mouseX={this.state.mouseX} mouseY={this.state.mouseY} />
- </Provider>
- </Stage>
- </HotKeys>
- )
- }
+ return (
+ <HotKeys handlers={handlers} allowChanges={true}>
+ <Stage
+ ref={stage}
+ width={mapDimensions.width}
+ height={mapDimensions.height}
+ onMouseMove={updateMousePosition}
+ >
+ <Provider store={store}>
+ <MapLayer />
+ <RoomHoverLayer mouseX={x} mouseY={y} />
+ <ObjectHoverLayer mouseX={x} mouseY={y} />
+ </Provider>
+ </Stage>
+ </HotKeys>
+ )
}
export default MapStageComponent
diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js
index b000b9e2..b714a7d2 100644
--- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js
+++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/PortfolioListComponent.js
@@ -1,7 +1,7 @@
import PropTypes from 'prop-types'
import React from 'react'
import Shapes from '../../../../shapes'
-import { Link } from 'react-router-dom'
+import Link from 'next/link'
import FontAwesome from 'react-fontawesome'
import ScenarioListContainer from '../../../../containers/app/sidebars/project/ScenarioListContainer'
@@ -44,11 +44,12 @@ class PortfolioListComponent extends React.Component {
{portfolio.name}
</div>
<div className="col-5 text-right">
- <Link
- className="btn btn-outline-primary mr-1 fa fa-play"
- to={`/projects/${this.props.currentProjectId}/portfolios/${portfolio._id}`}
- onClick={() => this.props.onChoosePortfolio(portfolio._id)}
- />
+ <Link href={`/projects/${this.props.currentProjectId}/portfolios/${portfolio._id}`}>
+ <a
+ className="btn btn-outline-primary mr-1 fa fa-play"
+ onClick={() => this.props.onChoosePortfolio(portfolio._id)}
+ />
+ </Link>
<span
className="btn btn-outline-danger fa fa-trash"
onClick={() => this.onDelete(portfolio._id)}
diff --git a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js
index e775a663..4efa99ef 100644
--- a/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js
+++ b/opendc-web/opendc-web-ui/src/components/app/sidebars/project/ScenarioListComponent.js
@@ -1,7 +1,7 @@
import PropTypes from 'prop-types'
import React from 'react'
import Shapes from '../../../../shapes'
-import { Link } from 'react-router-dom'
+import Link from 'next/link'
import FontAwesome from 'react-fontawesome'
class ScenarioListComponent extends React.Component {
@@ -34,10 +34,13 @@ class ScenarioListComponent extends React.Component {
</div>
<div className="col-5 text-right">
<Link
- className="btn btn-outline-primary mr-1 fa fa-play disabled"
- to={`/projects/${this.props.currentProjectId}/portfolios/${scenario.portfolioId}/scenarios/${scenario._id}`}
- onClick={() => this.props.onChooseScenario(scenario.portfolioId, scenario._id)}
- />
+ href={`/projects/${this.props.currentProjectId}/portfolios/${scenario.portfolioId}/scenarios/${scenario._id}`}
+ >
+ <a
+ className="btn btn-outline-primary mr-1 fa fa-play disabled"
+ onClick={() => this.props.onChooseScenario(scenario.portfolioId, scenario._id)}
+ />
+ </Link>
<span
className={'btn btn-outline-danger fa fa-trash ' + (idx === 0 ? 'disabled' : '')}
onClick={() => (idx !== 0 ? this.onDelete(scenario._id) : undefined)}
diff --git a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js
index 589047dc..5a95810a 100644
--- a/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js
+++ b/opendc-web/opendc-web-ui/src/components/modals/ConfirmationModal.js
@@ -2,36 +2,26 @@ import PropTypes from 'prop-types'
import React from 'react'
import Modal from './Modal'
-class ConfirmationModal extends React.Component {
- static propTypes = {
- title: PropTypes.string.isRequired,
- message: PropTypes.string.isRequired,
- show: PropTypes.bool.isRequired,
- callback: PropTypes.func.isRequired,
- }
-
- onConfirm() {
- this.props.callback(true)
- }
-
- onCancel() {
- this.props.callback(false)
- }
+function ConfirmationModal({ title, message, show, callback }) {
+ return (
+ <Modal
+ title={title}
+ show={show}
+ onSubmit={() => callback(true)}
+ onCancel={() => callback(false)}
+ submitButtonType="danger"
+ submitButtonText="Confirm"
+ >
+ {message}
+ </Modal>
+ )
+}
- render() {
- return (
- <Modal
- title={this.props.title}
- show={this.props.show}
- onSubmit={this.onConfirm.bind(this)}
- onCancel={this.onCancel.bind(this)}
- submitButtonType="danger"
- submitButtonText="Confirm"
- >
- {this.props.message}
- </Modal>
- )
- }
+ConfirmationModal.propTypes = {
+ title: PropTypes.string.isRequired,
+ message: PropTypes.string.isRequired,
+ show: PropTypes.bool.isRequired,
+ callback: PropTypes.func.isRequired,
}
export default ConfirmationModal
diff --git a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js
index 8c28c542..7b1eaae2 100644
--- a/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js
+++ b/opendc-web/opendc-web-ui/src/components/navigation/AppNavbarComponent.js
@@ -1,6 +1,6 @@
import React from 'react'
import FontAwesome from 'react-fontawesome'
-import { Link } from 'react-router-dom'
+import Link from 'next/link'
import { NavLink } from 'reactstrap'
import Navbar, { NavItem } from './Navbar'
import {} from './Navbar.module.scss'
@@ -8,16 +8,20 @@ import {} from './Navbar.module.scss'
const AppNavbarComponent = ({ project, fullWidth }) => (
<Navbar fullWidth={fullWidth}>
<NavItem route="/projects">
- <NavLink tag={Link} title="My Projects" to="/projects">
- <FontAwesome name="list" className="mr-2" />
- My Projects
- </NavLink>
+ <Link href="/projects">
+ <NavLink title="My Projects">
+ <FontAwesome name="list" className="mr-2" />
+ My Projects
+ </NavLink>
+ </Link>
</NavItem>
{project ? (
<NavItem>
- <NavLink tag={Link} title="Current Project" to={`/projects/${project._id}`}>
- <span>{project.name}</span>
- </NavLink>
+ <Link href={`/projects/${project._id}`}>
+ <NavLink title="Current Project">
+ <span>{project.name}</span>
+ </NavLink>
+ </Link>
</NavItem>
) : undefined}
</Navbar>
diff --git a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js
index 78b02b44..0c0feeb1 100644
--- a/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js
+++ b/opendc-web/opendc-web-ui/src/components/navigation/LogoutButton.js
@@ -1,11 +1,10 @@
import PropTypes from 'prop-types'
import React from 'react'
import FontAwesome from 'react-fontawesome'
-import { Link } from 'react-router-dom'
import { NavLink } from 'reactstrap'
const LogoutButton = ({ onLogout }) => (
- <NavLink tag={Link} className="logout" title="Sign out" to="#" onClick={onLogout}>
+ <NavLink className="logout" title="Sign out" onClick={onLogout}>
<FontAwesome name="power-off" size="lg" />
</NavLink>
)
diff --git a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js
index bf18f1c4..90f55665 100644
--- a/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js
+++ b/opendc-web/opendc-web-ui/src/components/navigation/Navbar.js
@@ -1,5 +1,6 @@
import React, { useState } from 'react'
-import { Link, useLocation } from 'react-router-dom'
+import Link from 'next/link'
+import { useRouter } from 'next/router'
import {
Navbar as RNavbar,
NavItem as RNavItem,
@@ -15,6 +16,7 @@ import Login from '../../containers/auth/Login'
import Logout from '../../containers/auth/Logout'
import ProfileName from '../../containers/auth/ProfileName'
import { login, navbar, opendcBrand } from './Navbar.module.scss'
+import { useAuth } from '../../auth/hook'
export const NAVBAR_HEIGHT = 60
@@ -24,32 +26,45 @@ const GitHubLink = () => (
className="ml-2 mr-3 text-dark"
style={{ position: 'relative', top: 7 }}
>
- <span className="fa fa-github fa-2x" />
+ <span aria-hidden className="fa fa-github fa-2x" />
</a>
)
export const NavItem = ({ route, children }) => {
- const location = useLocation()
- return <RNavItem active={location.pathname === route}>{children}</RNavItem>
+ const router = useRouter()
+ const handleClick = (e) => {
+ e.preventDefault()
+ router.push(route)
+ }
+ return (
+ <RNavItem onClick={handleClick} active={router.asPath === route}>
+ {children}
+ </RNavItem>
+ )
}
export const LoggedInSection = () => {
- const location = useLocation()
+ const router = useRouter()
+ const isLoggedIn = useAuth()
return (
<Nav navbar className="auth-links">
- {userIsLoggedIn() ? (
+ {isLoggedIn ? (
[
- location.pathname === '/' ? (
+ router.asPath === '/' ? (
<NavItem route="/projects" key="projects">
- <NavLink tag={Link} title="My Projects" to="/projects">
- My Projects
- </NavLink>
+ <Link href="/projects">
+ <NavLink title="My Projects" to="/projects">
+ My Projects
+ </NavLink>
+ </Link>
</NavItem>
) : (
<NavItem route="/profile" key="profile">
- <NavLink tag={Link} title="My Profile" to="/profile">
- <ProfileName />
- </NavLink>
+ <Link href="/profile">
+ <NavLink title="My Profile">
+ <ProfileName />
+ </NavLink>
+ </Link>
</NavItem>
),
<NavItem route="logout" key="logout">
@@ -57,10 +72,10 @@ export const LoggedInSection = () => {
</NavItem>,
]
) : (
- <NavItem route="login">
+ <RNavItem>
<GitHubLink />
<Login visible={true} className={login} />
- </NavItem>
+ </RNavItem>
)}
</Nav>
)
@@ -74,7 +89,7 @@ const Navbar = ({ fullWidth, children }) => {
<RNavbar fixed="top" color="light" light expand="lg" id="navbar" className={navbar}>
<Container fluid={fullWidth}>
<NavbarToggler onClick={toggle} />
- <NavbarBrand tag={Link} to="/" title="OpenDC" className={opendcBrand}>
+ <NavbarBrand href="/" title="OpenDC" className={opendcBrand}>
<img src="/img/logo.png" alt="OpenDC" />
</NavbarBrand>
diff --git a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js
index b38fc183..28fd81e9 100644
--- a/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js
+++ b/opendc-web/opendc-web-ui/src/components/not-found/TerminalWindow.js
@@ -1,5 +1,5 @@
import React from 'react'
-import { Link } from 'react-router-dom'
+import Link from 'next/link'
import BlinkingCursor from './BlinkingCursor'
import CodeBlock from './CodeBlock'
import { terminalWindow, terminalHeader, terminalBody, segfault, subTitle, homeBtn } from './TerminalWindow.module.scss'
@@ -23,8 +23,10 @@ const TerminalWindow = () => (
Got lost?
<BlinkingCursor />
</div>
- <Link to="/" className={homeBtn}>
- <span className="fa fa-home" /> GET ME BACK TO OPENDC
+ <Link href="/">
+ <a className={homeBtn}>
+ <span className="fa fa-home" /> GET ME BACK TO OPENDC
+ </a>
</Link>
</div>
</div>
diff --git a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js
index 1c76cc7f..48cce019 100644
--- a/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js
+++ b/opendc-web/opendc-web-ui/src/components/projects/ProjectActionButtons.js
@@ -1,11 +1,13 @@
import PropTypes from 'prop-types'
import React from 'react'
-import { Link } from 'react-router-dom'
+import Link from 'next/link'
const ProjectActionButtons = ({ projectId, onViewUsers, onDelete }) => (
<td className="text-right">
- <Link to={'/projects/' + projectId} className="btn btn-outline-primary btn-sm mr-2" title="Open this project">
- <span className="fa fa-play" />
+ <Link href={`/projects/${projectId}`}>
+ <a className="btn btn-outline-primary btn-sm mr-2" title="Open this project">
+ <span className="fa fa-play" />
+ </a>
</Link>
<div
className="btn btn-outline-success btn-sm disabled mr-2"