diff options
| author | mjkwiatkowski <mati.rewa@gmail.com> | 2026-02-16 15:18:21 +0100 |
|---|---|---|
| committer | mjkwiatkowski <mati.rewa@gmail.com> | 2026-02-16 15:18:21 +0100 |
| commit | 2f16cb0f48eca4453e3e894b3d45a3aa09e6dcc0 (patch) | |
| tree | 672d98baa2ac071f2c30de06d613254d0d8cd105 /opendc-web/opendc-web-ui/src/components/topologies/map | |
| parent | 86d35fcec83057e346e4982b5a6908f25342a392 (diff) | |
Diffstat (limited to 'opendc-web/opendc-web-ui/src/components/topologies/map')
36 files changed, 0 insertions, 1365 deletions
diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js deleted file mode 100644 index ccf637e5..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/GrayContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' -import GrayLayer from './elements/GrayLayer' - -function GrayContainer() { - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - return <GrayLayer onClick={onClick} /> -} - -export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js b/opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js deleted file mode 100644 index 4c3b2757..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapConstants.js +++ /dev/null @@ -1,25 +0,0 @@ -export const MAP_SIZE = 50 -export const TILE_SIZE_IN_PIXELS = 100 -export const TILE_SIZE_IN_METERS = 0.5 -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 GRID_LINE_WIDTH_IN_PIXELS = 2 -export const WALL_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 -export const OBJECT_BORDER_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 16 -export const TILE_PLUS_WIDTH_IN_PIXELS = TILE_SIZE_IN_PIXELS / 10 - -export const RACK_FILL_ICON_WIDTH = OBJECT_SIZE_IN_PIXELS / 3 -export const RACK_FILL_ICON_OPACITY = 0.8 - -export const MAP_MOVE_PIXELS_PER_EVENT = 20 -export const MAP_SCALE_PER_EVENT = 1.1 -export const MAP_MIN_SCALE = 0.5 -export const MAP_MAX_SCALE = 1.5 - -export const MAX_NUM_UNITS_PER_MACHINE = 6 -export const DEFAULT_RACK_SLOT_CAPACITY = 42 -export const DEFAULT_RACK_POWER_CAPACITY = 10000 diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js deleted file mode 100644 index e2b626ec..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js +++ /dev/null @@ -1,83 +0,0 @@ -import React, { useRef, useState } from 'react' -import PropTypes from 'prop-types' -import { useHotkeys } from 'react-hotkeys-hook' -import { Stage } from 'react-konva' -import { MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_MOVE_PIXELS_PER_EVENT, MAP_SCALE_PER_EVENT } from './MapConstants' -import useResizeObserver from 'use-resize-observer' -import { mapContainer } from './MapStage.module.css' -import MapLayer from './layers/MapLayer' -import RoomHoverLayer from './layers/RoomHoverLayer' -import ObjectHoverLayer from './layers/ObjectHoverLayer' -import ScaleIndicator from './controls/ScaleIndicator' -import Toolbar from './controls/Toolbar' - -function MapStage({ hotkeysRef }) { - const stageRef = useRef(null) - const { width = 500, height = 500 } = useResizeObserver({ ref: stageRef.current?.attrs?.container }) - const [[x, y], setPos] = useState([0, 0]) - const [scale, setScale] = useState(1) - - const clampScale = (target) => Math.min(Math.max(target, MAP_MIN_SCALE), MAP_MAX_SCALE) - const moveWithDelta = (deltaX, deltaY) => setPos(([x, y]) => [x + deltaX, y + deltaY]) - - const onZoom = (e) => { - e.evt.preventDefault() - - const stage = stageRef.current.getStage() - const oldScale = scale - - const pointer = stage.getPointerPosition() - const mousePointTo = { - x: (pointer.x - x) / oldScale, - y: (pointer.y - y) / oldScale, - } - - const newScale = clampScale(e.evt.deltaY > 0 ? oldScale * MAP_SCALE_PER_EVENT : oldScale / MAP_SCALE_PER_EVENT) - - setScale(newScale) - setPos([pointer.x - mousePointTo.x * newScale, pointer.y - mousePointTo.y * newScale]) - } - const onZoomButton = (zoomIn) => - setScale((scale) => clampScale(zoomIn ? scale * MAP_SCALE_PER_EVENT : scale / MAP_SCALE_PER_EVENT)) - const onDragEnd = (e) => setPos([e.target.x(), e.target.y()]) - const onExport = () => { - const download = document.createElement('a') - download.href = stageRef.current.getStage().toDataURL() - download.download = 'opendc-canvas-export-' + Date.now() + '.png' - download.click() - } - - useHotkeys('left, a', () => moveWithDelta(MAP_MOVE_PIXELS_PER_EVENT, 0), { element: hotkeysRef.current }) - useHotkeys('right, d', () => moveWithDelta(-MAP_MOVE_PIXELS_PER_EVENT, 0), { element: hotkeysRef.current }) - useHotkeys('up, w', () => moveWithDelta(0, MAP_MOVE_PIXELS_PER_EVENT), { element: hotkeysRef.current }) - useHotkeys('down, s', () => moveWithDelta(0, -MAP_MOVE_PIXELS_PER_EVENT), { element: hotkeysRef.current }) - - return ( - <> - <Stage - className={mapContainer} - ref={stageRef} - onWheel={onZoom} - onDragEnd={onDragEnd} - draggable - width={width} - height={height} - scale={{ x: scale, y: scale }} - x={x} - y={y} - > - <MapLayer /> - <RoomHoverLayer /> - <ObjectHoverLayer /> - </Stage> - <ScaleIndicator scale={scale} /> - <Toolbar onZoom={onZoomButton} onExport={onExport} /> - </> - ) -} - -MapStage.propTypes = { - hotkeysRef: PropTypes.object.isRequired, -} - -export default MapStage diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.css b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.css deleted file mode 100644 index 47c3dde2..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.css +++ /dev/null @@ -1,29 +0,0 @@ -/*! - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -.mapContainer { - background-color: var(--pf-global--Color--light-200); - position: relative; - display: flex; - width: 100%; - height: 100%; -} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js deleted file mode 100644 index 14449a91..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackContainer.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useSelector } from 'react-redux' -import { Tile } from '../../../shapes' -import RackGroup from './groups/RackGroup' - -function RackContainer({ tile }) { - const interactionLevel = useSelector((state) => state.interactionLevel) - return <RackGroup interactionLevel={interactionLevel} tile={tile} /> -} - -RackContainer.propTypes = { - tile: Tile, -} - -export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js deleted file mode 100644 index a1ca7426..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import RackFillBar from './elements/RackFillBar' - -function RackSpaceFillContainer({ rackId, ...props }) { - const fillFraction = useSelector((state) => { - const rack = state.topology.racks[rackId] - if (!rack) { - return 0 - } - - const { machines, cpus, gpus, memories, storages } = state.topology - let energyConsumptionTotal = 0 - - for (const machineId of rack.machines) { - if (!machineId) { - continue - } - const machine = machines[machineId] - machine.cpus.forEach((id) => (energyConsumptionTotal += cpus[id].energyConsumptionW)) - machine.gpus.forEach((id) => (energyConsumptionTotal += gpus[id].energyConsumptionW)) - machine.memories.forEach((id) => (energyConsumptionTotal += memories[id].energyConsumptionW)) - machine.storages.forEach((id) => (energyConsumptionTotal += storages[id].energyConsumptionW)) - } - - return Math.min(1, energyConsumptionTotal / rack.powerCapacityW) - }) - return <RackFillBar {...props} type="energy" fillFraction={fillFraction} /> -} - -RackSpaceFillContainer.propTypes = { - rackId: PropTypes.string.isRequired, -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js deleted file mode 100644 index 2039a9d3..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import RackFillBar from './elements/RackFillBar' - -function RackSpaceFillContainer({ rackId, ...props }) { - const rack = useSelector((state) => state.topology.racks[rackId]) - - if (!rack) { - return null - } - - return <RackFillBar {...props} type="space" fillFraction={rack.machines.length / rack.capacity} /> -} - -RackSpaceFillContainer.propTypes = { - rackId: PropTypes.string.isRequired, -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js deleted file mode 100644 index 76785bea..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' -import RoomGroup from './groups/RoomGroup' - -function RoomContainer({ roomId, ...props }) { - const interactionLevel = useSelector((state) => state.interactionLevel) - const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) - const room = useSelector((state) => state.topology.rooms[roomId]) - const dispatch = useDispatch() - - if (!room) { - return null - } - - return ( - <RoomGroup - {...props} - interactionLevel={interactionLevel} - currentRoomInConstruction={currentRoomInConstruction} - room={room} - onClick={() => dispatch(goFromBuildingToRoom(roomId))} - /> - ) -} - -RoomContainer.propTypes = { - roomId: PropTypes.string, -} - -export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js deleted file mode 100644 index 0788b894..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import PropTypes from 'prop-types' -import { useDispatch, useSelector } from 'react-redux' -import { goFromRoomToRack } from '../../../redux/actions/interaction-level' -import TileGroup from './groups/TileGroup' - -function TileContainer({ tileId, ...props }) { - const interactionLevel = useSelector((state) => state.interactionLevel) - const dispatch = useDispatch() - const tile = useSelector((state) => state.topology.tiles[tileId]) - - if (!tile) { - return null - } - - const onClick = (tile) => { - if (tile.rack) { - dispatch(goFromRoomToRack(tile.id)) - } - } - return <TileGroup {...props} onClick={onClick} tile={tile} interactionLevel={interactionLevel} /> -} - -TileContainer.propTypes = { - tileId: PropTypes.string.isRequired, -} - -export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js deleted file mode 100644 index cc0d46b3..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/TopologyContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useSelector } from 'react-redux' -import TopologyGroup from './groups/TopologyGroup' - -function TopologyContainer() { - const topology = useSelector((state) => state.topology.root) - const interactionLevel = useSelector((state) => state.interactionLevel) - - return <TopologyGroup topology={topology} interactionLevel={interactionLevel} /> -} - -export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js deleted file mode 100644 index 106d8d3d..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import PropTypes from 'prop-types' -import { useSelector } from 'react-redux' -import WallGroup from './groups/WallGroup' - -function WallContainer({ roomId, ...props }) { - const tiles = useSelector((state) => { - return state.topology.rooms[roomId]?.tiles.map((tileId) => state.topology.tiles[tileId]) ?? [] - }) - return <WallGroup {...props} tiles={tiles} /> -} - -WallContainer.propTypes = { - roomId: PropTypes.string.isRequired, -} - -export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js deleted file mode 100644 index 931ded94..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.js +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import PropTypes from 'prop-types' -import { ChevronLeftIcon } from '@patternfly/react-icons' -import { collapseContainer } from './Collapse.module.css' -import { Button } from '@patternfly/react-core' - -function Collapse({ onClick }) { - return ( - <div className={collapseContainer}> - <Button variant="tertiary" onClick={onClick}> - <ChevronLeftIcon /> - </Button> - </div> - ) -} - -Collapse.propTypes = { - onClick: PropTypes.func, -} - -export default Collapse diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.css b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.css deleted file mode 100644 index 70fd465f..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Collapse.module.css +++ /dev/null @@ -1,55 +0,0 @@ -/*! - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -.collapseContainer { - position: absolute; - right: var(--pf-global--spacer--xs); - top: 0; - bottom: 10%; - margin: auto 0; - height: 50px; -} - -.collapseContainer > button:global(.pf-m-tertiary) { - height: 100%; - padding: 2px; - - margin-right: var(--pf-global--spacer--xs); - margin-top: var(--pf-global--spacer--xs); - background-color: var(--pf-global--BackgroundColor--100); - border: none; - border-radius: var(--pf-global--BorderRadius--sm); - box-shadow: var(--pf-global--BoxShadow--sm); -} - -.collapseContainer > button:global(.pf-m-tertiary):not(:global(.pf-m-disabled)) { - background-color: var(--pf-global--BackgroundColor--100); -} - -.collapseContainer > button:global(.pf-m-tertiary):after { - display: none; -} - -.collapseContainer > button:global(.pf-m-tertiary):hover { - border: none; - box-shadow: var(--pf-global--BoxShadow--md); -} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js deleted file mode 100644 index 3ec893fb..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.js +++ /dev/null @@ -1,18 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { TILE_SIZE_IN_METERS, TILE_SIZE_IN_PIXELS } from '../MapConstants' -import { scaleIndicator } from './ScaleIndicator.module.css' - -function ScaleIndicator({ scale }) { - return ( - <div className={scaleIndicator} style={{ width: TILE_SIZE_IN_PIXELS * scale }}> - {TILE_SIZE_IN_METERS}m - </div> - ) -} - -ScaleIndicator.propTypes = { - scale: PropTypes.number.isRequired, -} - -export default ScaleIndicator diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.css b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.css deleted file mode 100644 index f19e0ff2..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/ScaleIndicator.module.css +++ /dev/null @@ -1,10 +0,0 @@ -.scaleIndicator { - position: absolute; - right: 10px; - bottom: 10px; - z-index: 50; - - border: solid 2px #212529; - border-top: none; - border-left: none; -} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js deleted file mode 100644 index 00aaf3e1..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.js +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { control, toolBar } from './Toolbar.module.css' -import { Button } from '@patternfly/react-core' -import { SearchPlusIcon, SearchMinusIcon, CameraIcon } from '@patternfly/react-icons' - -function Toolbar({ onZoom, onExport }) { - return ( - <div className={toolBar}> - <Button variant="tertiary" title="Zoom in" onClick={() => onZoom(true)} className={control}> - <SearchPlusIcon /> - </Button> - <Button variant="tertiary" title="Zoom out" onClick={() => onZoom(false)} className={control}> - <SearchMinusIcon /> - </Button> - <Button - variant="tertiary" - title="Export Canvas to PNG Image" - onClick={() => onExport()} - className={control} - > - <CameraIcon /> - </Button> - </div> - ) -} - -Toolbar.propTypes = { - onZoom: PropTypes.func, - onExport: PropTypes.func, -} - -export default Toolbar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.css b/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.css deleted file mode 100644 index 007389da..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/controls/Toolbar.module.css +++ /dev/null @@ -1,27 +0,0 @@ -.toolBar { - position: absolute; - bottom: var(--pf-global--spacer--md); - left: var(--pf-global--spacer--xl); -} - -.control:global(.pf-m-tertiary) { - margin-right: var(--pf-global--spacer--xs); - margin-top: var(--pf-global--spacer--xs); - background-color: var(--pf-global--BackgroundColor--100); - border: none; - border-radius: var(--pf-global--BorderRadius--sm); - box-shadow: var(--pf-global--BoxShadow--sm); -} - -.control:global(.pf-m-tertiary):not(:global(.pf-m-disabled)) { - background-color: var(--pf-global--BackgroundColor--100); -} - -.control:global(.pf-m-tertiary):after { - display: none; -} - -.control:global(.pf-m-tertiary):hover { - border: none; - box-shadow: var(--pf-global--BoxShadow--md); -} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js deleted file mode 100644 index 93037b51..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/Backdrop.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { Rect } from 'react-konva' -import { BACKDROP_COLOR } from '../../../../util/colors' -import { MAP_SIZE_IN_PIXELS } from '../MapConstants' - -function Backdrop() { - return <Rect x={0} y={0} width={MAP_SIZE_IN_PIXELS} height={MAP_SIZE_IN_PIXELS} fill={BACKDROP_COLOR} /> -} - -export default Backdrop diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js deleted file mode 100644 index 08c687f6..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/GrayLayer.js +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Rect } from 'react-konva' -import { GRAYED_OUT_AREA_COLOR } from '../../../../util/colors' -import { MAP_SIZE_IN_PIXELS } from '../MapConstants' - -function GrayLayer({ onClick }) { - return ( - <Rect - x={0} - y={0} - width={MAP_SIZE_IN_PIXELS} - height={MAP_SIZE_IN_PIXELS} - fill={GRAYED_OUT_AREA_COLOR} - onClick={onClick} - /> - ) -} - -GrayLayer.propTypes = { - onClick: PropTypes.func, -} - -export default GrayLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js deleted file mode 100644 index 20c2c6d1..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/HoverTile.js +++ /dev/null @@ -1,30 +0,0 @@ -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' - -function HoverTile({ x, y, isValid, scale = 1, onClick }) { - return ( - <Rect - x={x} - y={y} - 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 = { - x: PropTypes.number.isRequired, - y: PropTypes.number.isRequired, - isValid: PropTypes.bool.isRequired, - scale: PropTypes.number, - onClick: PropTypes.func.isRequired, -} - -export default HoverTile diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js deleted file mode 100644 index fdae53f2..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/ImageComponent.js +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useEffect, useState } from 'react' -import { Image } from 'react-konva' - -const imageCaches = {} - -function ImageComponent({ src, x, y, width, height, opacity }) { - const [image, setImage] = useState(null) - - useEffect(() => { - if (imageCaches[src]) { - setImage(imageCaches[src]) - return - } - - const image = new window.Image() - image.src = src - image.onload = () => { - setImage(image) - imageCaches[src] = image - } - }, [src]) - - // eslint-disable-next-line jsx-a11y/alt-text - return <Image image={image} x={x} y={y} width={width} height={height} opacity={opacity} /> -} - -ImageComponent.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, -} - -export default ImageComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js deleted file mode 100644 index aa284944..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RackFillBar.js +++ /dev/null @@ -1,68 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -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, -} 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, -} from '../MapConstants' -import ImageComponent from './ImageComponent' - -function 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 - - 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, -} - -export default RackFillBar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js deleted file mode 100644 index e7329dc0..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/RoomTile.js +++ /dev/null @@ -1,24 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Rect } from 'react-konva' -import { Tile } from '../../../../shapes' -import { TILE_SIZE_IN_PIXELS } from '../MapConstants' - -function RoomTile({ tile, color }) { - return ( - <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: Tile, - color: PropTypes.string, -} - -export default RoomTile diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js deleted file mode 100644 index 3211f187..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TileObject.js +++ /dev/null @@ -1,27 +0,0 @@ -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' - -function TileObject({ positionX, positionY, color }) { - return ( - <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, -} - -export default TileObject diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js deleted file mode 100644 index 186c2b3a..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/TilePlusIcon.js +++ /dev/null @@ -1,44 +0,0 @@ -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' - -function TilePlusIcon({ x, y, scale = 1 }) { - const linePoints = [ - [ - x + 0.5 * TILE_SIZE_IN_PIXELS * scale, - y + TILE_PLUS_MARGIN_IN_PIXELS * scale, - x + 0.5 * TILE_SIZE_IN_PIXELS * scale, - y + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, - ], - [ - x + TILE_PLUS_MARGIN_IN_PIXELS * scale, - y + 0.5 * TILE_SIZE_IN_PIXELS * scale, - x + TILE_SIZE_IN_PIXELS * scale - TILE_PLUS_MARGIN_IN_PIXELS * scale, - y + 0.5 * TILE_SIZE_IN_PIXELS * scale, - ], - ] - return ( - <Group> - {linePoints.map((points, index) => ( - <Line - key={index} - points={points} - lineCap="round" - stroke={TILE_PLUS_COLOR} - strokeWidth={TILE_PLUS_WIDTH_IN_PIXELS * scale} - listening={false} - /> - ))} - </Group> - ) -} - -TilePlusIcon.propTypes = { - x: PropTypes.number, - y: PropTypes.number, - scale: PropTypes.number, -} - -export default TilePlusIcon diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js b/opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js deleted file mode 100644 index 4f18813e..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/elements/WallSegment.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { Line } from 'react-konva' -import { WallSegment as WallSegmentShape } from '../../../../shapes' -import { WALL_COLOR } from '../../../../util/colors' -import { TILE_SIZE_IN_PIXELS, WALL_WIDTH_IN_PIXELS } from '../MapConstants' - -function 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} /> -} - -WallSegment.propTypes = { - wallSegment: WallSegmentShape, -} - -export default WallSegment diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js deleted file mode 100644 index d66a18de..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/GridGroup.js +++ /dev/null @@ -1,36 +0,0 @@ -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' - -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, -]) -const VERTICAL_POINT_PAIRS = MAP_COORDINATE_ENTRIES.map((index) => [ - index * TILE_SIZE_IN_PIXELS, - 0, - index * TILE_SIZE_IN_PIXELS, - MAP_SIZE_IN_PIXELS, -]) - -function GridGroup() { - return ( - <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/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js deleted file mode 100644 index ed942661..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RackGroup.js +++ /dev/null @@ -1,25 +0,0 @@ -import React from 'react' -import { Group } from 'react-konva' -import { Tile } from '../../../../shapes' -import { RACK_BACKGROUND_COLOR } from '../../../../util/colors' -import TileObject from '../elements/TileObject' -import RackSpaceFillContainer from '../RackSpaceFillContainer' -import RackEnergyFillContainer from '../RackEnergyFillContainer' - -function RackGroup({ tile }) { - return ( - <Group> - <TileObject positionX={tile.positionX} positionY={tile.positionY} color={RACK_BACKGROUND_COLOR} /> - <Group> - <RackSpaceFillContainer rackId={tile.rack} positionX={tile.positionX} positionY={tile.positionY} /> - <RackEnergyFillContainer rackId={tile.rack} positionX={tile.positionX} positionY={tile.positionY} /> - </Group> - </Group> - ) -} - -RackGroup.propTypes = { - tile: Tile, -} - -export default RackGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js deleted file mode 100644 index 3f8b3089..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/RoomGroup.js +++ /dev/null @@ -1,52 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group } from 'react-konva' -import { InteractionLevel, Room } from '../../../../shapes' -import GrayContainer from '../GrayContainer' -import TileContainer from '../TileContainer' -import WallContainer from '../WallContainer' - -function RoomGroup({ room, interactionLevel, currentRoomInConstruction, onClick }) { - if (currentRoomInConstruction === room.id) { - return ( - <Group onClick={onClick}> - {room.tiles.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.tiles - .filter((tileId) => tileId !== interactionLevel.tileId) - .map((tileId) => <TileContainer key={tileId} tileId={tileId} />), - <GrayContainer key={-1} />, - room.tiles - .filter((tileId) => tileId === interactionLevel.tileId) - .map((tileId) => <TileContainer key={tileId} tileId={tileId} />), - ] - } else { - return room.tiles.map((tileId) => <TileContainer key={tileId} tileId={tileId} />) - } - })()} - <WallContainer roomId={room.id} /> - </Group> - ) -} - -RoomGroup.propTypes = { - room: Room, - interactionLevel: InteractionLevel, - currentRoomInConstruction: PropTypes.string, - onClick: PropTypes.func, -} - -export default RoomGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js deleted file mode 100644 index f2084017..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TileGroup.js +++ /dev/null @@ -1,36 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group } from 'react-konva' -import { Tile } from '../../../../shapes' -import { ROOM_DEFAULT_COLOR, ROOM_IN_CONSTRUCTION_COLOR } from '../../../../util/colors' -import RoomTile from '../elements/RoomTile' -import RackContainer from '../RackContainer' - -function TileGroup({ tile, newTile, onClick }) { - let tileObject - if (tile.rack) { - tileObject = <RackContainer tile={tile} /> - } else { - tileObject = null - } - - let color = ROOM_DEFAULT_COLOR - if (newTile) { - color = ROOM_IN_CONSTRUCTION_COLOR - } - - return ( - <Group onClick={() => onClick(tile)}> - <RoomTile tile={tile} color={color} /> - {tileObject} - </Group> - ) -} - -TileGroup.propTypes = { - tile: Tile, - newTile: PropTypes.bool, - onClick: PropTypes.func, -} - -export default TileGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js deleted file mode 100644 index 011dcf34..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/TopologyGroup.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react' -import { Group } from 'react-konva' -import { InteractionLevel, Topology } from '../../../../shapes' -import RoomContainer from '../RoomContainer' -import GrayContainer from '../GrayContainer' - -function TopologyGroup({ topology, interactionLevel }) { - if (!topology) { - return <Group /> - } - - if (interactionLevel.mode === 'BUILDING') { - return ( - <Group> - {topology.rooms.map((roomId) => ( - <RoomContainer key={roomId} roomId={roomId} /> - ))} - </Group> - ) - } - - return ( - <Group> - {topology.rooms - .filter((roomId) => roomId !== interactionLevel.roomId) - .map((roomId) => ( - <RoomContainer key={roomId} roomId={roomId} /> - ))} - {interactionLevel.mode === 'ROOM' ? <GrayContainer /> : null} - {topology.rooms - .filter((roomId) => roomId === interactionLevel.roomId) - .map((roomId) => ( - <RoomContainer key={roomId} roomId={roomId} /> - ))} - </Group> - ) -} - -TopologyGroup.propTypes = { - topology: Topology, - interactionLevel: InteractionLevel, -} - -export default TopologyGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js b/opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js deleted file mode 100644 index 6cbd1cd0..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/groups/WallGroup.js +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { Group } from 'react-konva' -import { Tile } from '../../../../shapes' -import { deriveWallLocations } from '../../../../util/tile-calculations' -import WallSegment from '../elements/WallSegment' - -function WallGroup({ tiles }) { - return ( - <Group> - {deriveWallLocations(tiles).map((wallSegment, index) => ( - <WallSegment key={index} wallSegment={wallSegment} /> - ))} - </Group> - ) -} - -WallGroup.propTypes = { - tiles: PropTypes.arrayOf(Tile).isRequired, -} - -export default WallGroup diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js deleted file mode 100644 index d7e0c56a..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js +++ /dev/null @@ -1,55 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useMemo, useState } from 'react' -import { Layer } from 'react-konva/lib/ReactKonva' -import HoverTile from '../elements/HoverTile' -import { TILE_SIZE_IN_PIXELS } from '../MapConstants' -import { useEffectRef } from '../../../../util/effect-ref' - -function HoverLayerComponent({ isEnabled, isValid, onClick, children }) { - const [[mouseWorldX, mouseWorldY], setPos] = useState([0, 0]) - - const layerRef = useEffectRef((layer) => { - if (!layer) { - return - } - - const stage = layer.getStage() - - stage.on('mousemove.hover', () => { - // Transform used to convert mouse coordinates to world coordinates - const transform = stage.getAbsoluteTransform().copy() - transform.invert() - - const { x, y } = transform.point(stage.getPointerPosition()) - setPos([x, y]) - }) - return () => stage.off('mousemove.hover') - }) - - const gridX = Math.floor(mouseWorldX / TILE_SIZE_IN_PIXELS) - const gridY = Math.floor(mouseWorldY / TILE_SIZE_IN_PIXELS) - const valid = useMemo(() => isEnabled && isValid(gridX, gridY), [isEnabled, isValid, gridX, gridY]) - - if (!isEnabled) { - return <Layer /> - } - - const x = gridX * TILE_SIZE_IN_PIXELS - const y = gridY * TILE_SIZE_IN_PIXELS - - return ( - <Layer opacity={0.2} ref={layerRef}> - <HoverTile x={x} y={y} isValid={valid} onClick={() => (valid ? onClick(gridX, gridY) : undefined)} /> - {children ? React.cloneElement(children, { x, y, scale: 1 }) : undefined} - </Layer> - ) -} - -HoverLayerComponent.propTypes = { - isEnabled: PropTypes.bool.isRequired, - isValid: PropTypes.func.isRequired, - onClick: PropTypes.func.isRequired, - children: PropTypes.node, -} - -export default HoverLayerComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js deleted file mode 100644 index c902532b..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/MapLayer.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { Group, Layer } from 'react-konva' -import Backdrop from '../elements/Backdrop' -import TopologyContainer from '../TopologyContainer' -import GridGroup from '../groups/GridGroup' - -function MapLayer() { - return ( - <Layer> - <Group> - <Backdrop /> - <TopologyContainer /> - <GridGroup /> - </Group> - </Layer> - ) -} - -export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js deleted file mode 100644 index 5e741a3b..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addRackToTile } from '../../../../redux/actions/topology/room' -import { findTileWithPosition } from '../../../../util/tile-calculations' -import HoverLayerComponent from './HoverLayerComponent' -import TilePlusIcon from '../elements/TilePlusIcon' - -export default function ObjectHoverLayer() { - const isEnabled = useSelector((state) => state.construction.inRackConstructionMode) - const isValid = useSelector((state) => (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } - - const currentRoom = state.topology.rooms[state.interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => state.topology.tiles[tileId]) - const tile = findTileWithPosition(tiles, x, y) - - return !(tile === null || tile.rack) - }) - - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(addRackToTile(x, y)) - return ( - <HoverLayerComponent onClick={onClick} isEnabled={isEnabled} isValid={isValid}> - <TilePlusIcon /> - </HoverLayerComponent> - ) -} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js deleted file mode 100644 index b9cfcaf4..00000000 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' -import { - deriveValidNextTilePositions, - findPositionInPositions, - findPositionInRooms, -} from '../../../../util/tile-calculations' -import HoverLayerComponent from './HoverLayerComponent' - -export default function RoomHoverLayer() { - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) - const isEnabled = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - const isValid = useSelector((state) => (x, y) => { - const newRoom = { ...state.topology.rooms[state.construction.currentRoomInConstruction] } - const oldRooms = Object.keys(state.topology.rooms) - .map((id) => ({ ...state.topology.rooms[id] })) - .filter( - (room) => - state.topology.root.rooms.indexOf(room.id) !== -1 && - room.id !== state.construction.currentRoomInConstruction - ) - - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tiles.map((tileId) => state.topology.tiles[tileId]) - }) - if (newRoom.tiles.length === 0) { - return findPositionInRooms(oldRooms, x, y) === -1 - } - - const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) - return findPositionInPositions(validNextPositions, x, y) !== -1 - }) - - return <HoverLayerComponent onClick={onClick} isEnabled={isEnabled} isValid={isValid} /> -} |
