From 419297128ce2ab2c8085c81fafdb843c1135661d Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 14 Sep 2022 13:49:58 +0200 Subject: fix(web/ui): Fix deletion of topology This change fixes an issue with the OpenDC web interface where the user cannot remove an existing topology from the topology table due to a programming mistake. --- opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'opendc-web/opendc-web-ui/src/components/topologies/map') 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 index 21be3c79..ef5af263 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js @@ -28,9 +28,9 @@ 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]) - const dispatch = useDispatch() const onClick = (tile) => { if (tile.rack) { dispatch(goFromRoomToRack(tile.id)) -- cgit v1.2.3 From 0b3d0ba3193ebcdeadc6a4b0a192eeb06e9add29 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 20 Sep 2022 11:04:34 +0200 Subject: fix(web/ui): Do not fail on stale Redux state This change fixes an issue where switching between different topologies would fail due to stale Redux state. We have updated the components to take into account that ids may not exist in the Redux store. --- .../topologies/map/RackEnergyFillContainer.js | 34 ++++++++++++---------- .../topologies/map/RackSpaceFillContainer.js | 11 +++++-- .../src/components/topologies/map/RoomContainer.js | 17 ++++++----- .../src/components/topologies/map/TileContainer.js | 4 +++ .../src/components/topologies/map/WallContainer.js | 2 +- .../components/topologies/map/groups/RackGroup.js | 4 +-- 6 files changed, 42 insertions(+), 30 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components/topologies/map') 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 index be1f3e45..a1ca7426 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackEnergyFillContainer.js @@ -3,24 +3,26 @@ import PropTypes from 'prop-types' import { useSelector } from 'react-redux' import RackFillBar from './elements/RackFillBar' -function RackSpaceFillContainer({ tileId, ...props }) { +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 - const rack = state.topology.racks[state.topology.tiles[tileId].rack] - const machineIds = rack.machines - machineIds.forEach((machineId) => { - if (machineId !== null) { - const machine = state.topology.machines[machineId] - machine.cpus.forEach((id) => (energyConsumptionTotal += state.topology.cpus[id].energyConsumptionW)) - machine.gpus.forEach((id) => (energyConsumptionTotal += state.topology.gpus[id].energyConsumptionW)) - machine.memories.forEach( - (id) => (energyConsumptionTotal += state.topology.memories[id].energyConsumptionW) - ) - machine.storages.forEach( - (id) => (energyConsumptionTotal += state.topology.storages[id].energyConsumptionW) - ) + + 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) }) @@ -28,7 +30,7 @@ function RackSpaceFillContainer({ tileId, ...props }) { } RackSpaceFillContainer.propTypes = { - tileId: PropTypes.string.isRequired, + 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 index 0c15d54b..2039a9d3 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RackSpaceFillContainer.js @@ -25,13 +25,18 @@ import PropTypes from 'prop-types' import { useSelector } from 'react-redux' import RackFillBar from './elements/RackFillBar' -function RackSpaceFillContainer({ tileId, ...props }) { - const rack = useSelector((state) => state.topology.racks[state.topology.tiles[tileId].rack]) +function RackSpaceFillContainer({ rackId, ...props }) { + const rack = useSelector((state) => state.topology.racks[rackId]) + + if (!rack) { + return null + } + return } RackSpaceFillContainer.propTypes = { - tileId: PropTypes.string.isRequired, + 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 index 65189891..191318ee 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js @@ -27,15 +27,16 @@ import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' import RoomGroup from './groups/RoomGroup' function RoomContainer({ roomId, ...props }) { - const state = useSelector((state) => { - return { - interactionLevel: state.interactionLevel, - currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.topology.rooms[roomId], - } - }) + const interactionLevel = useSelector((state) => state.interactionLevel) + const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) + const room = useSelector((state) => state.topology.rooms[roomId]) const dispatch = useDispatch() - return dispatch(goFromBuildingToRoom(roomId))} /> + + if (!room) { + return null + } + + return dispatch(goFromBuildingToRoom(roomId))} /> } RoomContainer.propTypes = { 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 index ef5af263..0788b894 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/TileContainer.js @@ -31,6 +31,10 @@ function TileContainer({ tileId, ...props }) { 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)) 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 index 143f70c2..106d8d3d 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/WallContainer.js @@ -27,7 +27,7 @@ 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 state.topology.rooms[roomId]?.tiles.map((tileId) => state.topology.tiles[tileId]) ?? [] }) return } 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 index dad2d62d..ed942661 100644 --- 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 @@ -11,8 +11,8 @@ function RackGroup({ tile }) { - - + + ) -- cgit v1.2.3 From 78255fc6a1ef18759670682c1d90cee685315493 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Tue, 20 Sep 2022 12:17:34 +0200 Subject: fix(web/ui): Fix overflow of topology sidebar This change fixes an issue with the web interface where the sidebar would overflow due to the large number of rack slots that are displayed in the sidebar. --- .../opendc-web-ui/src/components/topologies/map/MapStage.js | 2 +- .../src/components/topologies/map/MapStage.module.scss | 2 -- .../src/components/topologies/map/RoomContainer.js | 10 +++++++++- 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components/topologies/map') 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 index 7b96f548..8bf529b2 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js @@ -15,7 +15,7 @@ import Toolbar from './controls/Toolbar' function MapStage({ hotkeysRef }) { const reduxContext = useContext(ReactReduxContext) const stageRef = useRef(null) - const { width = 100, height = 100 } = useResizeObserver({ ref: stageRef.current?.attrs?.container }) + const { width = 500, height = 500 } = useResizeObserver({ ref: stageRef.current?.attrs?.container }) const [[x, y], setPos] = useState([0, 0]) const [scale, setScale] = useState(1) diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss index d879b4c8..47c3dde2 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.module.scss @@ -24,8 +24,6 @@ background-color: var(--pf-global--Color--light-200); position: relative; display: flex; - justify-content: center; - align-items: center; width: 100%; height: 100%; } 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 index 191318ee..76785bea 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/RoomContainer.js @@ -36,7 +36,15 @@ function RoomContainer({ roomId, ...props }) { return null } - return dispatch(goFromBuildingToRoom(roomId))} /> + return ( + dispatch(goFromBuildingToRoom(roomId))} + /> + ) } RoomContainer.propTypes = { -- cgit v1.2.3