diff options
| author | Georgios Andreadis <g.andreadis@student.tudelft.nl> | 2017-10-04 22:49:07 +0200 |
|---|---|---|
| committer | Georgios Andreadis <g.andreadis@student.tudelft.nl> | 2017-10-04 22:49:25 +0200 |
| commit | 751a9ef3a12c952fe179f256d854d0c4aa37e28e (patch) | |
| tree | 241fc22c592a277526e73cc70ea0f95d5a8a7b29 /src/components | |
| parent | 9257d89ec2e22b65ffecc7dc7cf67b7a74c34d60 (diff) | |
Apply prettier to codebase
Diffstat (limited to 'src/components')
93 files changed, 2402 insertions, 2034 deletions
diff --git a/src/components/app/map/LoadingScreen.js b/src/components/app/map/LoadingScreen.js index 3d5753e2..9f379e0b 100644 --- a/src/components/app/map/LoadingScreen.js +++ b/src/components/app/map/LoadingScreen.js @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; import FontAwesome from "react-fontawesome"; const LoadingScreen = () => ( - <div className="display-4"> - <FontAwesome name="refresh" className="mr-4" spin/> - Loading your datacenter... - </div> + <div className="display-4"> + <FontAwesome name="refresh" className="mr-4" spin /> + Loading your datacenter... + </div> ); export default LoadingScreen; diff --git a/src/components/app/map/MapConstants.js b/src/components/app/map/MapConstants.js index a0166d15..32438b5e 100644 --- a/src/components/app/map/MapConstants.js +++ b/src/components/app/map/MapConstants.js @@ -5,7 +5,8 @@ export const MAP_SIZE_IN_PIXELS = MAP_SIZE * TILE_SIZE_IN_PIXELS; export const OBJECT_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 5; export const TILE_PLUS_MARGIN_IN_PIXELS = TILE_SIZE_IN_PIXELS / 3; -export const OBJECT_SIZE_IN_PIXELS = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2; +export const OBJECT_SIZE_IN_PIXELS = + TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2; export const GRID_LINE_WIDTH_IN_PIXELS = 2; export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 8; diff --git a/src/components/app/map/MapStageComponent.js b/src/components/app/map/MapStageComponent.js index c5b31e0f..ce6a60f6 100644 --- a/src/components/app/map/MapStageComponent.js +++ b/src/components/app/map/MapStageComponent.js @@ -1,108 +1,122 @@ import React from "react"; -import {Stage} from "react-konva"; -import {Shortcuts} from "react-shortcuts"; +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"; import jQuery from "../../../util/jquery"; -import {NAVBAR_HEIGHT} from "../../navigation/Navbar"; -import {MAP_MOVE_PIXELS_PER_EVENT} from "./MapConstants"; +import { NAVBAR_HEIGHT } from "../../navigation/Navbar"; +import { MAP_MOVE_PIXELS_PER_EVENT } from "./MapConstants"; class MapStageComponent extends React.Component { - state = { - mouseX: 0, - mouseY: 0 - }; + state = { + mouseX: 0, + mouseY: 0 + }; - constructor() { - super(); + constructor() { + super(); - this.updateDimensions = this.updateDimensions.bind(this); - this.updateScale = this.updateScale.bind(this); - } + this.updateDimensions = this.updateDimensions.bind(this); + this.updateScale = this.updateScale.bind(this); + } - componentWillMount() { - this.updateDimensions(); - } + componentWillMount() { + this.updateDimensions(); + } - componentDidMount() { - window.addEventListener("resize", this.updateDimensions); - window.addEventListener("wheel", this.updateScale); + componentDidMount() { + window.addEventListener("resize", this.updateDimensions); + window.addEventListener("wheel", this.updateScale); - window["exportCanvasToImage"] = () => { - const download = document.createElement("a"); - download.href = this.stage.getStage().toDataURL(); - download.download = "opendc-canvas-export-" + Date.now() + ".png"; - download.click(); - } - } + window["exportCanvasToImage"] = () => { + const download = document.createElement("a"); + download.href = this.stage.getStage().toDataURL(); + download.download = "opendc-canvas-export-" + Date.now() + ".png"; + download.click(); + }; + } - componentWillUnmount() { - window.removeEventListener("resize", this.updateDimensions); - window.removeEventListener("wheel", this.updateScale); - } + componentWillUnmount() { + window.removeEventListener("resize", this.updateDimensions); + window.removeEventListener("wheel", this.updateScale); + } - updateDimensions() { - this.props.setMapDimensions(jQuery(window).width(), jQuery(window).height() - NAVBAR_HEIGHT); - } + updateDimensions() { + this.props.setMapDimensions( + jQuery(window).width(), + jQuery(window).height() - NAVBAR_HEIGHT + ); + } - updateScale(e) { - e.preventDefault(); - this.props.zoomInOnPosition(e.deltaY < 0, this.state.mouseX, this.state.mouseY); - } + updateScale(e) { + e.preventDefault(); + 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}); - } + updateMousePosition() { + const mousePos = this.stage.getStage().getPointerPosition(); + 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; - } + 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; } + } - moveWithDelta(deltaX, deltaY) { - this.props.setMapPositionWithBoundsCheck(this.props.mapPosition.x + deltaX, this.props.mapPosition.y + deltaY); - } + moveWithDelta(deltaX, deltaY) { + this.props.setMapPositionWithBoundsCheck( + this.props.mapPosition.x + deltaX, + this.props.mapPosition.y + deltaY + ); + } - render() { - return ( - <Shortcuts name="MAP" handler={this.handleShortcuts.bind(this)} targetNodeSelector="body"> - <Stage - ref={(stage) => { - this.stage = stage; - }} - width={this.props.mapDimensions.width} - height={this.props.mapDimensions.height} - onMouseMove={this.updateMousePosition.bind(this)} - > - <MapLayer/> - <RoomHoverLayer - mouseX={this.state.mouseX} - mouseY={this.state.mouseY} - /> - <ObjectHoverLayer - mouseX={this.state.mouseX} - mouseY={this.state.mouseY} - /> - </Stage> - </Shortcuts> - ) - } + render() { + return ( + <Shortcuts + name="MAP" + handler={this.handleShortcuts.bind(this)} + targetNodeSelector="body" + > + <Stage + ref={stage => { + this.stage = stage; + }} + width={this.props.mapDimensions.width} + height={this.props.mapDimensions.height} + onMouseMove={this.updateMousePosition.bind(this)} + > + <MapLayer /> + <RoomHoverLayer + mouseX={this.state.mouseX} + mouseY={this.state.mouseY} + /> + <ObjectHoverLayer + mouseX={this.state.mouseX} + mouseY={this.state.mouseY} + /> + </Stage> + </Shortcuts> + ); + } } export default MapStageComponent; diff --git a/src/components/app/map/controls/ExportCanvasComponent.js b/src/components/app/map/controls/ExportCanvasComponent.js index 2f044ffe..ee934f21 100644 --- a/src/components/app/map/controls/ExportCanvasComponent.js +++ b/src/components/app/map/controls/ExportCanvasComponent.js @@ -1,13 +1,13 @@ import React from "react"; const ExportCanvasComponent = () => ( - <button - className="btn btn-success btn-circle btn-sm" - title="Export Canvas to PNG Image" - onClick={() => window["exportCanvasToImage"]()} - > - <span className="fa fa-camera"/> - </button> + <button + className="btn btn-success btn-circle btn-sm" + title="Export Canvas to PNG Image" + onClick={() => window["exportCanvasToImage"]()} + > + <span className="fa fa-camera" /> + </button> ); export default ExportCanvasComponent; diff --git a/src/components/app/map/controls/ScaleIndicatorComponent.js b/src/components/app/map/controls/ScaleIndicatorComponent.js index fd9483b5..b7b5cc36 100644 --- a/src/components/app/map/controls/ScaleIndicatorComponent.js +++ b/src/components/app/map/controls/ScaleIndicatorComponent.js @@ -1,14 +1,14 @@ import React from "react"; -import {TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from "../MapConstants"; import "./ScaleIndicatorComponent.css"; -const ScaleIndicatorComponent = ({scale}) => ( - <div - className="scale-indicator" - style={{width: TILE_SIZE_IN_PIXELS * scale}} - > - {TILE_SIZE_IN_METERS}m - </div> +const ScaleIndicatorComponent = ({ scale }) => ( + <div + className="scale-indicator" + style={{ width: TILE_SIZE_IN_PIXELS * scale }} + > + {TILE_SIZE_IN_METERS}m + </div> ); export default ScaleIndicatorComponent; diff --git a/src/components/app/map/controls/ToolPanelComponent.js b/src/components/app/map/controls/ToolPanelComponent.js index a065358a..605e9887 100644 --- a/src/components/app/map/controls/ToolPanelComponent.js +++ b/src/components/app/map/controls/ToolPanelComponent.js @@ -4,10 +4,10 @@ import ExportCanvasComponent from "./ExportCanvasComponent"; import "./ToolPanelComponent.css"; const ToolPanelComponent = () => ( - <div className="tool-panel"> - <ZoomControlContainer/> - <ExportCanvasComponent/> - </div> + <div className="tool-panel"> + <ZoomControlContainer /> + <ExportCanvasComponent /> + </div> ); export default ToolPanelComponent; diff --git a/src/components/app/map/controls/ZoomControlComponent.js b/src/components/app/map/controls/ZoomControlComponent.js index 8406e8c1..e1b7491e 100644 --- a/src/components/app/map/controls/ZoomControlComponent.js +++ b/src/components/app/map/controls/ZoomControlComponent.js @@ -1,24 +1,24 @@ import React from "react"; -const ZoomControlComponent = ({zoomInOnCenter}) => { - return ( - <span> - <button - className="btn btn-default btn-circle btn-sm mr-1" - title="Zoom in" - onClick={() => zoomInOnCenter(true)} - > - <span className="fa fa-plus"/> - </button> - <button - className="btn btn-default btn-circle btn-sm mr-1" - title="Zoom out" - onClick={() => zoomInOnCenter(false)} - > - <span className="fa fa-minus"/> - </button> - </span> - ); +const ZoomControlComponent = ({ zoomInOnCenter }) => { + return ( + <span> + <button + className="btn btn-default btn-circle btn-sm mr-1" + title="Zoom in" + onClick={() => zoomInOnCenter(true)} + > + <span className="fa fa-plus" /> + </button> + <button + className="btn btn-default btn-circle btn-sm mr-1" + title="Zoom out" + onClick={() => zoomInOnCenter(false)} + > + <span className="fa fa-minus" /> + </button> + </span> + ); }; export default ZoomControlComponent; diff --git a/src/components/app/map/elements/Backdrop.js b/src/components/app/map/elements/Backdrop.js index 9c01df63..57414463 100644 --- a/src/components/app/map/elements/Backdrop.js +++ b/src/components/app/map/elements/Backdrop.js @@ -1,16 +1,16 @@ import React from "react"; -import {Rect} from "react-konva"; -import {BACKDROP_COLOR} from "../../../../util/colors"; -import {MAP_SIZE_IN_PIXELS} from "../MapConstants"; +import { Rect } from "react-konva"; +import { BACKDROP_COLOR } from "../../../../util/colors"; +import { MAP_SIZE_IN_PIXELS } from "../MapConstants"; const Backdrop = () => ( - <Rect - x={0} - y={0} - width={MAP_SIZE_IN_PIXELS} - height={MAP_SIZE_IN_PIXELS} - fill={BACKDROP_COLOR} - /> + <Rect + x={0} + y={0} + width={MAP_SIZE_IN_PIXELS} + height={MAP_SIZE_IN_PIXELS} + fill={BACKDROP_COLOR} + /> ); export default Backdrop; diff --git a/src/components/app/map/elements/GrayLayer.js b/src/components/app/map/elements/GrayLayer.js index c5994d06..28fadd8a 100644 --- a/src/components/app/map/elements/GrayLayer.js +++ b/src/components/app/map/elements/GrayLayer.js @@ -1,17 +1,17 @@ import React from "react"; -import {Rect} from "react-konva"; -import {GRAYED_OUT_AREA_COLOR} from "../../../../util/colors"; -import {MAP_SIZE_IN_PIXELS} from "../MapConstants"; +import { Rect } from "react-konva"; +import { GRAYED_OUT_AREA_COLOR } from "../../../../util/colors"; +import { MAP_SIZE_IN_PIXELS } from "../MapConstants"; -const GrayLayer = ({onClick}) => ( - <Rect - x={0} - y={0} - width={MAP_SIZE_IN_PIXELS} - height={MAP_SIZE_IN_PIXELS} - fill={GRAYED_OUT_AREA_COLOR} - onClick={onClick} - /> +const GrayLayer = ({ onClick }) => ( + <Rect + x={0} + y={0} + width={MAP_SIZE_IN_PIXELS} + height={MAP_SIZE_IN_PIXELS} + fill={GRAYED_OUT_AREA_COLOR} + onClick={onClick} + /> ); export default GrayLayer; diff --git a/src/components/app/map/elements/HoverTile.js b/src/components/app/map/elements/HoverTile.js index fc12cbdd..42e6547c 100644 --- a/src/components/app/map/elements/HoverTile.js +++ b/src/components/app/map/elements/HoverTile.js @@ -1,27 +1,30 @@ import PropTypes from "prop-types"; import React from "react"; -import {Rect} from "react-konva"; -import {ROOM_HOVER_INVALID_COLOR, ROOM_HOVER_VALID_COLOR} from "../../../../util/colors"; -import {TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { Rect } from "react-konva"; +import { + ROOM_HOVER_INVALID_COLOR, + ROOM_HOVER_VALID_COLOR +} from "../../../../util/colors"; +import { TILE_SIZE_IN_PIXELS } from "../MapConstants"; -const HoverTile = ({pixelX, pixelY, isValid, scale, onClick}) => ( - <Rect - x={pixelX} - y={pixelY} - scaleX={scale} - scaleY={scale} - width={TILE_SIZE_IN_PIXELS} - height={TILE_SIZE_IN_PIXELS} - fill={isValid ? ROOM_HOVER_VALID_COLOR : ROOM_HOVER_INVALID_COLOR} - onClick={onClick} - /> +const HoverTile = ({ pixelX, pixelY, isValid, scale, onClick }) => ( + <Rect + x={pixelX} + y={pixelY} + scaleX={scale} + scaleY={scale} + width={TILE_SIZE_IN_PIXELS} + height={TILE_SIZE_IN_PIXELS} + fill={isValid ? ROOM_HOVER_VALID_COLOR : ROOM_HOVER_INVALID_COLOR} + onClick={onClick} + /> ); HoverTile.propTypes = { - pixelX: PropTypes.number.isRequired, - pixelY: PropTypes.number.isRequired, - isValid: PropTypes.bool.isRequired, - onClick: PropTypes.func.isRequired, + pixelX: PropTypes.number.isRequired, + pixelY: PropTypes.number.isRequired, + isValid: PropTypes.bool.isRequired, + onClick: PropTypes.func.isRequired }; export default HoverTile; diff --git a/src/components/app/map/elements/ImageComponent.js b/src/components/app/map/elements/ImageComponent.js index 486296ea..cf41ddfe 100644 --- a/src/components/app/map/elements/ImageComponent.js +++ b/src/components/app/map/elements/ImageComponent.js @@ -1,48 +1,48 @@ import PropTypes from "prop-types"; import React from "react"; -import {Image} from "react-konva"; +import { Image } from "react-konva"; class ImageComponent extends React.Component { - static imageCaches = {}; - static propTypes = { - src: PropTypes.string.isRequired, - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - width: PropTypes.number.isRequired, - height: PropTypes.number.isRequired, - opacity: PropTypes.number.isRequired, - }; - - state = { - image: null - }; + static imageCaches = {}; + static propTypes = { + src: PropTypes.string.isRequired, + x: PropTypes.number.isRequired, + y: PropTypes.number.isRequired, + width: PropTypes.number.isRequired, + height: PropTypes.number.isRequired, + opacity: PropTypes.number.isRequired + }; - componentDidMount() { - if (ImageComponent.imageCaches[this.props.src]) { - this.setState({image: ImageComponent.imageCaches[this.props.src]}); - return; - } + state = { + image: null + }; - const image = new window.Image(); - image.src = this.props.src; - image.onload = () => { - this.setState({image}); - ImageComponent.imageCaches[this.props.src] = image; - } + componentDidMount() { + if (ImageComponent.imageCaches[this.props.src]) { + this.setState({ image: ImageComponent.imageCaches[this.props.src] }); + return; } - render() { - return ( - <Image - image={this.state.image} - x={this.props.x} - y={this.props.y} - width={this.props.width} - height={this.props.height} - opacity={this.props.opacity} - /> - ) - } + const image = new window.Image(); + image.src = this.props.src; + image.onload = () => { + this.setState({ image }); + ImageComponent.imageCaches[this.props.src] = image; + }; + } + + render() { + return ( + <Image + image={this.state.image} + x={this.props.x} + y={this.props.y} + width={this.props.width} + height={this.props.height} + opacity={this.props.opacity} + /> + ); + } } export default ImageComponent; diff --git a/src/components/app/map/elements/RackFillBar.js b/src/components/app/map/elements/RackFillBar.js index 3a8a1137..43701d97 100644 --- a/src/components/app/map/elements/RackFillBar.js +++ b/src/components/app/map/elements/RackFillBar.js @@ -1,67 +1,89 @@ import PropTypes from "prop-types"; import React from "react"; -import {Group, Rect} from "react-konva"; +import { Group, Rect } from "react-konva"; import { - RACK_ENERGY_BAR_BACKGROUND_COLOR, - RACK_ENERGY_BAR_FILL_COLOR, - RACK_SPACE_BAR_BACKGROUND_COLOR, - RACK_SPACE_BAR_FILL_COLOR + RACK_ENERGY_BAR_BACKGROUND_COLOR, + RACK_ENERGY_BAR_FILL_COLOR, + RACK_SPACE_BAR_BACKGROUND_COLOR, + RACK_SPACE_BAR_FILL_COLOR } from "../../../../util/colors"; import { - OBJECT_BORDER_WIDTH_IN_PIXELS, - OBJECT_MARGIN_IN_PIXELS, - RACK_FILL_ICON_OPACITY, - RACK_FILL_ICON_WIDTH, - TILE_SIZE_IN_PIXELS + OBJECT_BORDER_WIDTH_IN_PIXELS, + OBJECT_MARGIN_IN_PIXELS, + RACK_FILL_ICON_OPACITY, + RACK_FILL_ICON_WIDTH, + TILE_SIZE_IN_PIXELS } from "../MapConstants"; import ImageComponent from "./ImageComponent"; -const RackFillBar = ({positionX, positionY, type, fillFraction}) => { - const halfOfObjectBorderWidth = OBJECT_BORDER_WIDTH_IN_PIXELS / 2; - const x = positionX * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS - + (type === "space" ? halfOfObjectBorderWidth : - 0.5 * (TILE_SIZE_IN_PIXELS - 2 * OBJECT_MARGIN_IN_PIXELS)); - const startY = positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS + halfOfObjectBorderWidth; - const width = 0.5 * (TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2) - halfOfObjectBorderWidth; - const fullHeight = TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2 - OBJECT_BORDER_WIDTH_IN_PIXELS; +const RackFillBar = ({ positionX, positionY, type, fillFraction }) => { + const halfOfObjectBorderWidth = OBJECT_BORDER_WIDTH_IN_PIXELS / 2; + const x = + positionX * TILE_SIZE_IN_PIXELS + + OBJECT_MARGIN_IN_PIXELS + + (type === "space" + ? halfOfObjectBorderWidth + : 0.5 * (TILE_SIZE_IN_PIXELS - 2 * OBJECT_MARGIN_IN_PIXELS)); + const startY = + positionY * TILE_SIZE_IN_PIXELS + + OBJECT_MARGIN_IN_PIXELS + + halfOfObjectBorderWidth; + const width = + 0.5 * (TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2) - + halfOfObjectBorderWidth; + const fullHeight = + TILE_SIZE_IN_PIXELS - + OBJECT_MARGIN_IN_PIXELS * 2 - + OBJECT_BORDER_WIDTH_IN_PIXELS; - const fractionHeight = fillFraction * fullHeight; - const fractionY = (positionY + 1) * TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS - halfOfObjectBorderWidth - - fractionHeight; + const fractionHeight = fillFraction * fullHeight; + const fractionY = + (positionY + 1) * TILE_SIZE_IN_PIXELS - + OBJECT_MARGIN_IN_PIXELS - + halfOfObjectBorderWidth - + fractionHeight; - return ( - <Group> - <Rect - x={x} - y={startY} - width={width} - height={fullHeight} - fill={type === "space" ? RACK_SPACE_BAR_BACKGROUND_COLOR : RACK_ENERGY_BAR_BACKGROUND_COLOR} - /> - <Rect - x={x} - y={fractionY} - width={width} - height={fractionHeight} - fill={type === "space" ? RACK_SPACE_BAR_FILL_COLOR : RACK_ENERGY_BAR_FILL_COLOR} - /> - <ImageComponent - src={"/img/topology/rack-" + type + "-icon.png"} - x={x + width * 0.5 - RACK_FILL_ICON_WIDTH * 0.5} - y={startY + fullHeight * 0.5 - RACK_FILL_ICON_WIDTH * 0.5} - width={RACK_FILL_ICON_WIDTH} - height={RACK_FILL_ICON_WIDTH} - opacity={RACK_FILL_ICON_OPACITY} - /> - </Group> - ); + return ( + <Group> + <Rect + x={x} + y={startY} + width={width} + height={fullHeight} + fill={ + type === "space" + ? RACK_SPACE_BAR_BACKGROUND_COLOR + : RACK_ENERGY_BAR_BACKGROUND_COLOR + } + /> + <Rect + x={x} + y={fractionY} + width={width} + height={fractionHeight} + fill={ + type === "space" + ? RACK_SPACE_BAR_FILL_COLOR + : RACK_ENERGY_BAR_FILL_COLOR + } + /> + <ImageComponent + src={"/img/topology/rack-" + type + "-icon.png"} + x={x + width * 0.5 - RACK_FILL_ICON_WIDTH * 0.5} + y={startY + fullHeight * 0.5 - RACK_FILL_ICON_WIDTH * 0.5} + width={RACK_FILL_ICON_WIDTH} + height={RACK_FILL_ICON_WIDTH} + opacity={RACK_FILL_ICON_OPACITY} + /> + </Group> + ); }; RackFillBar.propTypes = { - positionX: PropTypes.number.isRequired, - positionY: PropTypes.number.isRequired, - type: PropTypes.string.isRequired, - fillFraction: PropTypes.number.isRequired, + positionX: PropTypes.number.isRequired, + positionY: PropTypes.number.isRequired, + type: PropTypes.string.isRequired, + fillFraction: PropTypes.number.isRequired }; export default RackFillBar; diff --git a/src/components/app/map/elements/RoomTile.js b/src/components/app/map/elements/RoomTile.js index 11948a7a..71c3bf15 100644 --- a/src/components/app/map/elements/RoomTile.js +++ b/src/components/app/map/elements/RoomTile.js @@ -1,20 +1,20 @@ import React from "react"; -import {Rect} from "react-konva"; +import { Rect } from "react-konva"; import Shapes from "../../../../shapes/index"; -import {TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { TILE_SIZE_IN_PIXELS } from "../MapConstants"; -const RoomTile = ({tile, color}) => ( - <Rect - x={tile.positionX * TILE_SIZE_IN_PIXELS} - y={tile.positionY * TILE_SIZE_IN_PIXELS} - width={TILE_SIZE_IN_PIXELS} - height={TILE_SIZE_IN_PIXELS} - fill={color} - /> +const RoomTile = ({ tile, color }) => ( + <Rect + x={tile.positionX * TILE_SIZE_IN_PIXELS} + y={tile.positionY * TILE_SIZE_IN_PIXELS} + width={TILE_SIZE_IN_PIXELS} + height={TILE_SIZE_IN_PIXELS} + fill={color} + /> ); RoomTile.propTypes = { - tile: Shapes.Tile, + tile: Shapes.Tile }; export default RoomTile; diff --git a/src/components/app/map/elements/TileObject.js b/src/components/app/map/elements/TileObject.js index 73bfddba..c1b631db 100644 --- a/src/components/app/map/elements/TileObject.js +++ b/src/components/app/map/elements/TileObject.js @@ -1,25 +1,29 @@ import PropTypes from "prop-types"; import React from "react"; -import {Rect} from "react-konva"; -import {OBJECT_BORDER_COLOR} from "../../../../util/colors"; -import {OBJECT_BORDER_WIDTH_IN_PIXELS, OBJECT_MARGIN_IN_PIXELS, TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { Rect } from "react-konva"; +import { OBJECT_BORDER_COLOR } from "../../../../util/colors"; +import { + OBJECT_BORDER_WIDTH_IN_PIXELS, + OBJECT_MARGIN_IN_PIXELS, + TILE_SIZE_IN_PIXELS +} from "../MapConstants"; -const TileObject = ({positionX, positionY, color}) => ( - <Rect - x={positionX * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS} - y={positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS} - width={TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2} - height={TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2} - fill={color} - stroke={OBJECT_BORDER_COLOR} - strokeWidth={OBJECT_BORDER_WIDTH_IN_PIXELS} - /> +const TileObject = ({ positionX, positionY, color }) => ( + <Rect + x={positionX * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS} + y={positionY * TILE_SIZE_IN_PIXELS + OBJECT_MARGIN_IN_PIXELS} + width={TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2} + height={TILE_SIZE_IN_PIXELS - OBJECT_MARGIN_IN_PIXELS * 2} + fill={color} + stroke={OBJECT_BORDER_COLOR} + strokeWidth={OBJECT_BORDER_WIDTH_IN_PIXELS} + /> ); TileObject.propTypes = { - positionX: PropTypes.number.isRequired, - positionY: PropTypes.number.isRequired, - color: PropTypes.string.isRequired, + positionX: PropTypes.number.isRequired, + positionY: PropTypes.number.isRequired, + color: PropTypes.string.isRequired }; export default TileObject; diff --git a/src/components/app/map/elements/TilePlusIcon.js b/src/components/app/map/elements/TilePlusIcon.js index b96bf0f5..06377152 100644 --- a/src/components/app/map/elements/TilePlusIcon.js +++ b/src/components/app/map/elements/TilePlusIcon.js @@ -1,44 +1,52 @@ import PropTypes from "prop-types"; import React from "react"; -import {Group, Line} from "react-konva"; -import {TILE_PLUS_COLOR} from "../../../../util/colors"; -import {TILE_PLUS_MARGIN_IN_PIXELS, TILE_PLUS_WIDTH_IN_PIXELS, TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { Group, Line } from "react-konva"; +import { TILE_PLUS_COLOR } from "../../../../util/colors"; +import { + TILE_PLUS_MARGIN_IN_PIXELS, + TILE_PLUS_WIDTH_IN_PIXELS, + TILE_SIZE_IN_PIXELS +} from "../MapConstants"; -const TilePlusIcon = ({pixelX, pixelY, mapScale}) => { - const linePoints = [ - [ - pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - pixelY + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - pixelY + TILE_SIZE_IN_PIXELS * mapScale - TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - ], - [ - pixelX + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - pixelX + TILE_SIZE_IN_PIXELS * mapScale - TILE_PLUS_MARGIN_IN_PIXELS * mapScale, - pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, - ], - ]; - return ( - <Group> - {linePoints.map((points, index) => ( - <Line - key={index} - points={points} - lineCap="round" - stroke={TILE_PLUS_COLOR} - strokeWidth={TILE_PLUS_WIDTH_IN_PIXELS * mapScale} - listening={false} - /> - ))} - </Group> - ) +const TilePlusIcon = ({ pixelX, pixelY, mapScale }) => { + const linePoints = [ + [ + pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, + pixelY + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, + pixelX + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, + pixelY + + TILE_SIZE_IN_PIXELS * mapScale - + TILE_PLUS_MARGIN_IN_PIXELS * mapScale + ], + [ + pixelX + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, + pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale, + pixelX + + TILE_SIZE_IN_PIXELS * mapScale - + TILE_PLUS_MARGIN_IN_PIXELS * mapScale, + pixelY + 0.5 * TILE_SIZE_IN_PIXELS * mapScale + ] + ]; + return ( + <Group> + {linePoints.map((points, index) => ( + <Line + key={index} + points={points} + lineCap="round" + stroke={TILE_PLUS_COLOR} + strokeWidth={TILE_PLUS_WIDTH_IN_PIXELS * mapScale} + listening={false} + /> + ))} + </Group> + ); }; TilePlusIcon.propTypes = { - pixelX: PropTypes.number, - pixelY: PropTypes.number, - mapScale: PropTypes.number, + pixelX: PropTypes.number, + pixelY: PropTypes.number, + mapScale: PropTypes.number }; export default TilePlusIcon; diff --git a/src/components/app/map/elements/WallSegment.js b/src/components/app/map/elements/WallSegment.js index 14efd3fc..c5011656 100644 --- a/src/components/app/map/elements/WallSegment.js +++ b/src/components/app/map/elements/WallSegment.js @@ -1,39 +1,39 @@ import React from "react"; -import {Line} from "react-konva"; +import { Line } from "react-konva"; import Shapes from "../../../../shapes/index"; -import {WALL_COLOR} from "../../../../util/colors"; -import {TILE_SIZE_IN_PIXELS, WALL_WIDTH_IN_PIXELS} from "../MapConstants"; +import { WALL_COLOR } from "../../../../util/colors"; +import { TILE_SIZE_IN_PIXELS, WALL_WIDTH_IN_PIXELS } from "../MapConstants"; -const WallSegment = ({wallSegment}) => { - let points; - if (wallSegment.isHorizontal) { - points = [ - wallSegment.startPosX * TILE_SIZE_IN_PIXELS, - wallSegment.startPosY * TILE_SIZE_IN_PIXELS, - (wallSegment.startPosX + wallSegment.length) * TILE_SIZE_IN_PIXELS, - wallSegment.startPosY * TILE_SIZE_IN_PIXELS - ]; - } else { - points = [ - wallSegment.startPosX * TILE_SIZE_IN_PIXELS, - wallSegment.startPosY * TILE_SIZE_IN_PIXELS, - wallSegment.startPosX * TILE_SIZE_IN_PIXELS, - (wallSegment.startPosY + wallSegment.length) * TILE_SIZE_IN_PIXELS, - ]; - } +const WallSegment = ({ wallSegment }) => { + let points; + if (wallSegment.isHorizontal) { + points = [ + wallSegment.startPosX * TILE_SIZE_IN_PIXELS, + wallSegment.startPosY * TILE_SIZE_IN_PIXELS, + (wallSegment.startPosX + wallSegment.length) * TILE_SIZE_IN_PIXELS, + wallSegment.startPosY * TILE_SIZE_IN_PIXELS + ]; + } else { + points = [ + wallSegment.startPosX * TILE_SIZE_IN_PIXELS, + wallSegment.startPosY * TILE_SIZE_IN_PIXELS, + wallSegment.startPosX * TILE_SIZE_IN_PIXELS, + (wallSegment.startPosY + wallSegment.length) * TILE_SIZE_IN_PIXELS + ]; + } - return ( - <Line - points={points} - lineCap="round" - stroke={WALL_COLOR} - strokeWidth={WALL_WIDTH_IN_PIXELS} - /> - ) + return ( + <Line + points={points} + lineCap="round" + stroke={WALL_COLOR} + strokeWidth={WALL_WIDTH_IN_PIXELS} + /> + ); }; WallSegment.propTypes = { - wallSegment: Shapes.WallSegment, + wallSegment: Shapes.WallSegment }; export default WallSegment; diff --git a/src/components/app/map/groups/DatacenterGroup.js b/src/components/app/map/groups/DatacenterGroup.js index 1c978360..51e32db6 100644 --- a/src/components/app/map/groups/DatacenterGroup.js +++ b/src/components/app/map/groups/DatacenterGroup.js @@ -1,42 +1,40 @@ import React from "react"; -import {Group} from "react-konva"; +import { Group } from "react-konva"; import GrayContainer from "../../../../containers/app/map/GrayContainer"; import RoomContainer from "../../../../containers/app/map/RoomContainer"; import Shapes from "../../../../shapes/index"; -const DatacenterGroup = ({datacenter, interactionLevel}) => { - if (!datacenter) { - return <Group/>; - } - - if (interactionLevel.mode === "BUILDING") { - return ( - <Group> - {datacenter.roomIds.map(roomId => ( - <RoomContainer key={roomId} roomId={roomId}/> - ))} - </Group> - ); - } +const DatacenterGroup = ({ datacenter, interactionLevel }) => { + if (!datacenter) { + return <Group />; + } + if (interactionLevel.mode === "BUILDING") { return ( - <Group> - {datacenter.roomIds - .filter(roomId => roomId !== interactionLevel.roomId) - .map(roomId => <RoomContainer key={roomId} roomId={roomId}/>) - } - {interactionLevel.mode === "ROOM" ? <GrayContainer/> : null} - {datacenter.roomIds - .filter(roomId => roomId === interactionLevel.roomId) - .map(roomId => <RoomContainer key={roomId} roomId={roomId}/>) - } - </Group> + <Group> + {datacenter.roomIds.map(roomId => ( + <RoomContainer key={roomId} roomId={roomId} /> + ))} + </Group> ); + } + + return ( + <Group> + {datacenter.roomIds + .filter(roomId => roomId !== interactionLevel.roomId) + .map(roomId => <RoomContainer key={roomId} roomId={roomId} />)} + {interactionLevel.mode === "ROOM" ? <GrayContainer /> : null} + {datacenter.roomIds + .filter(roomId => roomId === interactionLevel.roomId) + .map(roomId => <RoomContainer key={roomId} roomId={roomId} />)} + </Group> + ); }; DatacenterGroup.propTypes = { - datacenter: Shapes.Datacenter, - interactionLevel: Shapes.InteractionLevel, + datacenter: Shapes.Datacenter, + interactionLevel: Shapes.InteractionLevel }; export default DatacenterGroup; diff --git a/src/components/app/map/groups/GridGroup.js b/src/components/app/map/groups/GridGroup.js index b3c6e1d5..bbb1eb68 100644 --- a/src/components/app/map/groups/GridGroup.js +++ b/src/components/app/map/groups/GridGroup.js @@ -1,30 +1,41 @@ import React from "react"; -import {Group, Line} from "react-konva"; -import {GRID_COLOR} from "../../../../util/colors"; -import {GRID_LINE_WIDTH_IN_PIXELS, MAP_SIZE, MAP_SIZE_IN_PIXELS, TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { Group, Line } from "react-konva"; +import { GRID_COLOR } from "../../../../util/colors"; +import { + GRID_LINE_WIDTH_IN_PIXELS, + MAP_SIZE, + MAP_SIZE_IN_PIXELS, + TILE_SIZE_IN_PIXELS +} from "../MapConstants"; const MAP_COORDINATE_ENTRIES = Array.from(new Array(MAP_SIZE), (x, i) => i); const HORIZONTAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map(index => [ - 0, index * TILE_SIZE_IN_PIXELS, - MAP_SIZE_IN_PIXELS, index * TILE_SIZE_IN_PIXELS + 0, + index * TILE_SIZE_IN_PIXELS, + MAP_SIZE_IN_PIXELS, + index * TILE_SIZE_IN_PIXELS ]); const VERTICAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map(index => [ - index * TILE_SIZE_IN_PIXELS, 0, - index * TILE_SIZE_IN_PIXELS, MAP_SIZE_IN_PIXELS + index * TILE_SIZE_IN_PIXELS, + 0, + index * TILE_SIZE_IN_PIXELS, + MAP_SIZE_IN_PIXELS ]); const GridGroup = () => ( - <Group> - {HORIZONTAL_POINT_PAIRS.concat(VERTICAL_POINT_PAIRS).map((points, index) => ( - <Line - key={index} - points={points} - stroke={GRID_COLOR} - strokeWidth={GRID_LINE_WIDTH_IN_PIXELS} - listening={false} - /> - ))} - </Group> + <Group> + {HORIZONTAL_POINT_PAIRS.concat( + VERTICAL_POINT_PAIRS + ).map((points, index) => ( + <Line + key={index} + points={points} + stroke={GRID_COLOR} + strokeWidth={GRID_LINE_WIDTH_IN_PIXELS} + listening={false} + /> + ))} + </Group> ); export default GridGroup; diff --git a/src/components/app/map/groups/RackGroup.js b/src/components/app/map/groups/RackGroup.js index 57062187..69d6ac10 100644 --- a/src/components/app/map/groups/RackGroup.js +++ b/src/components/app/map/groups/RackGroup.js @@ -1,31 +1,43 @@ import React from "react"; -import {Group} from "react-konva"; +import { Group } from "react-konva"; import RackEnergyFillContainer from "../../../../containers/app/map/RackEnergyFillContainer"; import RackSpaceFillContainer from "../../../../containers/app/map/RackSpaceFillContainer"; import Shapes from "../../../../shapes/index"; -import {RACK_BACKGROUND_COLOR} from "../../../../util/colors"; -import {convertLoadToSimulationColor} from "../../../../util/simulation-load"; +import { RACK_BACKGROUND_COLOR } from "../../../../util/colors"; +import { convertLoadToSimulationColor } from "../../../../util/simulation-load"; import TileObject from "../elements/TileObject"; -const RackGroup = ({tile, inSimulation, rackLoad}) => { - let color = RACK_BACKGROUND_COLOR; - if (inSimulation && rackLoad >= 0) { - color = convertLoadToSimulationColor(rackLoad); - } +const RackGroup = ({ tile, inSimulation, rackLoad }) => { + let color = RACK_BACKGROUND_COLOR; + if (inSimulation && rackLoad >= 0) { + color = convertLoadToSimulationColor(rackLoad); + } - return ( - <Group> - <TileObject positionX={tile.positionX} positionY={tile.positionY} color={color}/> - <Group opacity={inSimulation ? 0.3 : 1}> - <RackSpaceFillContainer tileId={tile.id} positionX={tile.positionX} positionY={tile.positionY}/> - <RackEnergyFillContainer tileId={tile.id} positionX={tile.positionX} positionY={tile.positionY}/> - </Group> - </Group> - ); + return ( + <Group> + <TileObject + positionX={tile.positionX} + positionY={tile.positionY} + color={color} + /> + <Group opacity={inSimulation ? 0.3 : 1}> + <RackSpaceFillContainer + tileId={tile.id} + positionX={tile.positionX} + positionY={tile.positionY} + /> + <RackEnergyFillContainer + tileId={tile.id} + positionX={tile.positionX} + positionY={tile.positionY} + /> + </Group> + </Group> + ); }; RackGroup.propTypes = { - tile: Shapes.Tile, + tile: Shapes.Tile }; export default RackGroup; diff --git a/src/components/app/map/groups/RoomGroup.js b/src/components/app/map/groups/RoomGroup.js index 18a6bd84..c8f0d3db 100644 --- a/src/components/app/map/groups/RoomGroup.js +++ b/src/components/app/map/groups/RoomGroup.js @@ -1,48 +1,56 @@ import React from "react"; -import {Group} from "react-konva"; +import { Group } from "react-konva"; import GrayContainer from "../../../../containers/app/map/GrayContainer"; import TileContainer from "../../../../containers/app/map/TileContainer"; import WallContainer from "../../../../containers/app/map/WallContainer"; import Shapes from "../../../../shapes/index"; -const RoomGroup = ({room, interactionLevel, currentRoomInConstruction, onClick}) => { - if (currentRoomInConstruction === room.id) { - return ( - <Group onClick={onClick}> - {room.tileIds.map(tileId => ( - <TileContainer key={tileId} tileId={tileId} newTile={true}/> - ))} - </Group> - ); - } - +const RoomGroup = ({ + room, + interactionLevel, + currentRoomInConstruction, + onClick +}) => { + if (currentRoomInConstruction === room.id) { return ( - <Group onClick={onClick}> - {(() => { - if ((interactionLevel.mode === "RACK" || interactionLevel.mode === "MACHINE") - && interactionLevel.roomId === room.id) { - return [ - room.tileIds - .filter(tileId => tileId !== interactionLevel.tileId) - .map(tileId => <TileContainer key={tileId} tileId={tileId}/>), - <GrayContainer key={-1}/>, - room.tileIds - .filter(tileId => tileId === interactionLevel.tileId) - .map(tileId => <TileContainer key={tileId} tileId={tileId}/>) - ]; - } else { - return room.tileIds.map(tileId => ( - <TileContainer key={tileId} tileId={tileId}/> - )); - } - })()} - <WallContainer roomId={room.id}/> - </Group> + <Group onClick={onClick}> + {room.tileIds.map(tileId => ( + <TileContainer key={tileId} tileId={tileId} newTile={true} /> + ))} + </Group> ); + } + + return ( + <Group onClick={onClick}> + {(() => { + if ( + (interactionLevel.mode === "RACK" || + interactionLevel.mode === "MACHINE") && + interactionLevel.roomId === room.id + ) { + return [ + room.tileIds + .filter(tileId => tileId !== interactionLevel.tileId) + .map(tileId => <TileContainer key={tileId} tileId={tileId} />), + <GrayContainer key={-1} />, + room.tileIds + .filter(tileId => tileId === interactionLevel.tileId) + .map(tileId => <TileContainer key={tileId} tileId={tileId} />) + ]; + } else { + return room.tileIds.map(tileId => ( + <TileContainer key={tileId} tileId={tileId} /> + )); + } + })()} + <WallContainer roomId={room.id} /> + </Group> + ); }; RoomGroup.propTypes = { - room: Shapes.Room, + room: Shapes.Room }; export default RoomGroup; diff --git a/src/components/app/map/groups/TileGroup.js b/src/components/app/map/groups/TileGroup.js index 0cd4ea59..8f3953d7 100644 --- a/src/components/app/map/groups/TileGroup.js +++ b/src/components/app/map/groups/TileGroup.js @@ -1,42 +1,43 @@ import PropTypes from "prop-types"; import React from "react"; -import {Group} from "react-konva"; +import { Group } from "react-konva"; import RackContainer from "../../../../containers/app/map/RackContainer"; import Shapes from "../../../../shapes/index"; -import {ROOM_DEFAULT_COLOR, ROOM_IN_CONSTRUCTION_COLOR} from "../../../../util/colors"; -import {convertLoadToSimulationColor} from "../../../../util/simulation-load"; +import { + ROOM_DEFAULT_COLOR, + ROOM_IN_CONSTRUCTION_COLOR +} from "../../../../util/colors"; +import { convertLoadToSimulationColor } from "../../../../util/simulation-load"; import RoomTile from "../elements/RoomTile"; -const TileGroup = ({tile, newTile, inSimulation, roomLoad, onClick}) => { - let tileObject; - switch (tile.objectType) { - case "RACK": - tileObject = <RackContainer tile={tile}/>; - break; - default: - tileObject = null; - } +const TileGroup = ({ tile, newTile, inSimulation, roomLoad, onClick }) => { + let tileObject; + switch (tile.objectType) { + case "RACK": + tileObject = <RackContainer tile={tile} />; + break; + default: + tileObject = null; + } - let color = ROOM_DEFAULT_COLOR; - if (newTile) { - color = ROOM_IN_CONSTRUCTION_COLOR; - } else if (inSimulation && roomLoad >= 0) { - color = convertLoadToSimulationColor(roomLoad); - } + let color = ROOM_DEFAULT_COLOR; + if (newTile) { + color = ROOM_IN_CONSTRUCTION_COLOR; + } else if (inSimulation && roomLoad >= 0) { + color = convertLoadToSimulationColor(roomLoad); + } - return ( - <Group - onClick={() => onClick(tile)} - > - <RoomTile tile={tile} color={color}/> - {tileObject} - </Group> - ); + return ( + <Group onClick={() => onClick(tile)}> + <RoomTile tile={tile} color={color} /> + {tileObject} + </Group> + ); }; TileGroup.propTypes = { - tile: Shapes.Tile, - newTile: PropTypes.bool, + tile: Shapes.Tile, + newTile: PropTypes.bool }; export default TileGroup; diff --git a/src/components/app/map/groups/WallGroup.js b/src/components/app/map/groups/WallGroup.js index 6de22523..43de66e8 100644 --- a/src/components/app/map/groups/WallGroup.js +++ b/src/components/app/map/groups/WallGroup.js @@ -1,22 +1,22 @@ import PropTypes from "prop-types"; import React from "react"; -import {Group} from "react-konva"; +import { Group } from "react-konva"; import Shapes from "../../../../shapes/index"; -import {deriveWallLocations} from "../../../../util/tile-calculations"; +import { deriveWallLocations } from "../../../../util/tile-calculations"; import WallSegment from "../elements/WallSegment"; -const WallGroup = ({tiles}) => { - return ( - <Group> - {deriveWallLocations(tiles).map((wallSegment, index) => ( - <WallSegment key={index} wallSegment={wallSegment}/> - ))} - </Group> - ); +const WallGroup = ({ tiles }) => { + return ( + <Group> + {deriveWallLocations(tiles).map((wallSegment, index) => ( + <WallSegment key={index} wallSegment={wallSegment} /> + ))} + </Group> + ); }; WallGroup.propTypes = { - tiles: PropTypes.arrayOf(Shapes.Tile).isRequired, + tiles: PropTypes.arrayOf(Shapes.Tile).isRequired }; export default WallGroup; diff --git a/src/components/app/map/layers/HoverLayerComponent.js b/src/components/app/map/layers/HoverLayerComponent.js index aa2e8313..c39532f1 100644 --- a/src/components/app/map/layers/HoverLayerComponent.js +++ b/src/components/app/map/layers/HoverLayerComponent.js @@ -1,63 +1,85 @@ import PropTypes from "prop-types"; -import React from 'react'; -import {Layer} from "react-konva"; +import React from "react"; +import { Layer } from "react-konva"; import HoverTile from "../elements/HoverTile"; -import {TILE_SIZE_IN_PIXELS} from "../MapConstants"; +import { TILE_SIZE_IN_PIXELS } from "../MapConstants"; class HoverLayerComponent extends React.Component { - static propTypes = { - mouseX: PropTypes.number.isRequired, - mouseY: PropTypes.number.isRequired, - mapPosition: PropTypes.object.isRequired, - mapScale: PropTypes.number.isRequired, - isEnabled: PropTypes.func.isRequired, - onClick: PropTypes.func.isRequired, - }; - - state = { - positionX: -1, - positionY: -1, - validity: false, - }; - - componentDidUpdate() { - if (!this.props.isEnabled()) { - return; - } - - const positionX = Math.floor((this.props.mouseX - this.props.mapPosition.x) / (this.props.mapScale * TILE_SIZE_IN_PIXELS)); - const positionY = Math.floor((this.props.mouseY - this.props.mapPosition.y) / (this.props.mapScale * TILE_SIZE_IN_PIXELS)); - - if (positionX !== this.state.positionX || positionY !== this.state.positionY) { - this.setState({positionX, positionY, validity: this.props.isValid(positionX, positionY)}); - } + static propTypes = { + mouseX: PropTypes.number.isRequired, + mouseY: PropTypes.number.isRequired, + mapPosition: PropTypes.object.isRequired, + mapScale: PropTypes.number.isRequired, + isEnabled: PropTypes.func.isRequired, + onClick: PropTypes.func.isRequired + }; + + state = { + positionX: -1, + positionY: -1, + validity: false + }; + + componentDidUpdate() { + if (!this.props.isEnabled()) { + return; } - render() { - if (!this.props.isEnabled()) { - return <Layer/>; - } - - const pixelX = this.props.mapScale * this.state.positionX * TILE_SIZE_IN_PIXELS + this.props.mapPosition.x; - const pixelY = this.props.mapScale * this.state.positionY * TILE_SIZE_IN_PIXELS + this.props.mapPosition.y; - - return ( - <Layer opacity={0.6}> - <HoverTile - pixelX={pixelX} - pixelY={pixelY} - scale={this.props.mapScale} - isValid={this.state.validity} - onClick={() => this.state.validity ? - this.props.onClick(this.state.positionX, this.state.positionY) : undefined} - /> - {this.props.children ? - React.cloneElement(this.props.children, {pixelX, pixelY, scale: this.props.mapScale}) : - undefined - } - </Layer> - ); + const positionX = Math.floor( + (this.props.mouseX - this.props.mapPosition.x) / + (this.props.mapScale * TILE_SIZE_IN_PIXELS) + ); + const positionY = Math.floor( + (this.props.mouseY - this.props.mapPosition.y) / + (this.props.mapScale * TILE_SIZE_IN_PIXELS) + ); + + if ( + positionX !== this.state.positionX || + positionY !== this.state.positionY + ) { + this.setState({ + positionX, + positionY, + validity: this.props.isValid(positionX, positionY) + }); } + } + + render() { + if (!this.props.isEnabled()) { + return <Layer />; + } + + const pixelX = + this.props.mapScale * this.state.positionX * TILE_SIZE_IN_PIXELS + + this.props.mapPosition.x; + const pixelY = + this.props.mapScale * this.state.positionY * TILE_SIZE_IN_PIXELS + + this.props.mapPosition.y; + + return ( + <Layer opacity={0.6}> + <HoverTile + pixelX={pixelX} + pixelY={pixelY} + scale={this.props.mapScale} + isValid={this.state.validity} + onClick={() => + this.state.validity + ? this.props.onClick(this.state.positionX, this.state.positionY) + : undefined} + /> + {this.props.children + ? React.cloneElement(this.props.children, { + pixelX, + pixelY, + scale: this.props.mapScale + }) + : undefined} + </Layer> + ); + } } export default HoverLayerComponent; diff --git a/src/components/app/map/layers/MapLayerComponent.js b/src/components/app/map/layers/MapLayerComponent.js index c969249c..6ad3cb88 100644 --- a/src/components/app/map/layers/MapLayerComponent.js +++ b/src/components/app/map/layers/MapLayerComponent.js @@ -1,17 +1,22 @@ -import React from 'react'; -import {Group, Layer} from "react-konva"; +import React from "react"; +import { Group, Layer } from "react-konva"; import DatacenterContainer from "../../../../containers/app/map/DatacenterContainer"; import Backdrop from "../elements/Backdrop"; import GridGroup from "../groups/GridGroup"; -const MapLayerComponent = ({mapPosition, mapScale}) => ( - <Layer> - <Group x={mapPosition.x} y={mapPosition.y} scaleX={mapScale} scaleY={mapScale}> - <Backdrop/> - <DatacenterContainer/> - <GridGroup/> - </Group> - </Layer> +const MapLayerComponent = ({ mapPosition, mapScale }) => ( + <Layer> + <Group + x={mapPosition.x} + y={mapPosition.y} + scaleX={mapScale} + scaleY={mapScale} + > + <Backdrop /> + <DatacenterContainer /> + <GridGroup /> + </Group> + </Layer> ); export default MapLayerComponent; diff --git a/src/components/app/map/layers/ObjectHoverLayerComponent.js b/src/components/app/map/layers/ObjectHoverLayerComponent.js index aa79f8c3..e7342d3c 100644 --- a/src/components/app/map/layers/ObjectHoverLayerComponent.js +++ b/src/components/app/map/layers/ObjectHoverLayerComponent.js @@ -1,11 +1,11 @@ -import React from 'react'; +import React from "react"; import TilePlusIcon from "../elements/TilePlusIcon"; import HoverLayerComponent from "./HoverLayerComponent"; -const ObjectHoverLayerComponent = (props) => ( - <HoverLayerComponent {...props}> - <TilePlusIcon {...props}/> - </HoverLayerComponent> +const ObjectHoverLayerComponent = props => ( + <HoverLayerComponent {...props}> + <TilePlusIcon {...props} /> + </HoverLayerComponent> ); export default ObjectHoverLayerComponent; diff --git a/src/components/app/map/layers/RoomHoverLayerComponent.js b/src/components/app/map/layers/RoomHoverLayerComponent.js index 2133c8d8..feea5ae5 100644 --- a/src/components/app/map/layers/RoomHoverLayerComponent.js +++ b/src/components/app/map/layers/RoomHoverLayerComponent.js @@ -1,8 +1,6 @@ -import React from 'react'; +import React from "react"; import HoverLayerComponent from "./HoverLayerComponent"; -const RoomHoverLayerComponent = (props) => ( - <HoverLayerComponent {...props}/> -); +const RoomHoverLayerComponent = props => <HoverLayerComponent {...props} />; export default RoomHoverLayerComponent; diff --git a/src/components/app/sidebars/Sidebar.js b/src/components/app/sidebars/Sidebar.js index 00e3607a..33dbe011 100644 --- a/src/components/app/sidebars/Sidebar.js +++ b/src/components/app/sidebars/Sidebar.js @@ -3,36 +3,48 @@ import React from "react"; import "./Sidebar.css"; class Sidebar extends React.Component { - state = { - collapsed: false - }; + state = { + collapsed: false + }; - render() { - const collapseButton = ( - <div - className={classNames("sidebar-collapse-button", {"sidebar-collapse-button-right": this.props.isRight})} - onClick={() => this.setState({collapsed: !this.state.collapsed})} - > - {(this.state.collapsed && this.props.isRight) || (!this.state.collapsed && !this.props.isRight) ? - <span className="fa fa-angle-left" title={this.props.isRight ? "Expand" : "Collapse"}/> : - <span className="fa fa-angle-right" title={this.props.isRight ? "Collapse" : "Expand"}/> - } - </div> - ); + render() { + const collapseButton = ( + <div + className={classNames("sidebar-collapse-button", { + "sidebar-collapse-button-right": this.props.isRight + })} + onClick={() => this.setState({ collapsed: !this.state.collapsed })} + > + {(this.state.collapsed && this.props.isRight) || + (!this.state.collapsed && !this.props.isRight) ? ( + <span + className="fa fa-angle-left" + title={this.props.isRight ? "Expand" : "Collapse"} + /> + ) : ( + <span + className="fa fa-angle-right" + title={this.props.isRight ? "Collapse" : "Expand"} + /> + )} + </div> + ); - if (this.state.collapsed) { - return collapseButton; - } - return ( - <div - className={classNames("sidebar p-3 h-100", {"sidebar-right": this.props.isRight})} - onWheel={e => e.stopPropagation()} - > - {this.props.children} - {collapseButton} - </div> - ); + if (this.state.collapsed) { + return collapseButton; } + return ( + <div + className={classNames("sidebar p-3 h-100", { + "sidebar-right": this.props.isRight + })} + onWheel={e => e.stopPropagation()} + > + {this.props.children} + {collapseButton} + </div> + ); + } } export default Sidebar; diff --git a/src/components/app/sidebars/elements/LoadBarComponent.js b/src/components/app/sidebars/elements/LoadBarComponent.js index 65f94b3d..8c9b164b 100644 --- a/src/components/app/sidebars/elements/LoadBarComponent.js +++ b/src/components/app/sidebars/elements/LoadBarComponent.js @@ -1,22 +1,22 @@ import classNames from "classnames"; import React from "react"; -const LoadBarComponent = ({percent, disabled}) => ( - <div className="mt-1"> - <strong>Current load</strong> - <div className={classNames("progress", {disabled})}> - <div - className="progress-bar" - role="progressbar" - aria-valuenow={percent} - aria-valuemin="0" - aria-valuemax="100" - style={{width: percent + "%"}} - > - {percent}% - </div> - </div> +const LoadBarComponent = ({ percent, disabled }) => ( + <div className="mt-1"> + <strong>Current load</strong> + <div className={classNames("progress", { disabled })}> + <div + className="progress-bar" + role="progressbar" + aria-valuenow={percent} + aria-valuemin="0" + aria-valuemax="100" + style={{ width: percent + "%" }} + > + {percent}% + </div> </div> + </div> ); export default LoadBarComponent; diff --git a/src/components/app/sidebars/elements/LoadChartComponent.js b/src/components/app/sidebars/elements/LoadChartComponent.js index 91d89287..6f66010e 100644 --- a/src/components/app/sidebars/elements/LoadChartComponent.js +++ b/src/components/app/sidebars/elements/LoadChartComponent.js @@ -1,73 +1,81 @@ import React from "react"; import ReactDOM from "react-dom/server"; import SvgSaver from "svgsaver"; -import {VictoryAxis, VictoryChart, VictoryLine, VictoryScatter} from "victory"; -import {convertSecondsToFormattedTime} from "../../../../util/date-time"; +import { + VictoryAxis, + VictoryChart, + VictoryLine, + VictoryScatter +} from "victory"; +import { convertSecondsToFormattedTime } from "../../../../util/date-time"; -const LoadChartComponent = ({data, currentTick}) => { - const onExport = () => { - const div = document.createElement("div"); - div.innerHTML = ReactDOM.renderToString( - <VictoryChartComponent data={data} currentTick={currentTick} showCurrentTick={false}/> - ); - div.firstChild.style = "font-family: Roboto, Arial, sans-serif; font-size: 10pt;"; - const svgSaver = new SvgSaver(); - svgSaver.asSvg(div.firstChild, "opendc-chart-export-" + Date.now() + ".svg"); - }; - - return ( - <div className="mt-1" style={{position: "relative"}}> - <strong>Load over time</strong> - <VictoryChartComponent data={data} currentTick={currentTick} showCurrentTick={true}/> - <ExportChartComponent onExport={onExport}/> - </div> +const LoadChartComponent = ({ data, currentTick }) => { + const onExport = () => { + const div = document.createElement("div"); + div.innerHTML = ReactDOM.renderToString( + <VictoryChartComponent + data={data} + currentTick={currentTick} + showCurrentTick={false} + /> + ); + div.firstChild.style = + "font-family: Roboto, Arial, sans-serif; font-size: 10pt;"; + const svgSaver = new SvgSaver(); + svgSaver.asSvg( + div.firstChild, + "opendc-chart-export-" + Date.now() + ".svg" ); + }; + + return ( + <div className="mt-1" style={{ position: "relative" }}> + <strong>Load over time</strong> + <VictoryChartComponent + data={data} + currentTick={currentTick} + showCurrentTick={true} + /> + <ExportChartComponent onExport={onExport} /> + </div> + ); }; -const VictoryChartComponent = ({data, currentTick, showCurrentTick}) => ( - <VictoryChart - height={250} - padding={{top: 10, bottom: 50, left: 50, right: 50}} - > - <VictoryAxis - tickFormat={tick => convertSecondsToFormattedTime(tick)} - fixLabelOverlap={true} - label="Simulated Time" - /> - <VictoryAxis - dependentAxis - label="Load" - /> - <VictoryLine - data={data} - /> - <VictoryScatter - data={data} - /> - {showCurrentTick ? - <VictoryLine - data={[ - {x: currentTick + 1, y: 0}, - {x: currentTick + 1, y: 1}, - ]} - style={{ - data: {stroke: "#00A6D6", strokeWidth: 3} - }} - /> : - undefined - } - </VictoryChart> +const VictoryChartComponent = ({ data, currentTick, showCurrentTick }) => ( + <VictoryChart + height={250} + padding={{ top: 10, bottom: 50, left: 50, right: 50 }} + > + <VictoryAxis + tickFormat={tick => convertSecondsToFormattedTime(tick)} + fixLabelOverlap={true} + label="Simulated Time" + /> + <VictoryAxis dependentAxis label="Load" /> + <VictoryLine data={data} /> + <VictoryScatter data={data} /> + {showCurrentTick ? ( + <VictoryLine + data={[{ x: currentTick + 1, y: 0 }, { x: currentTick + 1, y: 1 }]} + style={{ + data: { stroke: "#00A6D6", strokeWidth: 3 } + }} + /> + ) : ( + undefined + )} + </VictoryChart> ); -const ExportChartComponent = ({onExport}) => ( - <button - className="btn btn-success btn-circle btn-sm" - title="Export Chart to PNG Image" - onClick={onExport} - style={{position: "absolute", top: 0, right: 0}} - > - <span className="fa fa-camera"/> - </button> +const ExportChartComponent = ({ onExport }) => ( + <button + className="btn btn-success btn-circle btn-sm" + title="Export Chart to PNG Image" + onClick={onExport} + style={{ position: "absolute", top: 0, right: 0 }} + > + <span className="fa fa-camera" /> + </button> ); export default LoadChartComponent; diff --git a/src/components/app/sidebars/simulation/ExperimentMetadataComponent.js b/src/components/app/sidebars/simulation/ExperimentMetadataComponent.js index 3649045b..bc563dab 100644 --- a/src/components/app/sidebars/simulation/ExperimentMetadataComponent.js +++ b/src/components/app/sidebars/simulation/ExperimentMetadataComponent.js @@ -1,12 +1,23 @@ import React from "react"; -const ExperimentMetadataComponent = ({experimentName, pathName, traceName, schedulerName}) => ( - <div> - <h2>{experimentName}</h2> - <p>Path: <strong>{pathName}</strong></p> - <p>Trace: <strong>{traceName}</strong></p> - <p>Scheduler: <strong>{schedulerName}</strong></p> - </div> +const ExperimentMetadataComponent = ({ + experimentName, + pathName, + traceName, + schedulerName +}) => ( + <div> + <h2>{experimentName}</h2> + <p> + Path: <strong>{pathName}</strong> + </p> + <p> + Trace: <strong>{traceName}</strong> + </p> + <p> + Scheduler: <strong>{schedulerName}</strong> + </p> + </div> ); export default ExperimentMetadataComponent; diff --git a/src/components/app/sidebars/simulation/LoadMetricComponent.js b/src/components/app/sidebars/simulation/LoadMetricComponent.js index e72e6b67..3e4cf810 100644 --- a/src/components/app/sidebars/simulation/LoadMetricComponent.js +++ b/src/components/app/sidebars/simulation/LoadMetricComponent.js @@ -1,33 +1,40 @@ import React from "react"; -import {SIM_HIGH_COLOR, SIM_LOW_COLOR, SIM_MID_HIGH_COLOR, SIM_MID_LOW_COLOR} from "../../../../util/colors"; -import {LOAD_NAME_MAP} from "../../../../util/simulation-load"; +import { + SIM_HIGH_COLOR, + SIM_LOW_COLOR, + SIM_MID_HIGH_COLOR, + SIM_MID_LOW_COLOR +} from "../../../../util/colors"; +import { LOAD_NAME_MAP } from "../../../../util/simulation-load"; -const LoadMetricComponent = ({loadMetric}) => ( +const LoadMetricComponent = ({ loadMetric }) => ( + <div> <div> - <div>Colors represent <strong>{LOAD_NAME_MAP[loadMetric]}</strong></div> - <div className="btn-group mb-2" style={{display: "flex"}}> - <span - className="btn btn-secondary" - style={{backgroundColor: SIM_LOW_COLOR, flex: 1}} - title="0-25%" - /> - <span - className="btn btn-secondary" - style={{backgroundColor: SIM_MID_LOW_COLOR, flex: 1}} - title="25-50%" - /> - <span - className="btn btn-secondary" - style={{backgroundColor: SIM_MID_HIGH_COLOR, flex: 1}} - title="50-75%" - /> - <span - className="btn btn-secondary" - style={{backgroundColor: SIM_HIGH_COLOR, flex: 1}} - title="75-100%" - /> - </div> + Colors represent <strong>{LOAD_NAME_MAP[loadMetric]}</strong> </div> + <div className="btn-group mb-2" style={{ display: "flex" }}> + <span + className="btn btn-secondary" + style={{ backgroundColor: SIM_LOW_COLOR, flex: 1 }} + title="0-25%" + /> + <span + className="btn btn-secondary" + style={{ backgroundColor: SIM_MID_LOW_COLOR, flex: 1 }} + title="25-50%" + /> + <span + className="btn btn-secondary" + style={{ backgroundColor: SIM_MID_HIGH_COLOR, flex: 1 }} + title="50-75%" + /> + <span + className="btn btn-secondary" + style={{ backgroundColor: SIM_HIGH_COLOR, flex: 1 }} + title="75-100%" + /> + </div> + </div> ); export default LoadMetricComponent; diff --git a/src/components/app/sidebars/simulation/SimulationSidebarComponent.js b/src/components/app/sidebars/simulation/SimulationSidebarComponent.js index 92651dfc..08dbb29a 100644 --- a/src/components/app/sidebars/simulation/SimulationSidebarComponent.js +++ b/src/components/app/sidebars/simulation/SimulationSidebarComponent.js @@ -6,17 +6,17 @@ import Sidebar from "../Sidebar"; import "./SimulationSidebarComponent.css"; const SimulationSidebarComponent = () => { - return ( - <Sidebar isRight={false}> - <div className="simulation-sidebar-container flex-column"> - <ExperimentMetadataContainer/> - <LoadMetricContainer/> - <div className="trace-container"> - <TraceContainer/> - </div> - </div> - </Sidebar> - ); + return ( + <Sidebar isRight={false}> + <div className="simulation-sidebar-container flex-column"> + <ExperimentMetadataContainer /> + <LoadMetricContainer /> + <div className="trace-container"> + <TraceContainer /> + </div> + </div> + </Sidebar> + ); }; export default SimulationSidebarComponent; diff --git a/src/components/app/sidebars/simulation/TaskComponent.js b/src/components/app/sidebars/simulation/TaskComponent.js index baf6f9ce..bd917cc9 100644 --- a/src/components/app/sidebars/simulation/TaskComponent.js +++ b/src/components/app/sidebars/simulation/TaskComponent.js @@ -1,57 +1,58 @@ import approx from "approximate-number"; import classNames from "classnames"; import React from "react"; -import {convertSecondsToFormattedTime} from "../../../../util/date-time"; +import { convertSecondsToFormattedTime } from "../../../../util/date-time"; -const TaskComponent = ({task, flopsLeft}) => { - let icon; - let progressBarContent; - let percent; - let infoTitle; +const TaskComponent = ({ task, flopsLeft }) => { + let icon; + let progressBarContent; + let percent; + let infoTitle; - if (flopsLeft === task.totalFlopCount) { - icon = "hourglass-half"; - progressBarContent = ""; - percent = 0; - infoTitle = "Not submitted yet"; - } else if (flopsLeft > 0) { - icon = "refresh"; - progressBarContent = approx(task.totalFlopCount - flopsLeft) + " FLOP"; - percent = 100 * (task.totalFlopCount - flopsLeft) / task.totalFlopCount; - infoTitle = progressBarContent + " (" + Math.round(percent * 10) / 10 + "%)"; - } else { - icon = "check"; - progressBarContent = "Completed"; - percent = 100; - infoTitle = "Completed"; - } + if (flopsLeft === task.totalFlopCount) { + icon = "hourglass-half"; + progressBarContent = ""; + percent = 0; + infoTitle = "Not submitted yet"; + } else if (flopsLeft > 0) { + icon = "refresh"; + progressBarContent = approx(task.totalFlopCount - flopsLeft) + " FLOP"; + percent = 100 * (task.totalFlopCount - flopsLeft) / task.totalFlopCount; + infoTitle = + progressBarContent + " (" + Math.round(percent * 10) / 10 + "%)"; + } else { + icon = "check"; + progressBarContent = "Completed"; + percent = 100; + infoTitle = "Completed"; + } - return ( - <li className="list-group-item flex-column align-items-start"> - <div className="d-flex w-100 justify-content-between"> - <h5 className="mb-1">{approx(task.totalFlopCount)} FLOP</h5> - <small>Starts at {convertSecondsToFormattedTime(task.startTick)}</small> - </div> - <div title={infoTitle} style={{display: "flex"}}> - <span - className={classNames("fa", "fa-" + icon)} - style={{width: "20px"}} - /> - <div className="progress" style={{flexGrow: 1}}> - <div - className="progress-bar" - role="progressbar" - aria-valuenow={percent} - aria-valuemin="0" - aria-valuemax="100" - style={{width: percent + "%"}} - > - {progressBarContent} - </div> - </div> - </div> - </li> - ); + return ( + <li className="list-group-item flex-column align-items-start"> + <div className="d-flex w-100 justify-content-between"> + <h5 className="mb-1">{approx(task.totalFlopCount)} FLOP</h5> + <small>Starts at {convertSecondsToFormattedTime(task.startTick)}</small> + </div> + <div title={infoTitle} style={{ display: "flex" }}> + <span + className={classNames("fa", "fa-" + icon)} + style={{ width: "20px" }} + /> + <div className="progress" style={{ flexGrow: 1 }}> + <div + className="progress-bar" + role="progressbar" + aria-valuenow={percent} + aria-valuemin="0" + aria-valuemax="100" + style={{ width: percent + "%" }} + > + {progressBarContent} + </div> + </div> + </div> + </li> + ); }; export default TaskComponent; diff --git a/src/components/app/sidebars/simulation/TraceComponent.js b/src/components/app/sidebars/simulation/TraceComponent.js index b43a8cea..2b6559b4 100644 --- a/src/components/app/sidebars/simulation/TraceComponent.js +++ b/src/components/app/sidebars/simulation/TraceComponent.js @@ -1,20 +1,20 @@ import React from "react"; import TaskContainer from "../../../../containers/app/sidebars/simulation/TaskContainer"; -const TraceComponent = ({jobs}) => ( - <div> - <h3>Trace</h3> - {jobs.map(job => ( - <div key={job.id}> - <h4>Job: {job.name}</h4> - <ul className="list-group"> - {job.taskIds.map(taskId => ( - <TaskContainer taskId={taskId} key={taskId}/> - ))} - </ul> - </div> - ))} - </div> +const TraceComponent = ({ jobs }) => ( + <div> + <h3>Trace</h3> + {jobs.map(job => ( + <div key={job.id}> + <h4>Job: {job.name}</h4> + <ul className="list-group"> + {job.taskIds.map(taskId => ( + <TaskContainer taskId={taskId} key={taskId} /> + ))} + </ul> + </div> + ))} + </div> ); export default TraceComponent; diff --git a/src/components/app/sidebars/topology/NameComponent.js b/src/components/app/sidebars/topology/NameComponent.js index d663f4ae..805538b3 100644 --- a/src/components/app/sidebars/topology/NameComponent.js +++ b/src/components/app/sidebars/topology/NameComponent.js @@ -1,13 +1,13 @@ import React from "react"; import FontAwesome from "react-fontawesome"; -const NameComponent = ({name, onEdit}) => ( - <h2> - {name} - <button className="btn btn-outline-secondary float-right" onClick={onEdit}> - <FontAwesome name="pencil"/> - </button> - </h2> +const NameComponent = ({ name, onEdit }) => ( + <h2> + {name} + <button className="btn btn-outline-secondary float-right" onClick={onEdit}> + <FontAwesome name="pencil" /> + </button> + </h2> ); export default NameComponent; diff --git a/src/components/app/sidebars/topology/TopologySidebarComponent.js b/src/components/app/sidebars/topology/TopologySidebarComponent.js index ff4260a9..81e510a1 100644 --- a/src/components/app/sidebars/topology/TopologySidebarComponent.js +++ b/src/components/app/sidebars/topology/TopologySidebarComponent.js @@ -5,31 +5,27 @@ import RackSidebarContainer from "../../../../containers/app/sidebars/topology/r import RoomSidebarContainer from "../../../../containers/app/sidebars/topology/room/RoomSidebarContainer"; import Sidebar from "../Sidebar"; -const TopologySidebarComponent = ({interactionLevel}) => { - let sidebarContent; +const TopologySidebarComponent = ({ interactionLevel }) => { + let sidebarContent; - switch (interactionLevel.mode) { - case "BUILDING": - sidebarContent = <BuildingSidebarContainer/>; - break; - case "ROOM": - sidebarContent = <RoomSidebarContainer/>; - break; - case "RACK": - sidebarContent = <RackSidebarContainer/>; - break; - case "MACHINE": - sidebarContent = <MachineSidebarContainer/>; - break; - default: - sidebarContent = "Missing Content"; - } + switch (interactionLevel.mode) { + case "BUILDING": + sidebarContent = <BuildingSidebarContainer />; + break; + case "ROOM": + sidebarContent = <RoomSidebarContainer />; + break; + case "RACK": + sidebarContent = <RackSidebarContainer />; + break; + case "MACHINE": + sidebarContent = <MachineSidebarContainer />; + break; + default: + sidebarContent = "Missing Content"; + } - return ( - <Sidebar isRight={true}> - {sidebarContent} - </Sidebar> - ); + return <Sidebar isRight={true}>{sidebarContent}</Sidebar>; }; export default TopologySidebarComponent; diff --git a/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js b/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js index 2bf81a48..f16c19f0 100644 --- a/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js +++ b/src/components/app/sidebars/topology/building/BuildingSidebarComponent.js @@ -1,19 +1,20 @@ import React from "react"; import NewRoomConstructionContainer from "../../../../../containers/app/sidebars/topology/building/NewRoomConstructionContainer"; -const BuildingSidebarComponent = ({inSimulation}) => { - return ( - <div> - <h2>Building</h2> - {inSimulation ? - <div className="alert alert-info"> - <span className="fa fa-info-circle mr-2"/> - <strong>Click on individual rooms</strong> to see their stats! - </div> : - <NewRoomConstructionContainer/> - } +const BuildingSidebarComponent = ({ inSimulation }) => { + return ( + <div> + <h2>Building</h2> + {inSimulation ? ( + <div className="alert alert-info"> + <span className="fa fa-info-circle mr-2" /> + <strong>Click on individual rooms</strong> to see their stats! </div> - ); + ) : ( + <NewRoomConstructionContainer /> + )} + </div> + ); }; export default BuildingSidebarComponent; diff --git a/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js b/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js index d89b0ac0..a559c8dd 100644 --- a/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js +++ b/src/components/app/sidebars/topology/building/NewRoomConstructionComponent.js @@ -1,27 +1,31 @@ import React from "react"; -const NewRoomConstructionComponent = ({onStart, onFinish, onCancel, currentRoomInConstruction}) => { - if (currentRoomInConstruction === -1) { - return ( - <div className="btn btn-primary btn-block" onClick={onStart}> - <span className="fa fa-plus mr-2"/> - Construct a new room - </div> - ); - } +const NewRoomConstructionComponent = ({ + onStart, + onFinish, + onCancel, + currentRoomInConstruction +}) => { + if (currentRoomInConstruction === -1) { return ( - <div> - <div className="btn btn-primary btn-block" onClick={onFinish}> - <span className="fa fa-check mr-2"/> - Finalize new room - </div> - <div className="btn btn-default btn-block" onClick={onCancel}> - <span className="fa fa-times mr-2"/> - Cancel construction - </div> - </div> + <div className="btn btn-primary btn-block" onClick={onStart}> + <span className="fa fa-plus mr-2" /> + Construct a new room + </div> ); - + } + return ( + <div> + <div className="btn btn-primary btn-block" onClick={onFinish}> + <span className="fa fa-check mr-2" /> + Finalize new room + </div> + <div className="btn btn-default btn-block" onClick={onCancel}> + <span className="fa fa-times mr-2" /> + Cancel construction + </div> + </div> + ); }; export default NewRoomConstructionComponent; diff --git a/src/components/app/sidebars/topology/machine/BackToRackComponent.js b/src/components/app/sidebars/topology/machine/BackToRackComponent.js index 19e33904..7f56aca0 100644 --- a/src/components/app/sidebars/topology/machine/BackToRackComponent.js +++ b/src/components/app/sidebars/topology/machine/BackToRackComponent.js @@ -1,10 +1,10 @@ import React from "react"; -const BackToRackComponent = ({onClick}) => ( - <div className="btn btn-secondary btn-block" onClick={onClick}> - <span className="fa fa-angle-left mr-2"/> - Back to rack - </div> +const BackToRackComponent = ({ onClick }) => ( + <div className="btn btn-secondary btn-block" onClick={onClick}> + <span className="fa fa-angle-left mr-2" /> + Back to rack + </div> ); export default BackToRackComponent; diff --git a/src/components/app/sidebars/topology/machine/DeleteMachineComponent.js b/src/components/app/sidebars/topology/machine/DeleteMachineComponent.js index 7ba08352..8da39b30 100644 --- a/src/components/app/sidebars/topology/machine/DeleteMachineComponent.js +++ b/src/components/app/sidebars/topology/machine/DeleteMachineComponent.js @@ -1,10 +1,10 @@ import React from "react"; -const DeleteMachineComponent = ({onClick}) => ( - <div className="btn btn-danger btn-block" onClick={onClick}> - <span className="fa fa-trash mr-2"/> - Delete this machine - </div> +const DeleteMachineComponent = ({ onClick }) => ( + <div className="btn btn-danger btn-block" onClick={onClick}> + <span className="fa fa-trash mr-2" /> + Delete this machine + </div> ); export default DeleteMachineComponent; diff --git a/src/components/app/sidebars/topology/machine/MachineNameComponent.js b/src/components/app/sidebars/topology/machine/MachineNameComponent.js index 321e350d..0ad8b79c 100644 --- a/src/components/app/sidebars/topology/machine/MachineNameComponent.js +++ b/src/components/app/sidebars/topology/machine/MachineNameComponent.js @@ -1,7 +1,7 @@ import React from "react"; -const MachineNameComponent = ({position}) => ( - <h2>Machine at slot {position}</h2> +const MachineNameComponent = ({ position }) => ( + <h2>Machine at slot {position}</h2> ); export default MachineNameComponent; diff --git a/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js b/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js index cf4db80e..5ccaf25c 100644 --- a/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js +++ b/src/components/app/sidebars/topology/machine/MachineSidebarComponent.js @@ -6,21 +6,22 @@ import DeleteMachineContainer from "../../../../../containers/app/sidebars/topol import MachineNameContainer from "../../../../../containers/app/sidebars/topology/machine/MachineNameContainer"; import UnitTabsContainer from "../../../../../containers/app/sidebars/topology/machine/UnitTabsContainer"; -const MachineSidebarComponent = ({inSimulation, machineId}) => { - return ( +const MachineSidebarComponent = ({ inSimulation, machineId }) => { + return ( + <div> + <MachineNameContainer /> + <BackToRackContainer /> + {inSimulation ? ( <div> - <MachineNameContainer/> - <BackToRackContainer/> - {inSimulation ? - <div> - <LoadBarContainer objectType="machine" objectId={machineId}/> - <LoadChartContainer objectType="machine" objectId={machineId}/> - </div> : - <DeleteMachineContainer/> - } - <UnitTabsContainer/> + <LoadBarContainer objectType="machine" objectId={machineId} /> + <LoadChartContainer objectType="machine" objectId={machineId} /> </div> - ); + ) : ( + <DeleteMachineContainer /> + )} + <UnitTabsContainer /> + </div> + ); }; export default MachineSidebarComponent; diff --git a/src/components/app/sidebars/topology/machine/UnitAddComponent.js b/src/components/app/sidebars/topology/machine/UnitAddComponent.js index f16700df..d0082a72 100644 --- a/src/components/app/sidebars/topology/machine/UnitAddComponent.js +++ b/src/components/app/sidebars/topology/machine/UnitAddComponent.js @@ -2,37 +2,44 @@ import PropTypes from "prop-types"; import React from "react"; class UnitAddComponent extends React.Component { - static propTypes = { - units: PropTypes.array.isRequired, - onAdd: PropTypes.func.isRequired, - }; + static propTypes = { + units: PropTypes.array.isRequired, + onAdd: PropTypes.func.isRequired + }; - render() { - return ( - <div className="form-inline"> - <div className="form-group w-100"> - <select - className="form-control w-75 mr-1" - ref={unitSelect => this.unitSelect = unitSelect} - > - {this.props.units.map(unit => ( - <option value={unit.id} key={unit.id}> - {unit.manufacturer + " " + unit.family + " " + unit.model + " " + unit.generation} - </option> - ))} - </select> - <button - type="submit" - className="btn btn-primary" - onClick={() => this.props.onAdd(parseInt(this.unitSelect.value, 10))} - > - <span className="fa fa-plus mr-2"/> - Add - </button> - </div> - </div> - ); - } + render() { + return ( + <div className="form-inline"> + <div className="form-group w-100"> + <select + className="form-control w-75 mr-1" + ref={unitSelect => (this.unitSelect = unitSelect)} + > + {this.props.units.map(unit => ( + <option value={unit.id} key={unit.id}> + {unit.manufacturer + + " " + + unit.family + + " " + + unit.model + + " " + + unit.generation} + </option> + ))} + </select> + <button + type="submit" + className="btn btn-primary" + onClick={() => + this.props.onAdd(parseInt(this.unitSelect.value, 10))} + > + <span className="fa fa-plus mr-2" /> + Add + </button> + </div> + </div> + ); + } } export default UnitAddComponent; diff --git a/src/components/app/sidebars/topology/machine/UnitComponent.js b/src/components/app/sidebars/topology/machine/UnitComponent.js index a0435eab..10a310e8 100644 --- a/src/components/app/sidebars/topology/machine/UnitComponent.js +++ b/src/components/app/sidebars/topology/machine/UnitComponent.js @@ -2,61 +2,79 @@ import React from "react"; import jQuery from "../../../../../util/jquery"; class UnitComponent extends React.Component { - componentDidMount() { - jQuery(".unit-info-popover").popover({ - trigger: "focus" - }); - } - - render() { - let unitInfo; - if (this.props.unitType === "cpu" || this.props.unitType === "gpu") { - unitInfo = ( - "<strong>Clockrate:</strong> <code>" + this.props.unit.clockRateMhz + " MHz</code><br/>" + - "<strong>Num. Cores:</strong> <code>" + this.props.unit.numberOfCores + "</code><br/>" + - "<strong>Energy Cons.:</strong> <code>" + this.props.unit.energyConsumptionW + " W</code>" - ); - } else if (this.props.unitType === "memory" || this.props.unitType === "storage") { - unitInfo = ( - "<strong>Speed:</strong> <code>" + this.props.unit.speedMbPerS + " Mb/s</code><br/>" + - "<strong>Size:</strong> <code>" + this.props.unit.sizeMb + " MB</code><br/>" + - "<strong>Energy Cons.:</strong> <code> " + this.props.unit.energyConsumptionW + " W</code>" - ); - } + componentDidMount() { + jQuery(".unit-info-popover").popover({ + trigger: "focus" + }); + } - return ( - <li className="d-flex list-group-item justify-content-between align-items-center"> - <span style={{maxWidth: "60%"}}> - { - this.props.unit.manufacturer - + " " + this.props.unit.family - + " " + this.props.unit.model - + " " + this.props.unit.generation - } - </span> - <span> - <a - tabIndex="0" - className="unit-info-popover btn btn-outline-info mr-1" - role="button" - data-toggle="popover" - data-trigger="focus" - title="Unit information" - data-content={unitInfo} - data-html="true" - > - <span className="fa fa-info-circle"/> - </a> - {this.props.inSimulation ? - undefined : - <span className="btn btn-outline-danger" onClick={this.props.onDelete}> - <span className="fa fa-trash"/> - </span> - } - </span> - </li> - ); + render() { + let unitInfo; + if (this.props.unitType === "cpu" || this.props.unitType === "gpu") { + unitInfo = + "<strong>Clockrate:</strong> <code>" + + this.props.unit.clockRateMhz + + " MHz</code><br/>" + + "<strong>Num. Cores:</strong> <code>" + + this.props.unit.numberOfCores + + "</code><br/>" + + "<strong>Energy Cons.:</strong> <code>" + + this.props.unit.energyConsumptionW + + " W</code>"; + } else if ( + this.props.unitType === "memory" || + this.props.unitType === "storage" + ) { + unitInfo = + "<strong>Speed:</strong> <code>" + + this.props.unit.speedMbPerS + + " Mb/s</code><br/>" + + "<strong>Size:</strong> <code>" + + this.props.unit.sizeMb + + " MB</code><br/>" + + "<strong>Energy Cons.:</strong> <code> " + + this.props.unit.energyConsumptionW + + " W</code>"; } + + return ( + <li className="d-flex list-group-item justify-content-between align-items-center"> + <span style={{ maxWidth: "60%" }}> + {this.props.unit.manufacturer + + " " + + this.props.unit.family + + " " + + this.props.unit.model + + " " + + this.props.unit.generation} + </span> + <span> + <a + tabIndex="0" + className="unit-info-popover btn btn-outline-info mr-1" + role="button" + data-toggle="popover" + data-trigger="focus" + title="Unit information" + data-content={unitInfo} + data-html="true" + > + <span className="fa fa-info-circle" /> + </a> + {this.props.inSimulation ? ( + undefined + ) : ( + <span + className="btn btn-outline-danger" + onClick={this.props.onDelete} + > + <span className="fa fa-trash" /> + </span> + )} + </span> + </li> + ); + } } export default UnitComponent; diff --git a/src/components/app/sidebars/topology/machine/UnitListComponent.js b/src/components/app/sidebars/topology/machine/UnitListComponent.js index 683f6023..38df806b 100644 --- a/src/components/app/sidebars/topology/machine/UnitListComponent.js +++ b/src/components/app/sidebars/topology/machine/UnitListComponent.js @@ -1,20 +1,29 @@ import React from "react"; import UnitContainer from "../../../../../containers/app/sidebars/topology/machine/UnitContainer"; -const UnitListComponent = ({unitType, unitIds, inSimulation}) => ( - <ul className="list-group mt-1"> - {unitIds.length !== 0 ? - unitIds.map((unitId, index) => ( - <UnitContainer unitType={unitType} unitId={unitId} index={index} key={index}/> - )) : - <div className="alert alert-info"> - {inSimulation ? - <strong>No units of this type in this machine</strong> : - <span><strong>No units...</strong> Add some with the menu above!</span> - } - </div> - } - </ul> +const UnitListComponent = ({ unitType, unitIds, inSimulation }) => ( + <ul className="list-group mt-1"> + {unitIds.length !== 0 ? ( + unitIds.map((unitId, index) => ( + <UnitContainer + unitType={unitType} + unitId={unitId} + index={index} + key={index} + /> + )) + ) : ( + <div className="alert alert-info"> + {inSimulation ? ( + <strong>No units of this type in this machine</strong> + ) : ( + <span> + <strong>No units...</strong> Add some with the menu above! + </span> + )} + </div> + )} + </ul> ); export default UnitListComponent; diff --git a/src/components/app/sidebars/topology/machine/UnitTabsComponent.js b/src/components/app/sidebars/topology/machine/UnitTabsComponent.js index 2113d6d8..0683c796 100644 --- a/src/components/app/sidebars/topology/machine/UnitTabsComponent.js +++ b/src/components/app/sidebars/topology/machine/UnitTabsComponent.js @@ -2,53 +2,64 @@ import React from "react"; import UnitAddContainer from "../../../../../containers/app/sidebars/topology/machine/UnitAddContainer"; import UnitListContainer from "../../../../../containers/app/sidebars/topology/machine/UnitListContainer"; -const UnitTabsComponent = ({inSimulation}) => ( - <div> - <ul className="nav nav-tabs mt-2 mb-1" role="tablist"> - <li className="nav-item"> - <a className="nav-link active" data-toggle="tab" href="#cpu-units" role="tab">CPU</a> - </li> - <li className="nav-item"> - <a className="nav-link" data-toggle="tab" href="#gpu-units" role="tab">GPU</a> - </li> - <li className="nav-item"> - <a className="nav-link" data-toggle="tab" href="#memory-units" role="tab">Memory</a> - </li> - <li className="nav-item"> - <a className="nav-link" data-toggle="tab" href="#storage-units" role="tab">Storage</a> - </li> - </ul> - <div className="tab-content"> - <div className="tab-pane active" id="cpu-units" role="tabpanel"> - {inSimulation ? - undefined : - <UnitAddContainer unitType="cpu"/> - } - <UnitListContainer unitType="cpu"/> - </div> - <div className="tab-pane" id="gpu-units" role="tabpanel"> - {inSimulation ? - undefined : - <UnitAddContainer unitType="gpu"/> - } - <UnitListContainer unitType="gpu"/> - </div> - <div className="tab-pane" id="memory-units" role="tabpanel"> - {inSimulation ? - undefined : - <UnitAddContainer unitType="memory"/> - } - <UnitListContainer unitType="memory"/> - </div> - <div className="tab-pane" id="storage-units" role="tabpanel"> - {inSimulation ? - undefined : - <UnitAddContainer unitType="storage"/> - } - <UnitListContainer unitType="storage"/> - </div> - </div> +const UnitTabsComponent = ({ inSimulation }) => ( + <div> + <ul className="nav nav-tabs mt-2 mb-1" role="tablist"> + <li className="nav-item"> + <a + className="nav-link active" + data-toggle="tab" + href="#cpu-units" + role="tab" + > + CPU + </a> + </li> + <li className="nav-item"> + <a className="nav-link" data-toggle="tab" href="#gpu-units" role="tab"> + GPU + </a> + </li> + <li className="nav-item"> + <a + className="nav-link" + data-toggle="tab" + href="#memory-units" + role="tab" + > + Memory + </a> + </li> + <li className="nav-item"> + <a + className="nav-link" + data-toggle="tab" + href="#storage-units" + role="tab" + > + Storage + </a> + </li> + </ul> + <div className="tab-content"> + <div className="tab-pane active" id="cpu-units" role="tabpanel"> + {inSimulation ? undefined : <UnitAddContainer unitType="cpu" />} + <UnitListContainer unitType="cpu" /> + </div> + <div className="tab-pane" id="gpu-units" role="tabpanel"> + {inSimulation ? undefined : <UnitAddContainer unitType="gpu" />} + <UnitListContainer unitType="gpu" /> + </div> + <div className="tab-pane" id="memory-units" role="tabpanel"> + {inSimulation ? undefined : <UnitAddContainer unitType="memory" />} + <UnitListContainer unitType="memory" /> + </div> + <div className="tab-pane" id="storage-units" role="tabpanel"> + {inSimulation ? undefined : <UnitAddContainer unitType="storage" />} + <UnitListContainer unitType="storage" /> + </div> </div> + </div> ); export default UnitTabsComponent; diff --git a/src/components/app/sidebars/topology/rack/BackToRoomComponent.js b/src/components/app/sidebars/topology/rack/BackToRoomComponent.js index 267001c6..6bcf4088 100644 --- a/src/components/app/sidebars/topology/rack/BackToRoomComponent.js +++ b/src/components/app/sidebars/topology/rack/BackToRoomComponent.js @@ -1,10 +1,10 @@ import React from "react"; -const BackToRoomComponent = ({onClick}) => ( - <div className="btn btn-secondary btn-block mb-2" onClick={onClick}> - <span className="fa fa-angle-left mr-2"/> - Back to room - </div> +const BackToRoomComponent = ({ onClick }) => ( + <div className="btn btn-secondary btn-block mb-2" onClick={onClick}> + <span className="fa fa-angle-left mr-2" /> + Back to room + </div> ); export default BackToRoomComponent; diff --git a/src/components/app/sidebars/topology/rack/DeleteRackComponent.js b/src/components/app/sidebars/topology/rack/DeleteRackComponent.js index b268bd72..f0bad0ed 100644 --- a/src/components/app/sidebars/topology/rack/DeleteRackComponent.js +++ b/src/components/app/sidebars/topology/rack/DeleteRackComponent.js @@ -1,10 +1,10 @@ import React from "react"; -const DeleteRackComponent = ({onClick}) => ( - <div className="btn btn-danger btn-block" onClick={onClick}> - <span className="fa fa-trash mr-2"/> - Delete this rack - </div> +const DeleteRackComponent = ({ onClick }) => ( + <div className="btn btn-danger btn-block" onClick={onClick}> + <span className="fa fa-trash mr-2" /> + Delete this rack + </div> ); export default DeleteRackComponent; diff --git a/src/components/app/sidebars/topology/rack/EmptySlotComponent.js b/src/components/app/sidebars/topology/rack/EmptySlotComponent.js index 08665072..d86f9fee 100644 --- a/src/components/app/sidebars/topology/rack/EmptySlotComponent.js +++ b/src/components/app/sidebars/topology/rack/EmptySlotComponent.js @@ -1,20 +1,19 @@ import React from "react"; -const EmptySlotComponent = ({position, onAdd, inSimulation}) => ( - <li className="list-group-item d-flex justify-content-between align-items-center"> - <span className="badge badge-default badge-info mr-1 disabled"> - {position} - </span> - {inSimulation ? - <span className="badge badge-default badge-success"> - Empty Slot - </span> : - <button className="btn btn-outline-primary" onClick={onAdd}> - <span className="fa fa-plus mr-2"/> - Add machine - </button> - } - </li> +const EmptySlotComponent = ({ position, onAdd, inSimulation }) => ( + <li className="list-group-item d-flex justify-content-between align-items-center"> + <span className="badge badge-default badge-info mr-1 disabled"> + {position} + </span> + {inSimulation ? ( + <span className="badge badge-default badge-success">Empty Slot</span> + ) : ( + <button className="btn btn-outline-primary" onClick={onAdd}> + <span className="fa fa-plus mr-2" /> + Add machine + </button> + )} + </li> ); export default EmptySlotComponent; diff --git a/src/components/app/sidebars/topology/rack/MachineComponent.js b/src/components/app/sidebars/topology/rack/MachineComponent.js index 0ba4503d..2521f4a2 100644 --- a/src/components/app/sidebars/topology/rack/MachineComponent.js +++ b/src/components/app/sidebars/topology/rack/MachineComponent.js @@ -1,65 +1,78 @@ import React from "react"; import Shapes from "../../../../../shapes"; -import {convertLoadToSimulationColor} from "../../../../../util/simulation-load"; +import { convertLoadToSimulationColor } from "../../../../../util/simulation-load"; -const UnitIcon = ({id, type}) => ( - <div> - <img - src={"/img/topology/" + id + "-icon.png"} - alt={"Machine contains " + type + " units"} - className="img-fluid ml-1" - style={{maxHeight: "35px"}} - /> - </div> +const UnitIcon = ({ id, type }) => ( + <div> + <img + src={"/img/topology/" + id + "-icon.png"} + alt={"Machine contains " + type + " units"} + className="img-fluid ml-1" + style={{ maxHeight: "35px" }} + /> + </div> ); -const MachineComponent = ({position, machine, inSimulation, machineLoad, onClick}) => { - let color = "white"; - if (inSimulation && machineLoad >= 0) { - color = convertLoadToSimulationColor(machineLoad); - } - const hasNoUnits = machine.cpuIds.length + machine.gpuIds.length + machine.memoryIds.length - + machine.storageIds.length === 0; +const MachineComponent = ({ + position, + machine, + inSimulation, + machineLoad, + onClick +}) => { + let color = "white"; + if (inSimulation && machineLoad >= 0) { + color = convertLoadToSimulationColor(machineLoad); + } + const hasNoUnits = + machine.cpuIds.length + + machine.gpuIds.length + + machine.memoryIds.length + + machine.storageIds.length === + 0; - return ( - <li - className="d-flex list-group-item list-group-item-action justify-content-between align-items-center" - onClick={onClick} - style={{backgroundColor: color}} - > - <span className="badge badge-default badge-info mr-1"> - {position} - </span> - <div className="d-inline-flex"> - {machine.cpuIds.length > 0 ? - <UnitIcon id="cpu" type="CPU"/> : - undefined - } - {machine.gpuIds.length > 0 ? - <UnitIcon id="gpu" type="GPU"/> : - undefined - } - {machine.memoryIds.length > 0 ? - <UnitIcon id="memory" type="memory"/> : - undefined - } - {machine.storageIds.length > 0 ? - <UnitIcon id="storage" type="storage"/> : - undefined - } - {hasNoUnits ? - <span className="badge badge-default badge-warning"> - Machine with no units - </span> : - undefined - } - </div> - </li> - ); + return ( + <li + className="d-flex list-group-item list-group-item-action justify-content-between align-items-center" + onClick={onClick} + style={{ backgroundColor: color }} + > + <span className="badge badge-default badge-info mr-1">{position}</span> + <div className="d-inline-flex"> + {machine.cpuIds.length > 0 ? ( + <UnitIcon id="cpu" type="CPU" /> + ) : ( + undefined + )} + {machine.gpuIds.length > 0 ? ( + <UnitIcon id="gpu" type="GPU" /> + ) : ( + undefined + )} + {machine.memoryIds.length > 0 ? ( + <UnitIcon id="memory" type="memory" /> + ) : ( + undefined + )} + {machine.storageIds.length > 0 ? ( + <UnitIcon id="storage" type="storage" /> + ) : ( + undefined + )} + {hasNoUnits ? ( + <span className="badge badge-default badge-warning"> + Machine with no units + </span> + ) : ( + undefined + )} + </div> + </li> + ); }; MachineComponent.propTypes = { - machine: Shapes.Machine + machine: Shapes.Machine }; export default MachineComponent; diff --git a/src/components/app/sidebars/topology/rack/MachineListComponent.js b/src/components/app/sidebars/topology/rack/MachineListComponent.js index fcb90d66..d5521557 100644 --- a/src/components/app/sidebars/topology/rack/MachineListComponent.js +++ b/src/components/app/sidebars/topology/rack/MachineListComponent.js @@ -3,18 +3,24 @@ import EmptySlotContainer from "../../../../../containers/app/sidebars/topology/ import MachineContainer from "../../../../../containers/app/sidebars/topology/rack/MachineContainer"; import "./MachineListComponent.css"; -const MachineListComponent = ({machineIds}) => { - return ( - <ul className="list-group machine-list"> - {machineIds.map((machineId, index) => { - if (machineId === null) { - return <EmptySlotContainer key={index} position={index + 1}/>; - } else { - return <MachineContainer key={index} position={index + 1} machineId={machineId}/>; - } - })} - </ul> - ); +const MachineListComponent = ({ machineIds }) => { + return ( + <ul className="list-group machine-list"> + {machineIds.map((machineId, index) => { + if (machineId === null) { + return <EmptySlotContainer key={index} position={index + 1} />; + } else { + return ( + <MachineContainer + key={index} + position={index + 1} + machineId={machineId} + /> + ); + } + })} + </ul> + ); }; export default MachineListComponent; diff --git a/src/components/app/sidebars/topology/rack/RackNameComponent.js b/src/components/app/sidebars/topology/rack/RackNameComponent.js index ee8d194b..5e095823 100644 --- a/src/components/app/sidebars/topology/rack/RackNameComponent.js +++ b/src/components/app/sidebars/topology/rack/RackNameComponent.js @@ -1,8 +1,8 @@ import React from "react"; import NameComponent from "../NameComponent"; -const RackNameComponent = ({rackName, onEdit}) => ( - <NameComponent name={rackName} onEdit={onEdit}/> +const RackNameComponent = ({ rackName, onEdit }) => ( + <NameComponent name={rackName} onEdit={onEdit} /> ); export default RackNameComponent; diff --git a/src/components/app/sidebars/topology/rack/RackSidebarComponent.js b/src/components/app/sidebars/topology/rack/RackSidebarComponent.js index f563a52f..f832b9b9 100644 --- a/src/components/app/sidebars/topology/rack/RackSidebarComponent.js +++ b/src/components/app/sidebars/topology/rack/RackSidebarComponent.js @@ -7,27 +7,28 @@ import MachineListContainer from "../../../../../containers/app/sidebars/topolog import RackNameContainer from "../../../../../containers/app/sidebars/topology/rack/RackNameContainer"; import "./RackSidebarComponent.css"; -const RackSidebarComponent = ({inSimulation, rackId}) => { - return ( - <div className="rack-sidebar-container flex-column"> - <div className="rack-sidebar-header-container"> - <RackNameContainer/> - <BackToRoomContainer/> - {inSimulation ? - <div> - <LoadBarContainer objectType="rack" objectId={rackId}/> - <LoadChartContainer objectType="rack" objectId={rackId}/> - </div> : - <div> - <DeleteRackContainer/> - </div> - } - </div> - <div className="machine-list-container mt-2"> - <MachineListContainer/> - </div> - </div> - ); +const RackSidebarComponent = ({ inSimulation, rackId }) => { + return ( + <div className="rack-sidebar-container flex-column"> + <div className="rack-sidebar-header-container"> + <RackNameContainer /> + <BackToRoomContainer /> + {inSimulation ? ( + <div> + <LoadBarContainer objectType="rack" objectId={rackId} /> + <LoadChartContainer objectType="rack" objectId={rackId} /> + </div> + ) : ( + <div> + <DeleteRackContainer /> + </div> + )} + </div> + <div className="machine-list-container mt-2"> + <MachineListContainer /> + </div> + </div> + ); }; export default RackSidebarComponent; diff --git a/src/components/app/sidebars/topology/room/BackToBuildingComponent.js b/src/components/app/sidebars/topology/room/BackToBuildingComponent.js index 81384ba5..0409dbdd 100644 --- a/src/components/app/sidebars/topology/room/BackToBuildingComponent.js +++ b/src/components/app/sidebars/topology/room/BackToBuildingComponent.js @@ -1,10 +1,10 @@ import React from "react"; -const BackToBuildingComponent = ({onClick}) => ( - <div className="btn btn-secondary btn-block mb-2" onClick={onClick}> - <span className="fa fa-angle-left mr-2"/> - Back to building - </div> +const BackToBuildingComponent = ({ onClick }) => ( + <div className="btn btn-secondary btn-block mb-2" onClick={onClick}> + <span className="fa fa-angle-left mr-2" /> + Back to building + </div> ); export default BackToBuildingComponent; diff --git a/src/components/app/sidebars/topology/room/DeleteRoomComponent.js b/src/components/app/sidebars/topology/room/DeleteRoomComponent.js index 3f41eac0..5df484b5 100644 --- a/src/components/app/sidebars/topology/room/DeleteRoomComponent.js +++ b/src/components/app/sidebars/topology/room/DeleteRoomComponent.js @@ -1,10 +1,10 @@ import React from "react"; -const DeleteRoomComponent = ({onClick}) => ( - <div className="btn btn-danger btn-block" onClick={onClick}> - <span className="fa fa-trash mr-2"/> - Delete this room - </div> +const DeleteRoomComponent = ({ onClick }) => ( + <div className="btn btn-danger btn-block" onClick={onClick}> + <span className="fa fa-trash mr-2" /> + Delete this room + </div> ); export default DeleteRoomComponent; diff --git a/src/components/app/sidebars/topology/room/RackConstructionComponent.js b/src/components/app/sidebars/topology/room/RackConstructionComponent.js index 9bfe28ce..0982e403 100644 --- a/src/components/app/sidebars/topology/room/RackConstructionComponent.js +++ b/src/components/app/sidebars/topology/room/RackConstructionComponent.js @@ -1,21 +1,25 @@ import React from "react"; -const RackConstructionComponent = ({inRackConstructionMode, onStart, onStop}) => { - if (inRackConstructionMode) { - return ( - <div className="btn btn-primary btn-block" onClick={onStop}> - <span className="fa fa-times mr-2"/> - Stop rack construction - </div> - ); - } - +const RackConstructionComponent = ({ + inRackConstructionMode, + onStart, + onStop +}) => { + if (inRackConstructionMode) { return ( - <div className="btn btn-primary btn-block" onClick={onStart}> - <span className="fa fa-plus mr-2"/> - Start rack construction - </div> + <div className="btn btn-primary btn-block" onClick={onStop}> + <span className="fa fa-times mr-2" /> + Stop rack construction + </div> ); + } + + return ( + <div className="btn btn-primary btn-block" onClick={onStart}> + <span className="fa fa-plus mr-2" /> + Start rack construction + </div> + ); }; export default RackConstructionComponent; diff --git a/src/components/app/sidebars/topology/room/RoomNameComponent.js b/src/components/app/sidebars/topology/room/RoomNameComponent.js index 4d3e41cc..11b88edd 100644 --- a/src/components/app/sidebars/topology/room/RoomNameComponent.js +++ b/src/components/app/sidebars/topology/room/RoomNameComponent.js @@ -1,8 +1,8 @@ import React from "react"; import NameComponent from "../NameComponent"; -const RoomNameComponent = ({roomName, onEdit}) => ( - <NameComponent name={roomName} onEdit={onEdit}/> +const RoomNameComponent = ({ roomName, onEdit }) => ( + <NameComponent name={roomName} onEdit={onEdit} /> ); export default RoomNameComponent; diff --git a/src/components/app/sidebars/topology/room/RoomSidebarComponent.js b/src/components/app/sidebars/topology/room/RoomSidebarComponent.js index 53857408..727c3f43 100644 --- a/src/components/app/sidebars/topology/room/RoomSidebarComponent.js +++ b/src/components/app/sidebars/topology/room/RoomSidebarComponent.js @@ -7,29 +7,30 @@ import RackConstructionContainer from "../../../../../containers/app/sidebars/to import RoomNameContainer from "../../../../../containers/app/sidebars/topology/room/RoomNameContainer"; import RoomTypeContainer from "../../../../../containers/app/sidebars/topology/room/RoomTypeContainer"; -const RoomSidebarComponent = ({roomId, roomType, inSimulation}) => { - let allowedObjects; - if (!inSimulation && roomType === "SERVER") { - allowedObjects = <RackConstructionContainer/>; - } +const RoomSidebarComponent = ({ roomId, roomType, inSimulation }) => { + let allowedObjects; + if (!inSimulation && roomType === "SERVER") { + allowedObjects = <RackConstructionContainer />; + } - return ( + return ( + <div> + <RoomNameContainer /> + <RoomTypeContainer /> + <BackToBuildingContainer /> + {inSimulation ? ( <div> - <RoomNameContainer/> - <RoomTypeContainer/> - <BackToBuildingContainer/> - {inSimulation ? - <div> - <LoadBarContainer objectType="room" objectId={roomId}/> - <LoadChartContainer objectType="room" objectId={roomId}/> - </div> : - <div> - {allowedObjects} - <DeleteRoomContainer/> - </div> - } + <LoadBarContainer objectType="room" objectId={roomId} /> + <LoadChartContainer objectType="room" objectId={roomId} /> </div> - ); + ) : ( + <div> + {allowedObjects} + <DeleteRoomContainer /> + </div> + )} + </div> + ); }; export default RoomSidebarComponent; diff --git a/src/components/app/sidebars/topology/room/RoomTypeComponent.js b/src/components/app/sidebars/topology/room/RoomTypeComponent.js index d42eefb6..46d91c2c 100644 --- a/src/components/app/sidebars/topology/room/RoomTypeComponent.js +++ b/src/components/app/sidebars/topology/room/RoomTypeComponent.js @@ -1,10 +1,8 @@ import React from "react"; -import {ROOM_TYPE_TO_NAME_MAP} from "../../../../../util/room-types"; +import { ROOM_TYPE_TO_NAME_MAP } from "../../../../../util/room-types"; -const RoomTypeComponent = ({roomType}) => ( - <p className="lead"> - {ROOM_TYPE_TO_NAME_MAP[roomType]} - </p> +const RoomTypeComponent = ({ roomType }) => ( + <p className="lead">{ROOM_TYPE_TO_NAME_MAP[roomType]}</p> ); export default RoomTypeComponent; diff --git a/src/components/app/timeline/PlayButtonComponent.js b/src/components/app/timeline/PlayButtonComponent.js index 2b8e5328..1a9b0ced 100644 --- a/src/components/app/timeline/PlayButtonComponent.js +++ b/src/components/app/timeline/PlayButtonComponent.js @@ -1,20 +1,30 @@ import React from "react"; -const PlayButtonComponent = ({isPlaying, currentTick, lastSimulatedTick, onPlay, onPause}) => ( - <div className="play-btn" onClick={() => { - if (isPlaying) { - onPause(); - } else { - if (currentTick !== lastSimulatedTick) { - onPlay(); - } +const PlayButtonComponent = ({ + isPlaying, + currentTick, + lastSimulatedTick, + onPlay, + onPause +}) => ( + <div + className="play-btn" + onClick={() => { + if (isPlaying) { + onPause(); + } else { + if (currentTick !== lastSimulatedTick) { + onPlay(); } - }}> - {isPlaying ? - <span className="fa fa-pause"/> : - <span className="fa fa-play"/> - } - </div> + } + }} + > + {isPlaying ? ( + <span className="fa fa-pause" /> + ) : ( + <span className="fa fa-play" /> + )} + </div> ); export default PlayButtonComponent; diff --git a/src/components/app/timeline/TimelineComponent.js b/src/components/app/timeline/TimelineComponent.js index 950a25bd..0f88b8f4 100644 --- a/src/components/app/timeline/TimelineComponent.js +++ b/src/components/app/timeline/TimelineComponent.js @@ -4,34 +4,34 @@ import TimelineLabelsContainer from "../../../containers/app/timeline/TimelineLa import "./Timeline.css"; class TimelineComponent extends React.Component { - componentDidMount() { - this.interval = setInterval(() => { - if (!this.props.isPlaying) { - return; - } + componentDidMount() { + this.interval = setInterval(() => { + if (!this.props.isPlaying) { + return; + } - if (this.props.currentTick < this.props.lastSimulatedTick) { - this.props.incrementTick(); - } else { - this.props.pauseSimulation(); - } - }, 1000); - } + if (this.props.currentTick < this.props.lastSimulatedTick) { + this.props.incrementTick(); + } else { + this.props.pauseSimulation(); + } + }, 1000); + } - componentWillUnmount() { - clearInterval(this.interval); - } + componentWillUnmount() { + clearInterval(this.interval); + } - render() { - return ( - <div className="timeline-bar"> - <div className="timeline-container"> - <TimelineLabelsContainer/> - <TimelineControlsContainer/> - </div> - </div> - ); - } + render() { + return ( + <div className="timeline-bar"> + <div className="timeline-container"> + <TimelineLabelsContainer /> + <TimelineControlsContainer /> + </div> + </div> + ); + } } export default TimelineComponent; diff --git a/src/components/app/timeline/TimelineControlsComponent.js b/src/components/app/timeline/TimelineControlsComponent.js index 72fc4a60..f3d55154 100644 --- a/src/components/app/timeline/TimelineControlsComponent.js +++ b/src/components/app/timeline/TimelineControlsComponent.js @@ -1,39 +1,49 @@ import React from "react"; import PlayButtonContainer from "../../../containers/app/timeline/PlayButtonContainer"; -import {convertTickToPercentage} from "../../../util/timeline"; +import { convertTickToPercentage } from "../../../util/timeline"; class TimelineControlsComponent extends React.Component { - onTimelineClick(e) { - const percentage = e.nativeEvent.offsetX / this.timeline.clientWidth; - const tick = Math.floor(percentage * (this.props.lastSimulatedTick + 1)); - this.props.goToTick(tick); - } + onTimelineClick(e) { + const percentage = e.nativeEvent.offsetX / this.timeline.clientWidth; + const tick = Math.floor(percentage * (this.props.lastSimulatedTick + 1)); + this.props.goToTick(tick); + } - render() { - return ( - <div className="timeline-controls"> - <PlayButtonContainer/> - <div - className="timeline" - ref={timeline => this.timeline = timeline} - onClick={this.onTimelineClick.bind(this)} - > - <div - className="time-marker" - style={{left: convertTickToPercentage(this.props.currentTick, this.props.lastSimulatedTick)}} - /> - {this.props.sectionTicks.map(sectionTick => ( - <div - key={sectionTick} - className="section-marker" - style={{left: convertTickToPercentage(sectionTick, this.props.lastSimulatedTick)}} - title="Topology changes at this tick" - /> - ))} - </div> - </div> - ); - } + render() { + return ( + <div className="timeline-controls"> + <PlayButtonContainer /> + <div + className="timeline" + ref={timeline => (this.timeline = timeline)} + onClick={this.onTimelineClick.bind(this)} + > + <div + className="time-marker" + style={{ + left: convertTickToPercentage( + this.props.currentTick, + this.props.lastSimulatedTick + ) + }} + /> + {this.props.sectionTicks.map(sectionTick => ( + <div + key={sectionTick} + className="section-marker" + style={{ + left: convertTickToPercentage( + sectionTick, + this.props.lastSimulatedTick + ) + }} + title="Topology changes at this tick" + /> + ))} + </div> + </div> + ); + } } export default TimelineControlsComponent; diff --git a/src/components/app/timeline/TimelineLabelsComponent.js b/src/components/app/timeline/TimelineLabelsComponent.js index e795691f..6943a86f 100644 --- a/src/components/app/timeline/TimelineLabelsComponent.js +++ b/src/components/app/timeline/TimelineLabelsComponent.js @@ -1,11 +1,15 @@ import React from "react"; -import {convertSecondsToFormattedTime} from "../../../util/date-time"; +import { convertSecondsToFormattedTime } from "../../../util/date-time"; -const TimelineLabelsComponent = ({currentTick, lastSimulatedTick}) => ( - <div className="timeline-labels"> - <div className="start-time-label">{convertSecondsToFormattedTime(currentTick)}</div> - <div className="end-time-label">{convertSecondsToFormattedTime(lastSimulatedTick)}</div> +const TimelineLabelsComponent = ({ currentTick, lastSimulatedTick }) => ( + <div className="timeline-labels"> + <div className="start-time-label"> + {convertSecondsToFormattedTime(currentTick)} </div> + <div className="end-time-label"> + {convertSecondsToFormattedTime(lastSimulatedTick)} + </div> + </div> ); export default TimelineLabelsComponent; diff --git a/src/components/experiments/ExperimentListComponent.js b/src/components/experiments/ExperimentListComponent.js index f315ebbf..28c06f29 100644 --- a/src/components/experiments/ExperimentListComponent.js +++ b/src/components/experiments/ExperimentListComponent.js @@ -2,37 +2,42 @@ import PropTypes from "prop-types"; import React from "react"; import ExperimentRowContainer from "../../containers/experiments/ExperimentRowContainer"; -const ExperimentListComponent = ({experimentIds}) => { - return ( - <div className="vertically-expanding-container"> - {experimentIds.length === 0 ? - <div className="alert alert-info"> - <span className="info-icon fa fa-question-circle mr-2"/> - <strong>No experiments here yet...</strong> Add some with the button below! - </div> : - <table className="table table-striped"> - <thead> - <tr> - <th>Name</th> - <th>Path</th> - <th>Trace</th> - <th>Scheduler</th> - <th/> - </tr> - </thead> - <tbody> - {experimentIds.map(experimentId => ( - <ExperimentRowContainer experimentId={experimentId} key={experimentId}/> - ))} - </tbody> - </table> - } +const ExperimentListComponent = ({ experimentIds }) => { + return ( + <div className="vertically-expanding-container"> + {experimentIds.length === 0 ? ( + <div className="alert alert-info"> + <span className="info-icon fa fa-question-circle mr-2" /> + <strong>No experiments here yet...</strong> Add some with the button + below! </div> - ); + ) : ( + <table className="table table-striped"> + <thead> + <tr> + <th>Name</th> + <th>Path</th> + <th>Trace</th> + <th>Scheduler</th> + <th /> + </tr> + </thead> + <tbody> + {experimentIds.map(experimentId => ( + <ExperimentRowContainer + experimentId={experimentId} + key={experimentId} + /> + ))} + </tbody> + </table> + )} + </div> + ); }; ExperimentListComponent.propTypes = { - experimentIds: PropTypes.arrayOf(PropTypes.number).isRequired, + experimentIds: PropTypes.arrayOf(PropTypes.number).isRequired }; export default ExperimentListComponent; diff --git a/src/components/experiments/ExperimentRowComponent.js b/src/components/experiments/ExperimentRowComponent.js index eb9cbacf..e71c6a00 100644 --- a/src/components/experiments/ExperimentRowComponent.js +++ b/src/components/experiments/ExperimentRowComponent.js @@ -1,44 +1,40 @@ import PropTypes from "prop-types"; import React from "react"; -import {Link} from "react-router-dom"; +import { Link } from "react-router-dom"; import Shapes from "../../shapes/index"; -const ExperimentRowComponent = ({experiment, simulationId, onDelete}) => ( - <tr> - <td className="pt-3"> - {experiment.name} - </td> - <td className="pt-3"> - {experiment.path.name ? experiment.path.name : "Path " + experiment.path.id} - </td> - <td className="pt-3"> - {experiment.trace.name} - </td> - <td className="pt-3"> - {experiment.scheduler.name} - </td> - <td className="text-right"> - <Link - to={"/simulations/" + simulationId + "/experiments/" + experiment.id} - className="btn btn-outline-primary btn-sm mr-2" - title="Open this experiment" - > - <span className="fa fa-play"/> - </Link> - <div - className="btn btn-outline-danger btn-sm" - title="Delete this experiment" - onClick={() => onDelete(experiment.id)} - > - <span className="fa fa-trash"/> - </div> - </td> - </tr> +const ExperimentRowComponent = ({ experiment, simulationId, onDelete }) => ( + <tr> + <td className="pt-3">{experiment.name}</td> + <td className="pt-3"> + {experiment.path.name + ? experiment.path.name + : "Path " + experiment.path.id} + </td> + <td className="pt-3">{experiment.trace.name}</td> + <td className="pt-3">{experiment.scheduler.name}</td> + <td className="text-right"> + <Link + to={"/simulations/" + simulationId + "/experiments/" + experiment.id} + className="btn btn-outline-primary btn-sm mr-2" + title="Open this experiment" + > + <span className="fa fa-play" /> + </Link> + <div + className="btn btn-outline-danger btn-sm" + title="Delete this experiment" + onClick={() => onDelete(experiment.id)} + > + <span className="fa fa-trash" /> + </div> + </td> + </tr> ); ExperimentRowComponent.propTypes = { - experiment: Shapes.Experiment.isRequired, - simulationId: PropTypes.number.isRequired, + experiment: Shapes.Experiment.isRequired, + simulationId: PropTypes.number.isRequired }; export default ExperimentRowComponent; diff --git a/src/components/experiments/NewExperimentButtonComponent.js b/src/components/experiments/NewExperimentButtonComponent.js index 559a7218..651172e3 100644 --- a/src/components/experiments/NewExperimentButtonComponent.js +++ b/src/components/experiments/NewExperimentButtonComponent.js @@ -1,17 +1,17 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import PropTypes from "prop-types"; +import React from "react"; -const NewExperimentButtonComponent = ({onClick}) => ( - <div className="bottom-btn-container"> - <div className="btn btn-primary float-right" onClick={onClick}> - <span className="fa fa-plus mr-2"/> - New Experiment - </div> +const NewExperimentButtonComponent = ({ onClick }) => ( + <div className="bottom-btn-container"> + <div className="btn btn-primary float-right" onClick={onClick}> + <span className="fa fa-plus mr-2" /> + New Experiment </div> + </div> ); NewExperimentButtonComponent.propTypes = { - onClick: PropTypes.func.isRequired, + onClick: PropTypes.func.isRequired }; export default NewExperimentButtonComponent; diff --git a/src/components/home/ContactSection.js b/src/components/home/ContactSection.js index fd65b31c..d957297a 100644 --- a/src/components/home/ContactSection.js +++ b/src/components/home/ContactSection.js @@ -5,48 +5,61 @@ import "./ContactSection.css"; import ContentSection from "./ContentSection"; const ContactSection = () => ( - <ContentSection name="contact" title="Contact"> - <div className="row justify-content-center"> - <div className="col-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"> - <Mailto title="Contact us" email="opendc@atlarge-research.com"> - <FontAwesome name="envelope" size="3x" className="mb-2"/> - <div className="w-100"/> - opendc@atlarge-research.com - </Mailto> - </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"> - A project by the - <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"> - <FontAwesome name="exclamation-triangle" size="2x" className="mr-2"/> - <br/> - OpenDC is an experimental tool. Your data may get lost, overwritten, or otherwise become unavailable. - <br/> - The OpenDC authors should in no way be liable in the event this happens (see our <strong><a - href="https://github.com/atlarge-research/opendc/blob/master/LICENSE.md">license</a></strong>). Sorry - for the inconvenience. - </div> - </div> - </ContentSection> + <ContentSection name="contact" title="Contact"> + <div className="row justify-content-center"> + <div className="col-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"> + <Mailto title="Contact us" email="opendc@atlarge-research.com"> + <FontAwesome name="envelope" size="3x" className="mb-2" /> + <div className="w-100" /> + opendc@atlarge-research.com + </Mailto> + </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"> + A project by the + <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"> + <FontAwesome name="exclamation-triangle" size="2x" className="mr-2" /> + <br /> + OpenDC is an experimental tool. Your data may get lost, overwritten, or + otherwise become unavailable. + <br /> + The OpenDC authors should in no way be liable in the event this happens + (see our{" "} + <strong> + <a href="https://github.com/atlarge-research/opendc/blob/master/LICENSE.md"> + license + </a> + </strong>). Sorry for the inconvenience. + </div> + </div> + </ContentSection> ); export default ContactSection; diff --git a/src/components/home/ContentSection.js b/src/components/home/ContentSection.js index 6b4cbca4..2e24ee10 100644 --- a/src/components/home/ContentSection.js +++ b/src/components/home/ContentSection.js @@ -3,17 +3,17 @@ import PropTypes from "prop-types"; import React from "react"; import "./ContentSection.css"; -const ContentSection = ({name, title, children}) => ( - <div id={name} className={classNames(name + "-section", "content-section")}> - <div className="container"> - <h1>{title}</h1> - {children} - </div> +const ContentSection = ({ name, title, children }) => ( + <div id={name} className={classNames(name + "-section", "content-section")}> + <div className="container"> + <h1>{title}</h1> + {children} </div> + </div> ); ContentSection.propTypes = { - name: PropTypes.string.isRequired, + name: PropTypes.string.isRequired }; export default ContentSection; diff --git a/src/components/home/IntroSection.js b/src/components/home/IntroSection.js index 246786f2..59f5face 100644 --- a/src/components/home/IntroSection.js +++ b/src/components/home/IntroSection.js @@ -1,38 +1,40 @@ import React from "react"; 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"> - <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"> - <img src="img/datacenter-drawing.png" - className="col-12 img-fluid" - alt="Schematic top-down view of a datacenter"/> - <p className="col-12 figure-caption text-center"> - <a href="http://www.dolphinhosts.co.uk/wp-content/uploads/2013/07/data-centers.gif"> - Image source - </a> - </p> - </div> - <div className="col-xl-4 col-lg-4 col-md-4 col-sm-8 col-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> + <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"> + <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> - </section> + <div className="col-xl-4 col-lg-4 col-md-4 col-sm-8 col-8"> + <img + src="img/datacenter-drawing.png" + className="col-12 img-fluid" + alt="Schematic top-down view of a datacenter" + /> + <p className="col-12 figure-caption text-center"> + <a href="http://www.dolphinhosts.co.uk/wp-content/uploads/2013/07/data-centers.gif"> + Image source + </a> + </p> + </div> + <div className="col-xl-4 col-lg-4 col-md-4 col-sm-8 col-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> + </section> ); export default IntroSection; diff --git a/src/components/home/JumbotronHeader.js b/src/components/home/JumbotronHeader.js index ba504c18..8a5312b3 100644 --- a/src/components/home/JumbotronHeader.js +++ b/src/components/home/JumbotronHeader.js @@ -2,17 +2,19 @@ import React from "react"; import "./JumbotronHeader.css"; const JumbotronHeader = () => ( - <section className="jumbotron-header"> - <div className="container"> - <div className="jumbotron text-center"> - <h1>Open<span className="dc">DC</span></h1> - <p className="lead"> - Collaborative Datacenter Simulation and Exploration for Everybody - </p> - <img src="img/logo.png" className="img-responsive mt-3" alt="OpenDC"/> - </div> - </div> - </section> + <section className="jumbotron-header"> + <div className="container"> + <div className="jumbotron text-center"> + <h1> + Open<span className="dc">DC</span> + </h1> + <p className="lead"> + Collaborative Datacenter Simulation and Exploration for Everybody + </p> + <img src="img/logo.png" className="img-responsive mt-3" alt="OpenDC" /> + </div> + </div> + </section> ); export default JumbotronHeader; diff --git a/src/components/home/ModelingSection.js b/src/components/home/ModelingSection.js index d3252b9b..17834b0b 100644 --- a/src/components/home/ModelingSection.js +++ b/src/components/home/ModelingSection.js @@ -2,18 +2,23 @@ import React from "react"; import ScreenshotSection from "./ScreenshotSection"; const ModelingSection = () => ( - <ScreenshotSection name="modeling" title="Datacenter Modeling" - imageUrl="https://github.com/atlarge-research/opendc/raw/master/images/opendc-frontend-construction.PNG" - caption="Building a datacenter in OpenDC" - imageIsRight={true}> - <h3>Collaboratively...</h3> - <ul> - <li>Model DC layout, and room locations and types</li> - <li>Place racks in rooms and nodes in racks</li> - <li>Add real-world CPU, GPU, memory, storage and network units to each node</li> - <li>Select from diverse scheduling policies</li> - </ul> - </ScreenshotSection> + <ScreenshotSection + name="modeling" + title="Datacenter Modeling" + imageUrl="https://github.com/atlarge-research/opendc/raw/master/images/opendc-frontend-construction.PNG" + caption="Building a datacenter in OpenDC" + imageIsRight={true} + > + <h3>Collaboratively...</h3> + <ul> + <li>Model DC layout, and room locations and types</li> + <li>Place racks in rooms and nodes in racks</li> + <li> + Add real-world CPU, GPU, memory, storage and network units to each node + </li> + <li>Select from diverse scheduling policies</li> + </ul> + </ScreenshotSection> ); export default ModelingSection; diff --git a/src/components/home/ScreenshotSection.js b/src/components/home/ScreenshotSection.js index 74394dcb..42b8ac77 100644 --- a/src/components/home/ScreenshotSection.js +++ b/src/components/home/ScreenshotSection.js @@ -3,21 +3,30 @@ import React from "react"; import ContentSection from "./ContentSection"; import "./ScreenshotSection.css"; -const ScreenshotSection = ({name, title, imageUrl, caption, imageIsRight, children}) => ( - <ContentSection name={name} title={title}> - <div className="row"> - <div className={classNames("col-xl-5 col-lg-5 col-md-5 col-sm-12 col-12 text-left", - {"order-1": !imageIsRight})}> - {children} - </div> - <div className="col-xl-7 col-lg-7 col-md-7 col-sm-12 col-12"> - <img src={imageUrl} className="col-12 screenshot" alt={caption}/> - <div className="row text-muted justify-content-center"> - {caption} - </div> - </div> - </div> - </ContentSection> +const ScreenshotSection = ({ + name, + title, + imageUrl, + caption, + imageIsRight, + children +}) => ( + <ContentSection name={name} title={title}> + <div className="row"> + <div + className={classNames( + "col-xl-5 col-lg-5 col-md-5 col-sm-12 col-12 text-left", + { "order-1": !imageIsRight } + )} + > + {children} + </div> + <div className="col-xl-7 col-lg-7 col-md-7 col-sm-12 col-12"> + <img src={imageUrl} className="col-12 screenshot" alt={caption} /> + <div className="row text-muted justify-content-center">{caption}</div> + </div> + </div> + </ContentSection> ); export default ScreenshotSection; diff --git a/src/components/home/SimulationSection.js b/src/components/home/SimulationSection.js index eb1f7787..3961e549 100644 --- a/src/components/home/SimulationSection.js +++ b/src/components/home/SimulationSection.js @@ -2,18 +2,24 @@ import React from "react"; import ScreenshotSection from "./ScreenshotSection"; const ModelingSection = () => ( - <ScreenshotSection name="simulation" title="Datacenter Simulation" - imageUrl="https://github.com/atlarge-research/opendc/raw/master/images/opendc-frontend-simulation-zoom.PNG" - caption="Running an experiment in OpenDC" - imageIsRight={false}> - <h3>Working with OpenDC:</h3> - <ul> - <li>Seamlessly switch between construction and simulation modes</li> - <li>Choose one of several predefined workloads (Big Data, Bag of Tasks, Hadoop, etc.)</li> - <li>Play, pause, and skip around the informative simulation timeline</li> - <li>Visualize and demo live</li> - </ul> - </ScreenshotSection> + <ScreenshotSection + name="simulation" + title="Datacenter Simulation" + imageUrl="https://github.com/atlarge-research/opendc/raw/master/images/opendc-frontend-simulation-zoom.PNG" + caption="Running an experiment in OpenDC" + imageIsRight={false} + > + <h3>Working with OpenDC:</h3> + <ul> + <li>Seamlessly switch between construction and simulation modes</li> + <li> + Choose one of several predefined workloads (Big Data, Bag of Tasks, + Hadoop, etc.) + </li> + <li>Play, pause, and skip around the informative simulation timeline</li> + <li>Visualize and demo live</li> + </ul> + </ScreenshotSection> ); export default ModelingSection; diff --git a/src/components/home/StakeholderSection.js b/src/components/home/StakeholderSection.js index ddfe4f7c..6d25fd86 100644 --- a/src/components/home/StakeholderSection.js +++ b/src/components/home/StakeholderSection.js @@ -1,27 +1,42 @@ import React from "react"; 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 src={"img/stakeholders/" + name + ".png"} - className="col-xl-3 col-lg-4 col-md-4 col-sm-4 col-4 img-fluid" alt={title}/> - <div className="text-center mt-2"> - <h4>{title}</h4> - <p>{subtitle}</p> - </div> +const Stakeholder = ({ name, title, subtitle }) => ( + <div className="col-xl-4 col-lg-4 col-md-4 col-sm-6 col-6"> + <img + src={"img/stakeholders/" + name + ".png"} + className="col-xl-3 col-lg-4 col-md-4 col-sm-4 col-4 img-fluid" + alt={title} + /> + <div className="text-center mt-2"> + <h4>{title}</h4> + <p>{subtitle}</p> </div> + </div> ); const StakeholderSection = () => ( - <ContentSection name="stakeholders" title="Stakeholders"> - <div className="row 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> - </ContentSection> + <ContentSection name="stakeholders" title="Stakeholders"> + <div className="row 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> + </ContentSection> ); export default StakeholderSection; diff --git a/src/components/home/TeamSection.js b/src/components/home/TeamSection.js index f9ca3105..f29003f7 100644 --- a/src/components/home/TeamSection.js +++ b/src/components/home/TeamSection.js @@ -1,43 +1,57 @@ import React from "react"; import ContentSection from "./ContentSection"; -const TeamMember = ({photoId, name, description}) => ( - <div className="col-xl-3 col-lg-3 col-md-5 col-sm-6 col-12 justify-content-center"> - <img src={"img/portraits/" + photoId + ".png"} - className="col-xl-10 col-lg-10 col-md-10 col-sm-8 col-5 mb-2 mt-2" - alt={name}/> - <div className="col-12"> - <h4>{name}</h4> - <div className="team-member-description"> - {description} - </div> - </div> +const TeamMember = ({ photoId, name, description }) => ( + <div className="col-xl-3 col-lg-3 col-md-5 col-sm-6 col-12 justify-content-center"> + <img + src={"img/portraits/" + photoId + ".png"} + className="col-xl-10 col-lg-10 col-md-10 col-sm-8 col-5 mb-2 mt-2" + alt={name} + /> + <div className="col-12"> + <h4>{name}</h4> + <div className="team-member-description">{description}</div> </div> + </div> ); const TeamSection = () => ( - <ContentSection name="team" title="Core Team"> - <div className="row justify-content-center"> - <TeamMember photoId="aiosup" name="Prof. dr. ir. Alexandru Iosup" - description="Project Lead"/> - <TeamMember photoId="loverweel" name="Leon Overweel" - description="Product Lead and Software Engineer responsible for the web server, database, and - API specification"/> - <TeamMember photoId="gandreadis" name="Georgios Andreadis" - description="Software Engineer responsible for the frontend web application"/> - <TeamMember photoId="fmastenbroek" name="Fabian Mastenbroek" - description="Software Engineer responsible for the datacenter simulator"/> - </div> - <div className="text-center lead mt-3"> - See - {" "} - <a target="_blank" href="http://atlarge.science/opendc#team" rel="noopener noreferrer"> - atlarge.science/opendc - </a> - {" "} - for the full team! - </div> - </ContentSection> + <ContentSection name="team" title="Core Team"> + <div className="row justify-content-center"> + <TeamMember + photoId="aiosup" + name="Prof. dr. ir. Alexandru Iosup" + description="Project Lead" + /> + <TeamMember + photoId="loverweel" + name="Leon Overweel" + description="Product Lead and Software Engineer responsible for the web server, database, and + API specification" + /> + <TeamMember + photoId="gandreadis" + name="Georgios Andreadis" + description="Software Engineer responsible for the frontend web application" + /> + <TeamMember + photoId="fmastenbroek" + name="Fabian Mastenbroek" + description="Software Engineer responsible for the datacenter simulator" + /> + </div> + <div className="text-center lead mt-3"> + See{" "} + <a + target="_blank" + href="http://atlarge.science/opendc#team" + rel="noopener noreferrer" + > + atlarge.science/opendc + </a>{" "} + for the full team! + </div> + </ContentSection> ); export default TeamSection; diff --git a/src/components/home/TechnologiesSection.js b/src/components/home/TechnologiesSection.js index 5e2ec2fc..fdcfc522 100644 --- a/src/components/home/TechnologiesSection.js +++ b/src/components/home/TechnologiesSection.js @@ -3,46 +3,40 @@ import FontAwesome from "react-fontawesome"; 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"> - <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"> - <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"> - <span style={{minWidth: 100}}> - <FontAwesome name="database" className="mr-2"/> - <strong>Database</strong> - </span> - <span className="text-right"> - MariaDB - </span> - </li> - <li className="d-flex list-group-item justify-content-between align-items-center list-group-item-danger"> - <span style={{minWidth: 100}}> - <FontAwesome name="cogs" className="mr-2"/> - <strong>Simulator</strong> - </span> - <span className="text-right"> - Kotlin - </span> - </li> - </ul> - </ContentSection> + <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"> + <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"> + <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"> + <span style={{ minWidth: 100 }}> + <FontAwesome name="database" className="mr-2" /> + <strong>Database</strong> + </span> + <span className="text-right">MariaDB</span> + </li> + <li className="d-flex list-group-item justify-content-between align-items-center list-group-item-danger"> + <span style={{ minWidth: 100 }}> + <FontAwesome name="cogs" className="mr-2" /> + <strong>Simulator</strong> + </span> + <span className="text-right">Kotlin</span> + </li> + </ul> + </ContentSection> ); export default TechnologiesSection; diff --git a/src/components/modals/ConfirmationModal.js b/src/components/modals/ConfirmationModal.js index 4543cfd4..abdce5ac 100644 --- a/src/components/modals/ConfirmationModal.js +++ b/src/components/modals/ConfirmationModal.js @@ -3,33 +3,35 @@ 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, - }; + static propTypes = { + title: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + show: PropTypes.bool.isRequired, + callback: PropTypes.func.isRequired + }; - onConfirm() { - this.props.callback(true); - } + onConfirm() { + this.props.callback(true); + } - onCancel() { - this.props.callback(false); - } + onCancel() { + this.props.callback(false); + } - 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> - ); - } + 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> + ); + } } export default ConfirmationModal; diff --git a/src/components/modals/Modal.js b/src/components/modals/Modal.js index 1de17455..367cf2da 100644 --- a/src/components/modals/Modal.js +++ b/src/components/modals/Modal.js @@ -4,116 +4,129 @@ import React from "react"; import jQuery from "../../util/jquery"; class Modal extends React.Component { - static propTypes = { - title: PropTypes.string.isRequired, - show: PropTypes.bool.isRequired, - onSubmit: PropTypes.func.isRequired, - onCancel: PropTypes.func.isRequired, - submitButtonType: PropTypes.string, - submitButtonText: PropTypes.string, - }; - static defaultProps = { - submitButtonType: "primary", - submitButtonText: "Save", - }; - static idCounter = 0; + static propTypes = { + title: PropTypes.string.isRequired, + show: PropTypes.bool.isRequired, + onSubmit: PropTypes.func.isRequired, + onCancel: PropTypes.func.isRequired, + submitButtonType: PropTypes.string, + submitButtonText: PropTypes.string + }; + static defaultProps = { + submitButtonType: "primary", + submitButtonText: "Save" + }; + static idCounter = 0; - /** - * Local, up-to-date copy of modal visibility for time between close event and a props update (to prevent duplicate - * close triggers). - */ - visible = false; + // Local, up-to-date copy of modal visibility for time between close event and a props update (to prevent duplicate + // 'close' triggers) + visible = false; - constructor() { - super(); - this.id = "modal-" + Modal.idCounter++; - } - - componentDidMount() { - this.visible = this.props.show; - this.openOrCloseModal(); - - // Trigger auto-focus - jQuery("#" + this.id) - .on("shown.bs.modal", function () { - jQuery(this).find("input").first().focus(); - }) - .on("hide.bs.modal", () => { - if (this.visible) { - this.props.onCancel(); - } - }) - .on("keydown", e => { - e.stopPropagation(); - }); - } + constructor() { + super(); + this.id = "modal-" + Modal.idCounter++; + } - componentDidUpdate() { - this.visible = this.props.show; - this.openOrCloseModal(); - } + componentDidMount() { + this.visible = this.props.show; + this.openOrCloseModal(); - onSubmit() { + // Trigger auto-focus + jQuery("#" + this.id) + .on("shown.bs.modal", function() { + jQuery(this) + .find("input") + .first() + .focus(); + }) + .on("hide.bs.modal", () => { if (this.visible) { - this.props.onSubmit(); - this.visible = false; - this.closeModal(); + this.props.onCancel(); } - } + }) + .on("keydown", e => { + e.stopPropagation(); + }); + } - onCancel() { - if (this.visible) { - this.props.onCancel(); - this.visible = false; - this.closeModal(); - } - } + componentDidUpdate() { + this.visible = this.props.show; + this.openOrCloseModal(); + } - openModal() { - jQuery("#" + this.id).modal("show"); + onSubmit() { + if (this.visible) { + this.props.onSubmit(); + this.visible = false; + this.closeModal(); } + } - closeModal() { - jQuery("#" + this.id).modal("hide"); + onCancel() { + if (this.visible) { + this.props.onCancel(); + this.visible = false; + this.closeModal(); } + } - openOrCloseModal() { - if (this.visible) { - this.openModal(); - } else { - this.closeModal(); - } + openModal() { + jQuery("#" + this.id).modal("show"); + } + + closeModal() { + jQuery("#" + this.id).modal("hide"); + } + + openOrCloseModal() { + if (this.visible) { + this.openModal(); + } else { + this.closeModal(); } + } - render() { - return ( - <div className="modal fade" id={this.id} role="dialog"> - <div className="modal-dialog" role="document"> - <div className="modal-content"> - <div className="modal-header"> - <h5 className="modal-title">{this.props.title}</h5> - <button type="button" className="close" onClick={this.onCancel.bind(this)} - aria-label="Close"> - <span>×</span> - </button> - </div> - <div className="modal-body"> - {this.props.children} - </div> - <div className="modal-footer"> - <button type="button" className="btn btn-secondary" onClick={this.onCancel.bind(this)}> - Close - </button> - <button type="button" className={classNames("btn", "btn-" + this.props.submitButtonType)} - onClick={this.onSubmit.bind(this)}> - {this.props.submitButtonText} - </button> - </div> - </div> - </div> + render() { + return ( + <div className="modal fade" id={this.id} role="dialog"> + <div className="modal-dialog" role="document"> + <div className="modal-content"> + <div className="modal-header"> + <h5 className="modal-title">{this.props.title}</h5> + <button + type="button" + className="close" + onClick={this.onCancel.bind(this)} + aria-label="Close" + > + <span>×</span> + </button> </div> - ); - } + <div className="modal-body">{this.props.children}</div> + <div className="modal-footer"> + <button + type="button" + className="btn btn-secondary" + onClick={this.onCancel.bind(this)} + > + Close + </button> + <button + type="button" + className={classNames( + "btn", + "btn-" + this.props.submitButtonType + )} + onClick={this.onSubmit.bind(this)} + > + {this.props.submitButtonText} + </button> + </div> + </div> + </div> + </div> + ); + } } export default Modal; diff --git a/src/components/modals/TextInputModal.js b/src/components/modals/TextInputModal.js index 132df9fe..cc16f8e1 100644 --- a/src/components/modals/TextInputModal.js +++ b/src/components/modals/TextInputModal.js @@ -3,49 +3,56 @@ import React from "react"; import Modal from "./Modal"; class TextInputModal extends React.Component { - static propTypes = { - title: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - show: PropTypes.bool.isRequired, - callback: PropTypes.func.isRequired, - initialValue: PropTypes.string, - }; + static propTypes = { + title: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + show: PropTypes.bool.isRequired, + callback: PropTypes.func.isRequired, + initialValue: PropTypes.string + }; - componentDidUpdate() { - if (this.props.initialValue) { - this.textInput.value = this.props.initialValue; - } + componentDidUpdate() { + if (this.props.initialValue) { + this.textInput.value = this.props.initialValue; } + } - onSubmit() { - this.props.callback(this.textInput.value); - this.textInput.value = ""; - } + onSubmit() { + this.props.callback(this.textInput.value); + this.textInput.value = ""; + } - onCancel() { - this.props.callback(undefined); - this.textInput.value = ""; - } + onCancel() { + this.props.callback(undefined); + this.textInput.value = ""; + } - render() { - return ( - <Modal title={this.props.title} - show={this.props.show} - onSubmit={this.onSubmit.bind(this)} - onCancel={this.onCancel.bind(this)}> - <form onSubmit={e => { - e.preventDefault(); - this.onSubmit(); - }}> - <div className="form-group"> - <label className="form-control-label">{this.props.label}</label> - <input type="text" className="form-control" - ref={textInput => this.textInput = textInput}/> - </div> - </form> - </Modal> - ); - } + render() { + return ( + <Modal + title={this.props.title} + show={this.props.show} + onSubmit={this.onSubmit.bind(this)} + onCancel={this.onCancel.bind(this)} + > + <form + onSubmit={e => { + e.preventDefault(); + this.onSubmit(); + }} + > + <div className="form-group"> + <label className="form-control-label">{this.props.label}</label> + <input + type="text" + className="form-control" + ref={textInput => (this.textInput = textInput)} + /> + </div> + </form> + </Modal> + ); + } } export default TextInputModal; diff --git a/src/components/modals/custom-components/NewExperimentModalComponent.js b/src/components/modals/custom-components/NewExperimentModalComponent.js index d56d2316..e356fe96 100644 --- a/src/components/modals/custom-components/NewExperimentModalComponent.js +++ b/src/components/modals/custom-components/NewExperimentModalComponent.js @@ -4,88 +4,101 @@ import Shapes from "../../../shapes"; import Modal from "../Modal"; class NewExperimentModalComponent extends React.Component { - static propTypes = { - show: PropTypes.bool.isRequired, - paths: PropTypes.arrayOf(Shapes.Path), - schedulers: PropTypes.arrayOf(Shapes.Scheduler), - traces: PropTypes.arrayOf(Shapes.Trace), - callback: PropTypes.func.isRequired, - }; + static propTypes = { + show: PropTypes.bool.isRequired, + paths: PropTypes.arrayOf(Shapes.Path), + schedulers: PropTypes.arrayOf(Shapes.Scheduler), + traces: PropTypes.arrayOf(Shapes.Trace), + callback: PropTypes.func.isRequired + }; - reset() { - this.textInput.value = ""; - this.pathSelect.selectedIndex = 0; - this.traceSelect.selectedIndex = 0; - this.schedulerSelect.selectedIndex = 0; - } + reset() { + this.textInput.value = ""; + this.pathSelect.selectedIndex = 0; + this.traceSelect.selectedIndex = 0; + this.schedulerSelect.selectedIndex = 0; + } - onSubmit() { - this.props.callback( - this.textInput.value, - parseInt(this.pathSelect.value, 10), - parseInt(this.traceSelect.value, 10), - this.schedulerSelect.value - ); - this.reset(); - } + onSubmit() { + this.props.callback( + this.textInput.value, + parseInt(this.pathSelect.value, 10), + parseInt(this.traceSelect.value, 10), + this.schedulerSelect.value + ); + this.reset(); + } - onCancel() { - this.props.callback(undefined); - this.reset(); - } + onCancel() { + this.props.callback(undefined); + this.reset(); + } - render() { - return ( - <Modal title="New Experiment" - show={this.props.show} - onSubmit={this.onSubmit.bind(this)} - onCancel={this.onCancel.bind(this)}> - <form onSubmit={e => { - e.preventDefault(); - this.onSubmit(); - }}> - <div className="form-group"> - <label className="form-control-label">Name</label> - <input type="text" className="form-control" - ref={textInput => this.textInput = textInput}/> - </div> - <div className="form-group"> - <label className="form-control-label">Path</label> - <select className="form-control" - ref={pathSelect => this.pathSelect = pathSelect}> - {this.props.paths.map(path => ( - <option value={path.id} key={path.id}> - {path.name ? path.name : "Path " + path.id} - </option> - ))} - </select> - </div> - <div className="form-group"> - <label className="form-control-label">Trace</label> - <select className="form-control" - ref={traceSelect => this.traceSelect = traceSelect}> - {this.props.traces.map(trace => ( - <option value={trace.id} key={trace.id}> - {trace.name} - </option> - ))} - </select> - </div> - <div className="form-group"> - <label className="form-control-label">Scheduler</label> - <select className="form-control" - ref={schedulerSelect => this.schedulerSelect = schedulerSelect}> - {this.props.schedulers.map(scheduler => ( - <option value={scheduler.name} key={scheduler.name}> - {scheduler.name} - </option> - ))} - </select> - </div> - </form> - </Modal> - ); - } + render() { + return ( + <Modal + title="New Experiment" + show={this.props.show} + onSubmit={this.onSubmit.bind(this)} + onCancel={this.onCancel.bind(this)} + > + <form + onSubmit={e => { + e.preventDefault(); + this.onSubmit(); + }} + > + <div className="form-group"> + <label className="form-control-label">Name</label> + <input + type="text" + className="form-control" + ref={textInput => (this.textInput = textInput)} + /> + </div> + <div className="form-group"> + <label className="form-control-label">Path</label> + <select + className="form-control" + ref={pathSelect => (this.pathSelect = pathSelect)} + > + {this.props.paths.map(path => ( + <option value={path.id} key={path.id}> + {path.name ? path.name : "Path " + path.id} + </option> + ))} + </select> + </div> + <div className="form-group"> + <label className="form-control-label">Trace</label> + <select + className="form-control" + ref={traceSelect => (this.traceSelect = traceSelect)} + > + {this.props.traces.map(trace => ( + <option value={trace.id} key={trace.id}> + {trace.name} + </option> + ))} + </select> + </div> + <div className="form-group"> + <label className="form-control-label">Scheduler</label> + <select + className="form-control" + ref={schedulerSelect => (this.schedulerSelect = schedulerSelect)} + > + {this.props.schedulers.map(scheduler => ( + <option value={scheduler.name} key={scheduler.name}> + {scheduler.name} + </option> + ))} + </select> + </div> + </form> + </Modal> + ); + } } export default NewExperimentModalComponent; diff --git a/src/components/navigation/AppNavbar.js b/src/components/navigation/AppNavbar.js index 90724a3e..ab4b8412 100644 --- a/src/components/navigation/AppNavbar.js +++ b/src/components/navigation/AppNavbar.js @@ -1,53 +1,58 @@ -import React from 'react'; +import React from "react"; import FontAwesome from "react-fontawesome"; import Mailto from "react-mailto"; -import {Link} from "react-router-dom"; -import Navbar, {NavItem} from "./Navbar"; +import { Link } from "react-router-dom"; +import Navbar, { NavItem } from "./Navbar"; import "./Navbar.css"; -const AppNavbar = ({simulationId, inSimulation, fullWidth}) => ( - <Navbar fullWidth={fullWidth}> - {inSimulation ? - <NavItem route={"/simulations/" + simulationId}> - <Link - className="nav-link" - title="Construction" - to={"/simulations/" + simulationId}> - <FontAwesome name="industry" className="mr-2"/> - Construction - </Link> - </NavItem> : - undefined - } - {inSimulation ? - <NavItem route={"/simulations/" + simulationId + "/experiments"}> - <Link - className="nav-link" - title="Experiments" - to={"/simulations/" + simulationId + "/experiments"}> - <FontAwesome name="play" className="mr-2"/> - Experiments - </Link> - </NavItem> : - undefined - } - <NavItem route="/simulations"> - <Link - className="nav-link" - title="My Simulations" - to="/simulations"> - <FontAwesome name="list" className="mr-2"/> - My Simulations - </Link> - </NavItem> - <NavItem route="email"> - <Mailto className="nav-link" title="Support" email="opendc@atlarge-research.com" - headers={{subject: "[support]"}}> - <FontAwesome name="envelope" className="mr-2"/> - Support - </Mailto> - </NavItem> - </Navbar> +const AppNavbar = ({ simulationId, inSimulation, fullWidth }) => ( + <Navbar fullWidth={fullWidth}> + {inSimulation ? ( + <NavItem route={"/simulations/" + simulationId}> + <Link + className="nav-link" + title="Construction" + to={"/simulations/" + simulationId} + > + <FontAwesome name="industry" className="mr-2" /> + Construction + </Link> + </NavItem> + ) : ( + undefined + )} + {inSimulation ? ( + <NavItem route={"/simulations/" + simulationId + "/experiments"}> + <Link + className="nav-link" + title="Experiments" + to={"/simulations/" + simulationId + "/experiments"} + > + <FontAwesome name="play" className="mr-2" /> + Experiments + </Link> + </NavItem> + ) : ( + undefined + )} + <NavItem route="/simulations"> + <Link className="nav-link" title="My Simulations" to="/simulations"> + <FontAwesome name="list" className="mr-2" /> + My Simulations + </Link> + </NavItem> + <NavItem route="email"> + <Mailto + className="nav-link" + title="Support" + email="opendc@atlarge-research.com" + headers={{ subject: "[support]" }} + > + <FontAwesome name="envelope" className="mr-2" /> + Support + </Mailto> + </NavItem> + </Navbar> ); export default AppNavbar; diff --git a/src/components/navigation/HomeNavbar.js b/src/components/navigation/HomeNavbar.js index 4d821325..5d08bf3c 100644 --- a/src/components/navigation/HomeNavbar.js +++ b/src/components/navigation/HomeNavbar.js @@ -1,22 +1,24 @@ -import React from 'react'; +import React from "react"; import Navbar from "./Navbar"; import "./Navbar.css"; -const ScrollNavItem = ({id, name}) => ( - <li className="nav-item"> - <a className="nav-link" href={id}>{name}</a> - </li> +const ScrollNavItem = ({ id, name }) => ( + <li className="nav-item"> + <a className="nav-link" href={id}> + {name} + </a> + </li> ); const HomeNavbar = () => ( - <Navbar fullWidth={false}> - <ScrollNavItem id="#stakeholders" name="Stakeholders"/> - <ScrollNavItem id="#modeling" name="Modeling"/> - <ScrollNavItem id="#simulation" name="Simulation"/> - <ScrollNavItem id="#technologies" name="Technologies"/> - <ScrollNavItem id="#team" name="Team"/> - <ScrollNavItem id="#contact" name="Contact"/> - </Navbar> + <Navbar fullWidth={false}> + <ScrollNavItem id="#stakeholders" name="Stakeholders" /> + <ScrollNavItem id="#modeling" name="Modeling" /> + <ScrollNavItem id="#simulation" name="Simulation" /> + <ScrollNavItem id="#technologies" name="Technologies" /> + <ScrollNavItem id="#team" name="Team" /> + <ScrollNavItem id="#contact" name="Contact" /> + </Navbar> ); export default HomeNavbar; diff --git a/src/components/navigation/LogoutButton.js b/src/components/navigation/LogoutButton.js index d58776dc..800a3da8 100644 --- a/src/components/navigation/LogoutButton.js +++ b/src/components/navigation/LogoutButton.js @@ -1,16 +1,16 @@ import PropTypes from "prop-types"; import React from "react"; import FontAwesome from "react-fontawesome"; -import {Link} from "react-router-dom"; +import { Link } from "react-router-dom"; -const LogoutButton = ({onLogout}) => ( - <Link className="logout nav-link" title="Sign out" to="#" onClick={onLogout}> - <FontAwesome name="power-off" size="lg"/> - </Link> +const LogoutButton = ({ onLogout }) => ( + <Link className="logout nav-link" title="Sign out" to="#" onClick={onLogout}> + <FontAwesome name="power-off" size="lg" /> + </Link> ); LogoutButton.propTypes = { - onLogout: PropTypes.func.isRequired, + onLogout: PropTypes.func.isRequired }; export default LogoutButton; diff --git a/src/components/navigation/Navbar.js b/src/components/navigation/Navbar.js index 4981bb53..fa2516f5 100644 --- a/src/components/navigation/Navbar.js +++ b/src/components/navigation/Navbar.js @@ -1,7 +1,7 @@ import classNames from "classnames"; -import React from 'react'; -import {Link, withRouter} from "react-router-dom"; -import {userIsLoggedIn} from "../../auth/index"; +import React from "react"; +import { Link, withRouter } from "react-router-dom"; +import { userIsLoggedIn } from "../../auth/index"; import Login from "../../containers/auth/Login"; import Logout from "../../containers/auth/Logout"; import ProfileName from "../../containers/auth/ProfileName"; @@ -9,73 +9,83 @@ import "./Navbar.css"; export const NAVBAR_HEIGHT = 60; -export const NavItem = withRouter(props => <NavItemWithoutRoute {...props}/>); -export const LoggedInSection = withRouter(props => <LoggedInSectionWithoutRoute {...props}/>); +export const NavItem = withRouter(props => <NavItemWithoutRoute {...props} />); +export const LoggedInSection = withRouter(props => ( + <LoggedInSectionWithoutRoute {...props} /> +)); -const NavItemWithoutRoute = ({route, location, children}) => ( - <li className={classNames("nav-item", location.pathname === route ? "active" : undefined)}> - {children} - </li> +const NavItemWithoutRoute = ({ route, location, children }) => ( + <li + className={classNames( + "nav-item", + location.pathname === route ? "active" : undefined + )} + > + {children} + </li> ); -const LoggedInSectionWithoutRoute = ({location}) => ( - <ul className="navbar-nav auth-links"> - {userIsLoggedIn() ? - [ - location.pathname === "/" ? - <NavItem route="/simulations" key="simulations"> - <Link className="nav-link" title="My Simulations" to="/simulations"> - My Simulations - </Link> - </NavItem> : - <NavItem route="/profile" key="profile"> - <Link className="nav-link" title="My Profile" to="/profile"> - <ProfileName/> - </Link> - </NavItem>, - <NavItem route="logout" key="logout"> - <Logout/> - </NavItem> - ] : - <NavItem route="login"> - <Login visible={true}/> - </NavItem> - } - </ul> - ) -; - -const Navbar = ({fullWidth, children}) => ( - <nav className="navbar fixed-top navbar-expand-lg navbar-light bg-faded" id="navbar"> - <div className={fullWidth ? "container-fluid" : "container"}> - <button - className="navbar-toggler navbar-toggler-right" - type="button" - data-toggle="collapse" - data-target="#navbarSupportedContent" - aria-controls="navbarSupportedContent" - aria-expanded="false" - aria-label="Toggle navigation" - > - <span className="navbar-toggler-icon"/> - </button> - <Link - className="navbar-brand opendc-brand" - to="/" - title="OpenDC" - onClick={() => window.scrollTo(0, 0)} - > - <img src="/img/logo.png" alt="OpenDC"/> +const LoggedInSectionWithoutRoute = ({ location }) => ( + <ul className="navbar-nav auth-links"> + {userIsLoggedIn() ? ( + [ + location.pathname === "/" ? ( + <NavItem route="/simulations" key="simulations"> + <Link className="nav-link" title="My Simulations" to="/simulations"> + My Simulations + </Link> + </NavItem> + ) : ( + <NavItem route="/profile" key="profile"> + <Link className="nav-link" title="My Profile" to="/profile"> + <ProfileName /> </Link> + </NavItem> + ), + <NavItem route="logout" key="logout"> + <Logout /> + </NavItem> + ] + ) : ( + <NavItem route="login"> + <Login visible={true} /> + </NavItem> + )} + </ul> +); + +const Navbar = ({ fullWidth, children }) => ( + <nav + className="navbar fixed-top navbar-expand-lg navbar-light bg-faded" + id="navbar" + > + <div className={fullWidth ? "container-fluid" : "container"}> + <button + className="navbar-toggler navbar-toggler-right" + type="button" + data-toggle="collapse" + data-target="#navbarSupportedContent" + aria-controls="navbarSupportedContent" + aria-expanded="false" + aria-label="Toggle navigation" + > + <span className="navbar-toggler-icon" /> + </button> + <Link + className="navbar-brand opendc-brand" + to="/" + title="OpenDC" + onClick={() => window.scrollTo(0, 0)} + > + <img src="/img/logo.png" alt="OpenDC" /> + </Link> - <div className="collapse navbar-collapse" id="navbarSupportedContent"> - <ul className="navbar-nav mr-auto"> - {children} - </ul> - <LoggedInSection/> - </div> - </div> - </nav> + <div className="collapse navbar-collapse" id="navbarSupportedContent"> + <ul className="navbar-nav mr-auto">{children}</ul> + <LoggedInSection /> + </div> + </div> + </nav> ); export default Navbar; diff --git a/src/components/not-found/BlinkingCursor.js b/src/components/not-found/BlinkingCursor.js index f6c9768c..eea89e7b 100644 --- a/src/components/not-found/BlinkingCursor.js +++ b/src/components/not-found/BlinkingCursor.js @@ -1,8 +1,6 @@ import React from "react"; import "./BlinkingCursor.css"; -const BlinkingCursor = () => ( - <span className="blinking-cursor">_</span> -); +const BlinkingCursor = () => <span className="blinking-cursor">_</span>; export default BlinkingCursor; diff --git a/src/components/not-found/CodeBlock.js b/src/components/not-found/CodeBlock.js index 24d100cc..46dc4402 100644 --- a/src/components/not-found/CodeBlock.js +++ b/src/components/not-found/CodeBlock.js @@ -2,29 +2,33 @@ import React from "react"; import "./CodeBlock.css"; const CodeBlock = () => { - const textBlock = - " oo oooo oo <br/>" + - " oo oo oo oo <br/>" + - " oo oo oo oo <br/>" + - " oooooo oo oo oooooo <br/>" + - " oo oo oo oo <br/>" + - " oo oooo oo <br/>"; - const charList = textBlock.split(''); + const textBlock = + " oo oooo oo <br/>" + + " oo oo oo oo <br/>" + + " oo oo oo oo <br/>" + + " oooooo oo oo oooooo <br/>" + + " oo oo oo oo <br/>" + + " oo oooo oo <br/>"; + const charList = textBlock.split(""); - // Binary representation of the string "OpenDC!" ;) - const binaryString = "01001111011100000110010101101110010001000100001100100001"; + // Binary representation of the string "OpenDC!" ;) + const binaryString = + "01001111011100000110010101101110010001000100001100100001"; - let binaryIndex = 0; - for (let i = 0; i < charList.length; i++) { - if (charList[i] === "o") { - charList[i] = binaryString[binaryIndex]; - binaryIndex++; - } + let binaryIndex = 0; + for (let i = 0; i < charList.length; i++) { + if (charList[i] === "o") { + charList[i] = binaryString[binaryIndex]; + binaryIndex++; } + } - return ( - <div className="code-block" dangerouslySetInnerHTML={{__html: textBlock}}/> - ); + return ( + <div + className="code-block" + dangerouslySetInnerHTML={{ __html: textBlock }} + /> + ); }; export default CodeBlock; diff --git a/src/components/not-found/TerminalWindow.js b/src/components/not-found/TerminalWindow.js index 52d3c062..c6b8b78b 100644 --- a/src/components/not-found/TerminalWindow.js +++ b/src/components/not-found/TerminalWindow.js @@ -1,26 +1,29 @@ import React from "react"; -import {Link} from "react-router-dom"; +import { Link } from "react-router-dom"; import BlinkingCursor from "./BlinkingCursor"; import CodeBlock from "./CodeBlock"; import "./TerminalWindow.css"; const TerminalWindow = () => ( - <div className="terminal-window"> - <div className="terminal-header">Terminal -- bash</div> - <div className="terminal-body"> - <div className="segfault">$ status<br/> - opendc[4264]: segfault at 0000051497be459d1 err 12 in libopendc.9.0.4<br/> - opendc[4269]: segfault at 000004234855fc2db err 3 in libopendc.9.0.4<br/> - opendc[4270]: STDERR Page does not exist<br/> - </div> - <CodeBlock/> - <div className="sub-title">Got lost?<BlinkingCursor/></div> - <Link to="/" className="home-btn"> - <span className="fa fa-home"/> GET ME BACK TO OPENDC - </Link> - </div> + <div className="terminal-window"> + <div className="terminal-header">Terminal -- bash</div> + <div className="terminal-body"> + <div className="segfault"> + $ status<br /> + opendc[4264]: segfault at 0000051497be459d1 err 12 in libopendc.9.0.4<br + /> + opendc[4269]: segfault at 000004234855fc2db err 3 in libopendc.9.0.4<br /> + opendc[4270]: STDERR Page does not exist<br /> + </div> + <CodeBlock /> + <div className="sub-title"> + Got lost?<BlinkingCursor /> + </div> + <Link to="/" className="home-btn"> + <span className="fa fa-home" /> GET ME BACK TO OPENDC + </Link> </div> + </div> ); - export default TerminalWindow; diff --git a/src/components/simulations/FilterButton.js b/src/components/simulations/FilterButton.js index b26dd231..aa41f180 100644 --- a/src/components/simulations/FilterButton.js +++ b/src/components/simulations/FilterButton.js @@ -1,22 +1,24 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; +import classNames from "classnames"; +import PropTypes from "prop-types"; +import React from "react"; -const FilterButton = ({active, children, onClick}) => ( - <button className={classNames("btn btn-secondary", {"active": active})} - onClick={() => { - if (!active) { - onClick(); - } - }}> - {children} - </button> +const FilterButton = ({ active, children, onClick }) => ( + <button + className={classNames("btn btn-secondary", { active: active })} + onClick={() => { + if (!active) { + onClick(); + } + }} + > + {children} + </button> ); FilterButton.propTypes = { - active: PropTypes.bool.isRequired, - children: PropTypes.node.isRequired, - onClick: PropTypes.func.isRequired + active: PropTypes.bool.isRequired, + children: PropTypes.node.isRequired, + onClick: PropTypes.func.isRequired }; export default FilterButton; diff --git a/src/components/simulations/FilterPanel.js b/src/components/simulations/FilterPanel.js index 504e24e4..836c0842 100644 --- a/src/components/simulations/FilterPanel.js +++ b/src/components/simulations/FilterPanel.js @@ -1,13 +1,13 @@ -import React from 'react'; +import React from "react"; import FilterLink from "../../containers/simulations/FilterLink"; import "./FilterPanel.css"; const FilterPanel = () => ( - <div className="btn-group filter-panel mb-2"> - <FilterLink filter="SHOW_ALL">All Simulations</FilterLink> - <FilterLink filter="SHOW_OWN">My Simulations</FilterLink> - <FilterLink filter="SHOW_SHARED">Shared with me</FilterLink> - </div> + <div className="btn-group filter-panel mb-2"> + <FilterLink filter="SHOW_ALL">All Simulations</FilterLink> + <FilterLink filter="SHOW_OWN">My Simulations</FilterLink> + <FilterLink filter="SHOW_SHARED">Shared with me</FilterLink> + </div> ); export default FilterPanel; diff --git a/src/components/simulations/NewSimulationButtonComponent.js b/src/components/simulations/NewSimulationButtonComponent.js index 74036c1b..7e12d30f 100644 --- a/src/components/simulations/NewSimulationButtonComponent.js +++ b/src/components/simulations/NewSimulationButtonComponent.js @@ -1,17 +1,17 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import PropTypes from "prop-types"; +import React from "react"; -const NewSimulationButtonComponent = ({onClick}) => ( - <div className="bottom-btn-container"> - <div className="btn btn-primary float-right" onClick={onClick}> - <span className="fa fa-plus mr-2"/> - New Simulation - </div> +const NewSimulationButtonComponent = ({ onClick }) => ( + <div className="bottom-btn-container"> + <div className="btn btn-primary float-right" onClick={onClick}> + <span className="fa fa-plus mr-2" /> + New Simulation </div> + </div> ); NewSimulationButtonComponent.propTypes = { - onClick: PropTypes.func.isRequired, + onClick: PropTypes.func.isRequired }; export default NewSimulationButtonComponent; diff --git a/src/components/simulations/SimulationActionButtons.js b/src/components/simulations/SimulationActionButtons.js index c8325a71..46f4f159 100644 --- a/src/components/simulations/SimulationActionButtons.js +++ b/src/components/simulations/SimulationActionButtons.js @@ -1,37 +1,37 @@ import PropTypes from "prop-types"; -import React from 'react'; -import {Link} from "react-router-dom"; +import React from "react"; +import { Link } from "react-router-dom"; -const SimulationActionButtons = ({simulationId, onViewUsers, onDelete}) => ( - <td className="text-right"> - <Link - to={"/simulations/" + simulationId} - className="btn btn-outline-primary btn-sm mr-2" - title="Open this simulation" - > - <span className="fa fa-play"/> - </Link> - <div - className="btn btn-outline-success btn-sm disabled mr-2" - title="View and edit collaborators (not supported yet)" - onClick={() => onViewUsers(simulationId)} - > - <span className="fa fa-users"/> - </div> - <div - className="btn btn-outline-danger btn-sm" - title="Delete this simulation" - onClick={() => onDelete(simulationId)} - > - <span className="fa fa-trash"/> - </div> - </td> +const SimulationActionButtons = ({ simulationId, onViewUsers, onDelete }) => ( + <td className="text-right"> + <Link + to={"/simulations/" + simulationId} + className="btn btn-outline-primary btn-sm mr-2" + title="Open this simulation" + > + <span className="fa fa-play" /> + </Link> + <div + className="btn btn-outline-success btn-sm disabled mr-2" + title="View and edit collaborators (not supported yet)" + onClick={() => onViewUsers(simulationId)} + > + <span className="fa fa-users" /> + </div> + <div + className="btn btn-outline-danger btn-sm" + title="Delete this simulation" + onClick={() => onDelete(simulationId)} + > + <span className="fa fa-trash" /> + </div> + </td> ); SimulationActionButtons.propTypes = { - simulationId: PropTypes.number.isRequired, - onViewUsers: PropTypes.func, - onDelete: PropTypes.func, + simulationId: PropTypes.number.isRequired, + onViewUsers: PropTypes.func, + onDelete: PropTypes.func }; export default SimulationActionButtons; diff --git a/src/components/simulations/SimulationAuthList.js b/src/components/simulations/SimulationAuthList.js index 27b141fe..f29dc96d 100644 --- a/src/components/simulations/SimulationAuthList.js +++ b/src/components/simulations/SimulationAuthList.js @@ -1,38 +1,43 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import PropTypes from "prop-types"; +import React from "react"; import Shapes from "../../shapes/index"; import SimulationAuthRow from "./SimulationAuthRow"; -const SimulationAuthList = ({authorizations}) => { - return ( - <div className="vertically-expanding-container"> - {authorizations.length === 0 ? - <div className="alert alert-info"> - <span className="info-icon fa fa-question-circle mr-2"/> - <strong>No simulations here yet...</strong> Add some with the 'New Simulation' button! - </div> : - <table className="table table-striped"> - <thead> - <tr> - <th>Simulation name</th> - <th>Last edited</th> - <th>Access rights</th> - <th/> - </tr> - </thead> - <tbody> - {authorizations.map(authorization => ( - <SimulationAuthRow simulationAuth={authorization} key={authorization.simulation.id}/> - ))} - </tbody> - </table> - } +const SimulationAuthList = ({ authorizations }) => { + return ( + <div className="vertically-expanding-container"> + {authorizations.length === 0 ? ( + <div className="alert alert-info"> + <span className="info-icon fa fa-question-circle mr-2" /> + <strong>No simulations here yet...</strong> Add some with the 'New + Simulation' button! </div> - ); + ) : ( + <table className="table table-striped"> + <thead> + <tr> + <th>Simulation name</th> + <th>Last edited</th> + <th>Access rights</th> + <th /> + </tr> + </thead> + <tbody> + {authorizations.map(authorization => ( + <SimulationAuthRow + simulationAuth={authorization} + key={authorization.simulation.id} + /> + ))} + </tbody> + </table> + )} + </div> + ); }; SimulationAuthList.propTypes = { - authorizations: PropTypes.arrayOf(Shapes.Authorization).isRequired, + authorizations: PropTypes.arrayOf(Shapes.Authorization).isRequired }; export default SimulationAuthList; diff --git a/src/components/simulations/SimulationAuthRow.js b/src/components/simulations/SimulationAuthRow.js index 5f452f3e..b638fbce 100644 --- a/src/components/simulations/SimulationAuthRow.js +++ b/src/components/simulations/SimulationAuthRow.js @@ -1,28 +1,32 @@ -import classNames from 'classnames'; -import React from 'react'; +import classNames from "classnames"; +import React from "react"; import SimulationActions from "../../containers/simulations/SimulationActions"; import Shapes from "../../shapes/index"; -import {AUTH_DESCRIPTION_MAP, AUTH_ICON_MAP} from "../../util/authorizations"; -import {parseAndFormatDateTime} from "../../util/date-time"; +import { AUTH_DESCRIPTION_MAP, AUTH_ICON_MAP } from "../../util/authorizations"; +import { parseAndFormatDateTime } from "../../util/date-time"; -const SimulationAuthRow = ({simulationAuth}) => ( - <tr> - <td className="pt-3"> - {simulationAuth.simulation.name} - </td> - <td className="pt-3"> - {parseAndFormatDateTime(simulationAuth.simulation.datetimeLastEdited)} - </td> - <td className="pt-3"> - <span className={classNames("fa", "fa-" + AUTH_ICON_MAP[simulationAuth.authorizationLevel], "mr-2")}/> - {AUTH_DESCRIPTION_MAP[simulationAuth.authorizationLevel]} - </td> - <SimulationActions simulationId={simulationAuth.simulation.id}/> - </tr> +const SimulationAuthRow = ({ simulationAuth }) => ( + <tr> + <td className="pt-3">{simulationAuth.simulation.name}</td> + <td className="pt-3"> + {parseAndFormatDateTime(simulationAuth.simulation.datetimeLastEdited)} + </td> + <td className="pt-3"> + <span + className={classNames( + "fa", + "fa-" + AUTH_ICON_MAP[simulationAuth.authorizationLevel], + "mr-2" + )} + /> + {AUTH_DESCRIPTION_MAP[simulationAuth.authorizationLevel]} + </td> + <SimulationActions simulationId={simulationAuth.simulation.id} /> + </tr> ); SimulationAuthRow.propTypes = { - simulationAuth: Shapes.Authorization.isRequired, + simulationAuth: Shapes.Authorization.isRequired }; export default SimulationAuthRow; |
