From 6d5a2eebb609da67239ea37d12d6b2d3bbfef76e Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 28 Oct 2020 16:41:53 +0100 Subject: ui: Do not clutter component tree with Redux connects This change refactors the frontend to use hooks for obtaining state within the Redux store as opposed to using Higher-Order Components (HOCs). This eliminates a lot of clutter in the components. --- .../src/containers/app/map/GrayContainer.js | 13 ++-- .../src/containers/app/map/MapStage.js | 33 +++++----- .../src/containers/app/map/RackContainer.js | 12 ++-- .../containers/app/map/RackEnergyFillContainer.js | 44 +++++++------ .../containers/app/map/RackSpaceFillContainer.js | 20 +++--- .../src/containers/app/map/RoomContainer.js | 27 ++++---- .../src/containers/app/map/TileContainer.js | 29 ++++----- .../src/containers/app/map/TopologyContainer.js | 19 +++--- .../src/containers/app/map/WallContainer.js | 14 ++-- .../app/map/controls/ScaleIndicatorContainer.js | 12 ++-- .../app/map/controls/ZoomControlContainer.js | 19 ++---- .../src/containers/app/map/layers/MapLayer.js | 13 ++-- .../containers/app/map/layers/ObjectHoverLayer.js | 45 +++++++------ .../containers/app/map/layers/RoomHoverLayer.js | 63 +++++++++--------- .../app/results/PortfolioResultsContainer.js | 43 +++++++------ .../app/sidebars/project/PortfolioListContainer.js | 42 ++++++------ .../sidebars/project/ProjectSidebarContainer.js | 9 +-- .../app/sidebars/project/ScenarioListContainer.js | 68 +++++++++++--------- .../app/sidebars/project/TopologyListContainer.js | 74 ++++++++++++---------- .../sidebars/topology/TopologySidebarContainer.js | 12 ++-- .../building/NewRoomConstructionContainer.js | 23 ++++--- .../topology/machine/BackToRackContainer.js | 12 ++-- .../topology/machine/DeleteMachineContainer.js | 12 ++-- .../topology/machine/MachineNameContainer.js | 12 ++-- .../topology/machine/MachineSidebarContainer.js | 16 ++--- .../sidebars/topology/machine/UnitAddContainer.js | 20 +++--- .../app/sidebars/topology/machine/UnitContainer.js | 20 ++---- .../sidebars/topology/machine/UnitListContainer.js | 16 ++--- .../sidebars/topology/rack/AddPrefabContainer.js | 12 ++-- .../sidebars/topology/rack/BackToRoomContainer.js | 12 ++-- .../sidebars/topology/rack/DeleteRackContainer.js | 12 ++-- .../sidebars/topology/rack/EmptySlotContainer.js | 13 ++-- .../app/sidebars/topology/rack/MachineContainer.js | 21 +++--- .../sidebars/topology/rack/MachineListContainer.js | 14 ++-- .../sidebars/topology/rack/RackNameContainer.js | 21 +++--- .../sidebars/topology/rack/RackSidebarContainer.js | 12 ++-- .../topology/room/BackToBuildingContainer.js | 13 ++-- .../sidebars/topology/room/DeleteRoomContainer.js | 13 ++-- .../sidebars/topology/room/EditRoomContainer.js | 32 ++++++---- .../topology/room/RackConstructionContainer.js | 31 +++++---- .../sidebars/topology/room/RoomNameContainer.js | 20 ++---- .../sidebars/topology/room/RoomSidebarContainer.js | 12 ++-- 42 files changed, 472 insertions(+), 508 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js index 9e4a6969..651b3459 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../actions/interaction-level' import GrayLayer from '../../../components/app/map/elements/GrayLayer' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const GrayContainer = () => { + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + return } -const GrayContainer = connect(undefined, mapDispatchToProps)(GrayLayer) - export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js index 23c920b6..61d123e8 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -1,22 +1,23 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../actions/map' import MapStageComponent from '../../../components/app/map/MapStageComponent' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapDimensions: state.map.dimensions, - } +const MapStage = () => { + const { position, dimensions } = useSelector((state) => state.map) + const dispatch = useDispatch() + const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) + const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) + const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height)) + return ( + + ) } -const mapDispatchToProps = (dispatch) => { - return { - zoomInOnPosition: (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)), - setMapPositionWithBoundsCheck: (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)), - setMapDimensions: (width, height) => dispatch(setMapDimensions(width, height)), - } -} - -const MapStage = connect(mapStateToProps, mapDispatchToProps)(MapStageComponent) - export default MapStage diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js index 40077608..e5af5117 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackGroup from '../../../components/app/map/groups/RackGroup' -const mapStateToProps = (state) => { - return { - interactionLevel: state.interactionLevel, - } +const RackContainer = ({ tile }) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + return } -const RackContainer = connect(mapStateToProps)(RackGroup) - export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js index 53746271..00d3152f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js @@ -1,26 +1,32 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackFillBar from '../../../components/app/map/elements/RackFillBar' -const mapStateToProps = (state, ownProps) => { - let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[ownProps.tileId].rackId] - const machineIds = rack.machineIds - machineIds.forEach((machineId) => { - if (machineId !== null) { - const machine = state.objects.machine[machineId] - machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) - machine.memoryIds.forEach((id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW)) - machine.storageIds.forEach((id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW)) +const RackSpaceFillContainer = (props) => { + const state = useSelector((state) => { + let energyConsumptionTotal = 0 + const rack = state.objects.rack[state.objects.tile[props.tileId].rackId] + const machineIds = rack.machineIds + machineIds.forEach((machineId) => { + if (machineId !== null) { + const machine = state.objects.machine[machineId] + machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) + machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) + machine.memoryIds.forEach( + (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) + ) + machine.storageIds.forEach( + (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) + ) + } + }) + + return { + type: 'energy', + fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), } }) - - return { - type: 'energy', - fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), - } + return } -const RackSpaceFillContainer = connect(mapStateToProps)(RackFillBar) - export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js index 0509a5a5..dc5119fd 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js @@ -1,14 +1,16 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackFillBar from '../../../components/app/map/elements/RackFillBar' -const mapStateToProps = (state, ownProps) => { - const machineIds = state.objects.rack[state.objects.tile[ownProps.tileId].rackId].machineIds - return { - type: 'space', - fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, - } +const RackSpaceFillContainer = (props) => { + const state = useSelector((state) => { + const machineIds = state.objects.rack[state.objects.tile[props.tileId].rackId].machineIds + return { + type: 'space', + fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, + } + }) + return } -const RackSpaceFillContainer = connect(mapStateToProps)(RackFillBar) - export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js index 91bf4e5d..877233fc 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js @@ -1,21 +1,18 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { goFromBuildingToRoom } from '../../../actions/interaction-level' import RoomGroup from '../../../components/app/map/groups/RoomGroup' -const mapStateToProps = (state, ownProps) => { - return { - interactionLevel: state.interactionLevel, - currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.objects.room[ownProps.roomId], - } +const RoomContainer = (props) => { + const state = useSelector((state) => { + return { + interactionLevel: state.interactionLevel, + currentRoomInConstruction: state.construction.currentRoomInConstruction, + room: state.objects.room[props.roomId], + } + }) + const dispatch = useDispatch() + return dispatch(goFromBuildingToRoom(props.roomId))} /> } -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onClick: () => dispatch(goFromBuildingToRoom(ownProps.roomId)), - } -} - -const RoomContainer = connect(mapStateToProps, mapDispatchToProps)(RoomGroup) - export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js index 04d6c8d6..ad7301a7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js @@ -1,26 +1,19 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { goFromRoomToRack } from '../../../actions/interaction-level' import TileGroup from '../../../components/app/map/groups/TileGroup' -const mapStateToProps = (state, ownProps) => { - const tile = state.objects.tile[ownProps.tileId] +const TileContainer = (props) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + const tile = useSelector((state) => state.objects.tile[props.tileId]) - return { - interactionLevel: state.interactionLevel, - tile, + const dispatch = useDispatch() + const onClick = (tile) => { + if (tile.rackId) { + dispatch(goFromRoomToRack(tile._id)) + } } + return } -const mapDispatchToProps = (dispatch) => { - return { - onClick: (tile) => { - if (tile.rackId) { - dispatch(goFromRoomToRack(tile._id)) - } - }, - } -} - -const TileContainer = connect(mapStateToProps, mapDispatchToProps)(TileGroup) - export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js index de43a151..612ca41c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js @@ -1,17 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -const mapStateToProps = (state) => { - if (state.currentTopologyId === '-1') { - return {} - } +const TopologyContainer = () => { + const topology = useSelector( + (state) => state.currentTopologyId !== '-1' && state.objects.topology[state.currentTopologyId] + ) + const interactionLevel = useSelector((state) => state.interactionLevel) - return { - topology: state.objects.topology[state.currentTopologyId], - interactionLevel: state.interactionLevel, - } + return } -const TopologyContainer = connect(mapStateToProps)(TopologyGroup) - export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js index 67f8a242..2a469860 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import WallGroup from '../../../components/app/map/groups/WallGroup' -const mapStateToProps = (state, ownProps) => { - return { - tiles: state.objects.room[ownProps.roomId].tileIds.map((tileId) => state.objects.tile[tileId]), - } +const WallContainer = (props) => { + const tiles = useSelector((state) => + state.objects.room[props.roomId].tileIds.map((tileId) => state.objects.tile[tileId]) + ) + return } -const WallContainer = connect(mapStateToProps)(WallGroup) - export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js index fa3b9d22..e9d58b9f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' -const mapStateToProps = (state) => { - return { - scale: state.map.scale, - } +const ScaleIndicatorContainer = (props) => { + const scale = useSelector((state) => state.map.scale) + return } -const ScaleIndicatorContainer = connect(mapStateToProps)(ScaleIndicatorComponent) - export default ScaleIndicatorContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js index ddc68cc7..a18dfd5b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js @@ -1,19 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { zoomInOnCenter } from '../../../../actions/map' import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent' -const mapStateToProps = (state) => { - return { - mapScale: state.map.scale, - } +const ZoomControlContainer = () => { + const dispatch = useDispatch() + const scale = useSelector((state) => state.map.scale) + return dispatch(zoomInOnCenter(zoomIn))} /> } -const mapDispatchToProps = (dispatch) => { - return { - zoomInOnCenter: (zoomIn) => dispatch(zoomInOnCenter(zoomIn)), - } -} - -const ZoomControlContainer = connect(mapStateToProps, mapDispatchToProps)(ZoomControlComponent) - export default ZoomControlContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js index 8596cb9c..5f701b4b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js @@ -1,13 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - } +const MapLayer = (props) => { + const { position, scale } = useSelector((state) => state.map) + return } -const MapLayer = connect(mapStateToProps)(MapLayerComponent) - export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js index a4927862..cefdf35c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js @@ -1,33 +1,32 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { addRackToTile } from '../../../../actions/topology/room' import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' import { findTileWithPosition } from '../../../../util/tile-calculations' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.inRackConstructionMode, - isValid: (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } +const ObjectHoverLayer = (props) => { + const state = useSelector((state) => { + return { + mapPosition: state.map.position, + mapScale: state.map.scale, + isEnabled: () => state.construction.inRackConstructionMode, + isValid: (x, y) => { + if (state.interactionLevel.mode !== 'ROOM') { + return false + } - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId]) - const tile = findTileWithPosition(tiles, x, y) + const currentRoom = state.objects.room[state.interactionLevel.roomId] + const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId]) + const tile = findTileWithPosition(tiles, x, y) - return !(tile === null || tile.rackId) - }, - } -} + return !(tile === null || tile.rackId) + }, + } + }) -const mapDispatchToProps = (dispatch) => { - return { - onClick: (x, y) => dispatch(addRackToTile(x, y)), - } + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(addRackToTile(x, y)) + return } -const ObjectHoverLayer = connect(mapStateToProps, mapDispatchToProps)(ObjectHoverLayerComponent) - export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js index 66404f9e..2717d890 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js @@ -1,4 +1,5 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { toggleTileAtLocation } from '../../../../actions/topology/building' import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' import { @@ -7,40 +8,38 @@ import { findPositionInRooms, } from '../../../../util/tile-calculations' -const mapStateToProps = (state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.currentRoomInConstruction !== '-1', - isValid: (x, y) => { - const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) - const oldRooms = Object.keys(state.objects.room) - .map((id) => Object.assign({}, state.objects.room[id])) - .filter( - (room) => - state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 && - room._id !== state.construction.currentRoomInConstruction - ) +const RoomHoverLayer = (props) => { + const dispatch = useDispatch() + const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId]) - }) - if (newRoom.tileIds.length === 0) { - return findPositionInRooms(oldRooms, x, y) === -1 - } + const state = useSelector((state) => { + return { + mapPosition: state.map.position, + mapScale: state.map.scale, + isEnabled: () => state.construction.currentRoomInConstruction !== '-1', + isValid: (x, y) => { + const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) + const oldRooms = Object.keys(state.objects.room) + .map((id) => Object.assign({}, state.objects.room[id])) + .filter( + (room) => + state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 && + room._id !== state.construction.currentRoomInConstruction + ) - const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) - return findPositionInPositions(validNextPositions, x, y) !== -1 - }, - } -} + ;[...oldRooms, newRoom].forEach((room) => { + room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId]) + }) + if (newRoom.tileIds.length === 0) { + return findPositionInRooms(oldRooms, x, y) === -1 + } -const mapDispatchToProps = (dispatch) => { - return { - onClick: (x, y) => dispatch(toggleTileAtLocation(x, y)), - } + const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) + return findPositionInPositions(validNextPositions, x, y) !== -1 + }, + } + }) + return } -const RoomHoverLayer = connect(mapStateToProps, mapDispatchToProps)(RoomHoverLayerComponent) - export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js index 4b430e54..e60abe18 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js @@ -1,28 +1,31 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' -const mapStateToProps = (state) => { - if ( - state.currentPortfolioId === '-1' || - !state.objects.portfolio[state.currentPortfolioId] || - state.objects.portfolio[state.currentPortfolioId].scenarioIds - .map((scenarioId) => state.objects.scenario[scenarioId]) - .some((s) => s === undefined) - ) { +const PortfolioResultsContainer = (props) => { + const { scenarios, portfolio } = useSelector((state) => { + if ( + state.currentPortfolioId === '-1' || + !state.objects.portfolio[state.currentPortfolioId] || + state.objects.portfolio[state.currentPortfolioId].scenarioIds + .map((scenarioId) => state.objects.scenario[scenarioId]) + .some((s) => s === undefined) + ) { + return { + portfolio: undefined, + scenarios: [], + } + } + return { - portfolio: undefined, - scenarios: [], + portfolio: state.objects.portfolio[state.currentPortfolioId], + scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map( + (scenarioId) => state.objects.scenario[scenarioId] + ), } - } + }) - return { - portfolio: state.objects.portfolio[state.currentPortfolioId], - scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map( - (scenarioId) => state.objects.scenario[scenarioId] - ), - } + return } -const PortfolioResultsContainer = connect(mapStateToProps)(PortfolioResultsComponent) - export default PortfolioResultsContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index b32c8b1d..86f465b6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -1,28 +1,31 @@ -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import { useHistory } from 'react-router-dom' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' import { deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios' import { openNewPortfolioModal } from '../../../../actions/modals/portfolios' import { getState } from '../../../../util/state-utils' import { setCurrentTopology } from '../../../../actions/topology/building' -const mapStateToProps = (state) => { - let portfolios = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t]) - : [] - if (portfolios.filter((t) => !t).length > 0) { - portfolios = [] - } +const PortfolioListContainer = (props) => { + const state = useSelector((state) => { + let portfolios = state.objects.project[state.currentProjectId] + ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t]) + : [] + if (portfolios.filter((t) => !t).length > 0) { + portfolios = [] + } - return { - currentProjectId: state.currentProjectId, - currentPortfolioId: state.currentPortfolioId, - portfolios, - } -} + return { + currentProjectId: state.currentProjectId, + currentPortfolioId: state.currentPortfolioId, + portfolios, + } + }) -const mapDispatchToProps = (dispatch, ownProps) => { - return { + const dispatch = useDispatch() + const history = useHistory() + const actions = { onNewPortfolio: () => { dispatch(openNewPortfolioModal()) }, @@ -34,12 +37,11 @@ const mapDispatchToProps = (dispatch, ownProps) => { const state = await getState(dispatch) dispatch(deletePortfolio(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - ownProps.history.push(`/projects/${state.currentProjectId}`) + history.push(`/projects/${state.currentProjectId}`) } }, } + return } -const PortfolioListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(PortfolioListComponent)) - export default PortfolioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js index 49001099..35e6c52b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js @@ -1,10 +1,11 @@ import React from 'react' -import { withRouter } from 'react-router-dom' +import { useLocation } from 'react-router-dom' import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' import { isCollapsible } from '../../../../util/sidebar-space' -const ProjectSidebarContainer = withRouter(({ location, ...props }) => ( - -)) +const ProjectSidebarContainer = (props) => { + const location = useLocation() + return +} export default ProjectSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 415e2792..18d0735e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -1,41 +1,49 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' import { openNewScenarioModal } from '../../../../actions/modals/scenarios' import { deleteScenario, setCurrentScenario } from '../../../../actions/scenarios' import { setCurrentPortfolio } from '../../../../actions/portfolios' -const mapStateToProps = (state, ownProps) => { - let scenarios = state.objects.portfolio[ownProps.portfolioId] - ? state.objects.portfolio[ownProps.portfolioId].scenarioIds.map((t) => state.objects.scenario[t]) - : [] - if (scenarios.filter((t) => !t).length > 0) { - scenarios = [] - } +const ScenarioListContainer = ({ portfolioId, children }) => { + const currentProjectId = useSelector((state) => state.currentProjectId) + const currentScenarioId = useSelector((state) => state.currentScenarioId) + const scenarios = useSelector((state) => { + let scenarios = state.objects.portfolio[portfolioId] + ? state.objects.portfolio[portfolioId].scenarioIds.map((t) => state.objects.scenario[t]) + : [] + if (scenarios.filter((t) => !t).length > 0) { + scenarios = [] + } - return { - currentProjectId: state.currentProjectId, - currentScenarioId: state.currentScenarioId, - scenarios, - } -} + return scenarios + }) -const mapDispatchToProps = (dispatch) => { - return { - onNewScenario: (currentPortfolioId) => { - dispatch(setCurrentPortfolio(currentPortfolioId)) - dispatch(openNewScenarioModal()) - }, - onChooseScenario: (portfolioId, scenarioId) => { - dispatch(setCurrentScenario(portfolioId, scenarioId)) - }, - onDeleteScenario: (id) => { - if (id) { - dispatch(deleteScenario(id)) - } - }, + const dispatch = useDispatch() + const onNewScenario = (currentPortfolioId) => { + dispatch(setCurrentPortfolio(currentPortfolioId)) + dispatch(openNewScenarioModal()) + } + const onChooseScenario = (portfolioId, scenarioId) => { + dispatch(setCurrentScenario(portfolioId, scenarioId)) + } + const onDeleteScenario = (id) => { + if (id) { + dispatch(deleteScenario(id)) + } } -} -const ScenarioListContainer = connect(mapStateToProps, mapDispatchToProps)(ScenarioListComponent) + return ( + + ) +} export default ScenarioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index e1de18f9..954284a6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -1,46 +1,54 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' import { setCurrentTopology } from '../../../../actions/topology/building' import { openNewTopologyModal } from '../../../../actions/modals/topology' -import { withRouter } from 'react-router-dom' +import { useHistory } from 'react-router-dom' import { getState } from '../../../../util/state-utils' import { deleteTopology } from '../../../../actions/topologies' -const mapStateToProps = (state) => { - let topologies = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) - : [] - if (topologies.filter((t) => !t).length > 0) { - topologies = [] - } +const TopologyListContainer = () => { + const dispatch = useDispatch() + const history = useHistory() - return { - currentTopologyId: state.currentTopologyId, - topologies, - } -} + const topologies = useSelector((state) => { + let topologies = state.objects.project[state.currentProjectId] + ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) + : [] + if (topologies.filter((t) => !t).length > 0) { + topologies = [] + } + + return topologies + }) + const currentTopologyId = useSelector((state) => state.currentTopologyId) -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onChooseTopology: async (id) => { - dispatch(setCurrentTopology(id)) + const onChooseTopology = async (id) => { + dispatch(setCurrentTopology(id)) + const state = await getState(dispatch) + history.push(`/projects/${state.currentProjectId}`) + } + const onNewTopology = () => { + dispatch(openNewTopologyModal()) + } + const onDeleteTopology = async (id) => { + if (id) { const state = await getState(dispatch) - ownProps.history.push(`/projects/${state.currentProjectId}`) - }, - onNewTopology: () => { - dispatch(openNewTopologyModal()) - }, - onDeleteTopology: async (id) => { - if (id) { - const state = await getState(dispatch) - dispatch(deleteTopology(id)) - dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - ownProps.history.push(`/projects/${state.currentProjectId}`) - } - }, + dispatch(deleteTopology(id)) + dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) + history.push(`/projects/${state.currentProjectId}`) + } } -} -const TopologyListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(TopologyListComponent)) + return ( + + ) +} export default TopologyListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js index fe7c02fd..42c81c65 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import TopologySidebarComponent from '../../../../components/app/sidebars/topology/TopologySidebarComponent' -const mapStateToProps = (state) => { - return { - interactionLevel: state.interactionLevel, - } +const TopologySidebarContainer = (props) => { + const interactionLevel = useSelector((state) => state.interactionLevel) + return } -const TopologySidebarContainer = connect(mapStateToProps)(TopologySidebarComponent) - export default TopologySidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js index ea9e9e60..ea36539c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js @@ -1,4 +1,5 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { cancelNewRoomConstruction, finishNewRoomConstruction, @@ -6,20 +7,22 @@ import { } from '../../../../../actions/topology/building' import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent' -const mapStateToProps = (state) => { - return { - currentRoomInConstruction: state.construction.currentRoomInConstruction, - } -} +const NewRoomConstructionButton = (props) => { + const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) -const mapDispatchToProps = (dispatch) => { - return { + const dispatch = useDispatch() + const actions = { onStart: () => dispatch(startNewRoomConstruction()), onFinish: () => dispatch(finishNewRoomConstruction()), onCancel: () => dispatch(cancelNewRoomConstruction()), } + return ( + + ) } -const NewRoomConstructionButton = connect(mapStateToProps, mapDispatchToProps)(StartNewRoomConstructionComponent) - export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js index 24287ab0..46862472 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' import BackToRackComponent from '../../../../../components/app/sidebars/topology/machine/BackToRackComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const BackToRackContainer = (props) => { + const dispatch = useDispatch() + return dispatch(goDownOneInteractionLevel())} /> } -const BackToRackContainer = connect(undefined, mapDispatchToProps)(BackToRackComponent) - export default BackToRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js index 65e683e6..1510a436 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openDeleteMachineModal } from '../../../../../actions/modals/topology' import DeleteMachineComponent from '../../../../../components/app/sidebars/topology/machine/DeleteMachineComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openDeleteMachineModal()), - } +const DeleteMachineContainer = (props) => { + const dispatch = useDispatch() + return dispatch(openDeleteMachineModal())} /> } -const DeleteMachineContainer = connect(undefined, mapDispatchToProps)(DeleteMachineComponent) - export default DeleteMachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js index 1cf35b05..6f4285b2 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MachineNameComponent from '../../../../../components/app/sidebars/topology/machine/MachineNameComponent' -const mapStateToProps = (state) => { - return { - position: state.interactionLevel.position, - } +const MachineNameContainer = (props) => { + const position = useSelector((state) => state.interactionLevel.position) + return } -const MachineNameContainer = connect(mapStateToProps)(MachineNameComponent) - export default MachineNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js index b04e3118..cb7ec8f9 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js @@ -1,15 +1,15 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MachineSidebarComponent from '../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent' -const mapStateToProps = (state) => { - return { - machineId: +const MachineSidebarContainer = (props) => { + const machineId = useSelector( + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ state.interactionLevel.position - 1 - ], - } + ] + ) + return } -const MachineSidebarContainer = connect(mapStateToProps)(MachineSidebarComponent) - export default MachineSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js index 29e48016..3795cdff 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js @@ -1,19 +1,15 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { addUnit } from '../../../../../actions/topology/machine' import UnitAddComponent from '../../../../../components/app/sidebars/topology/machine/UnitAddComponent' -const mapStateToProps = (state, ownProps) => { - return { - units: Object.values(state.objects[ownProps.unitType]), - } -} +const UnitAddContainer = (props) => { + const units = useSelector((state) => Object.values(state.objects[props.unitType])) + const dispatch = useDispatch() -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onAdd: (id) => dispatch(addUnit(ownProps.unitType, id)), - } -} + const onAdd = (id) => dispatch(addUnit(props.unitType, id)) -const UnitAddContainer = connect(mapStateToProps, mapDispatchToProps)(UnitAddComponent) + return +} export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js index f334f9f2..3d24859e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js @@ -1,20 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { deleteUnit } from '../../../../../actions/topology/machine' import UnitComponent from '../../../../../components/app/sidebars/topology/machine/UnitComponent' -const mapStateToProps = (state, ownProps) => { - return { - unit: state.objects[ownProps.unitType][ownProps.unitId], - index: ownProps.unitId, - } -} +const UnitContainer = ({ unitId, unitType }) => { + const dispatch = useDispatch() + const unit = useSelector((state) => state.objects[unitType][unitId]) + const onDelete = () => dispatch(deleteUnit(unitType, unitId)) -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onDelete: () => dispatch(deleteUnit(ownProps.unitType, ownProps.index)), - } + return } -const UnitContainer = connect(mapStateToProps, mapDispatchToProps)(UnitComponent) - export default UnitContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js index f382ff74..c5c9444d 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js @@ -1,17 +1,17 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent' -const mapStateToProps = (state, ownProps) => { - return { - unitIds: +const UnitListContainer = (props) => { + const unitIds = useSelector( + (state) => state.objects.machine[ state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ state.interactionLevel.position - 1 ] - ][ownProps.unitType + 'Ids'], - } + ][props.unitType + 'Ids'] + ) + return } -const UnitListContainer = connect(mapStateToProps)(UnitListComponent) - export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js index c941e745..3708e33e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { addPrefab } from '../../../../../actions/prefabs' import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(addPrefab('name')), - } +const AddPrefabContainer = (props) => { + const dispatch = useDispatch() + return dispatch(addPrefab('name'))} /> } -const AddPrefabContainer = connect(undefined, mapDispatchToProps)(AddPrefabComponent) - export default AddPrefabContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js index 58c3b082..93bb749f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' import BackToRoomComponent from '../../../../../components/app/sidebars/topology/rack/BackToRoomComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const BackToRoomContainer = (props) => { + const dispatch = useDispatch() + return dispatch(goDownOneInteractionLevel())} /> } -const BackToRoomContainer = connect(undefined, mapDispatchToProps)(BackToRoomComponent) - export default BackToRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js index 8229a359..de46e491 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js @@ -1,13 +1,11 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openDeleteRackModal } from '../../../../../actions/modals/topology' import DeleteRackComponent from '../../../../../components/app/sidebars/topology/rack/DeleteRackComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openDeleteRackModal()), - } +const DeleteRackContainer = (props) => { + const dispatch = useDispatch() + return dispatch(openDeleteRackModal())} /> } -const DeleteRackContainer = connect(undefined, mapDispatchToProps)(DeleteRackComponent) - export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js index cf341da9..5bb2c784 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { addMachine } from '../../../../../actions/topology/rack' import EmptySlotComponent from '../../../../../components/app/sidebars/topology/rack/EmptySlotComponent' -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onAdd: () => dispatch(addMachine(ownProps.position)), - } +const EmptySlotContainer = (props) => { + const dispatch = useDispatch() + const onAdd = () => dispatch(addMachine(props.position)) + return } -const EmptySlotContainer = connect(undefined, mapDispatchToProps)(EmptySlotComponent) - export default EmptySlotContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js index fe12827d..149b4d18 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js @@ -1,19 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { goFromRackToMachine } from '../../../../../actions/interaction-level' import MachineComponent from '../../../../../components/app/sidebars/topology/rack/MachineComponent' -const mapStateToProps = (state, ownProps) => { - return { - machine: state.objects.machine[ownProps.machineId], - } +const MachineContainer = (props) => { + const machine = useSelector((state) => state.objects.machine[props.machineId]) + const dispatch = useDispatch() + return ( + dispatch(goFromRackToMachine(props.position))} machine={machine} /> + ) } -const mapDispatchToProps = (dispatch, ownProps) => { - return { - onClick: () => dispatch(goFromRackToMachine(ownProps.position)), - } -} - -const MachineContainer = connect(mapStateToProps, mapDispatchToProps)(MachineComponent) - export default MachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js index bc5a285a..b45300fc 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js @@ -1,12 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import MachineListComponent from '../../../../../components/app/sidebars/topology/rack/MachineListComponent' -const mapStateToProps = (state) => { - return { - machineIds: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds, - } +const MachineListContainer = (props) => { + const machineIds = useSelector( + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds + ) + return } -const MachineListContainer = connect(mapStateToProps)(MachineListComponent) - export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js index 504dbc61..7dfdb473 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js @@ -1,19 +1,14 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { openEditRackNameModal } from '../../../../../actions/modals/topology' import RackNameComponent from '../../../../../components/app/sidebars/topology/rack/RackNameComponent' -const mapStateToProps = (state) => { - return { - rackName: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name, - } +const RackNameContainer = (props) => { + const rackName = useSelector( + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name + ) + const dispatch = useDispatch() + return dispatch(openEditRackNameModal())} /> } -const mapDispatchToProps = (dispatch) => { - return { - onEdit: () => dispatch(openEditRackNameModal()), - } -} - -const RackNameContainer = connect(mapStateToProps, mapDispatchToProps)(RackNameComponent) - export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js index 453d7e41..b8fc3bfb 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RackSidebarComponent from '../../../../../components/app/sidebars/topology/rack/RackSidebarComponent' -const mapStateToProps = (state) => { - return { - rackId: state.objects.tile[state.interactionLevel.tileId].rackId, - } +const RackSidebarContainer = (props) => { + const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rackId) + return } -const RackSidebarContainer = connect(mapStateToProps)(RackSidebarComponent) - export default RackSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js index 4c1ab99d..a48bf0a7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' import BackToBuildingComponent from '../../../../../components/app/sidebars/topology/room/BackToBuildingComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(goDownOneInteractionLevel()), - } +const BackToBuildingContainer = () => { + const dispatch = useDispatch() + const onClick = () => dispatch(goDownOneInteractionLevel()) + return } -const BackToBuildingContainer = connect(undefined, mapDispatchToProps)(BackToBuildingComponent) - export default BackToBuildingContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js index 636fa5c5..6a80e9b0 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js @@ -1,13 +1,12 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch } from 'react-redux' import { openDeleteRoomModal } from '../../../../../actions/modals/topology' import DeleteRoomComponent from '../../../../../components/app/sidebars/topology/room/DeleteRoomComponent' -const mapDispatchToProps = (dispatch) => { - return { - onClick: () => dispatch(openDeleteRoomModal()), - } +const DeleteRoomContainer = (props) => { + const dispatch = useDispatch() + const onClick = () => dispatch(openDeleteRoomModal()) + return } -const DeleteRoomContainer = connect(undefined, mapDispatchToProps)(DeleteRoomComponent) - export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js index d17a45d1..37027fc5 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js @@ -1,21 +1,25 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { finishRoomEdit, startRoomEdit } from '../../../../../actions/topology/building' import EditRoomComponent from '../../../../../components/app/sidebars/topology/room/EditRoomComponent' -const mapStateToProps = (state) => { - return { - isEditing: state.construction.currentRoomInConstruction !== '-1', - isInRackConstructionMode: state.construction.inRackConstructionMode, - } -} +const EditRoomContainer = (props) => { + const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') + const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) -const mapDispatchToProps = (dispatch) => { - return { - onEdit: () => dispatch(startRoomEdit()), - onFinish: () => dispatch(finishRoomEdit()), - } -} + const dispatch = useDispatch() + const onEdit = () => dispatch(startRoomEdit()) + const onFinish = () => dispatch(finishRoomEdit()) -const EditRoomContainer = connect(mapStateToProps, mapDispatchToProps)(EditRoomComponent) + return ( + + ) +} export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js index cd8319de..726e9d37 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js @@ -1,21 +1,24 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { startRackConstruction, stopRackConstruction } from '../../../../../actions/topology/room' import RackConstructionComponent from '../../../../../components/app/sidebars/topology/room/RackConstructionComponent' -const mapStateToProps = (state) => { - return { - inRackConstructionMode: state.construction.inRackConstructionMode, - isEditingRoom: state.construction.currentRoomInConstruction !== '-1', - } -} +const RackConstructionContainer = (props) => { + const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) + const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') -const mapDispatchToProps = (dispatch) => { - return { - onStart: () => dispatch(startRackConstruction()), - onStop: () => dispatch(stopRackConstruction()), - } + const dispatch = useDispatch() + const onStart = () => dispatch(startRackConstruction()) + const onStop = () => dispatch(stopRackConstruction()) + return ( + + ) } -const RackConstructionContainer = connect(mapStateToProps, mapDispatchToProps)(RackConstructionComponent) - export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js index cab16016..1f53aeb6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js @@ -1,19 +1,13 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' import { openEditRoomNameModal } from '../../../../../actions/modals/topology' import RoomNameComponent from '../../../../../components/app/sidebars/topology/room/RoomNameComponent' -const mapStateToProps = (state) => { - return { - roomName: state.objects.room[state.interactionLevel.roomId].name, - } +const RoomNameContainer = (props) => { + const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name) + const dispatch = useDispatch() + const onEdit = () => dispatch(openEditRoomNameModal()) + return } -const mapDispatchToProps = (dispatch) => { - return { - onEdit: () => dispatch(openEditRoomNameModal()), - } -} - -const RoomNameContainer = connect(mapStateToProps, mapDispatchToProps)(RoomNameComponent) - export default RoomNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js index 8c3ca8ab..252881a0 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js @@ -1,12 +1,10 @@ -import { connect } from 'react-redux' +import React from 'react' +import { useSelector } from 'react-redux' import RoomSidebarComponent from '../../../../../components/app/sidebars/topology/room/RoomSidebarComponent' -const mapStateToProps = (state) => { - return { - roomId: state.interactionLevel.roomId, - } +const RoomSidebarContainer = (props) => { + const roomId = useSelector((state) => state.interactionLevel.roomId) + return } -const RoomSidebarContainer = connect(mapStateToProps)(RoomSidebarComponent) - export default RoomSidebarContainer -- cgit v1.2.3 From 4397a959e806bf476be4c81bc804616adf58b969 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 12 May 2021 22:42:12 +0200 Subject: ui: Migrate from CRA to Next.js This change updates the web frontend to use Next.js instead of Create React App (CRA). Next.js enables the possibility of rendering pages on the server side (which reduces the time to first frame) and overall provides a better development experience. Future commits will try to futher optimize the implementation for Next.js. --- opendc-web/opendc-web-ui/src/containers/app/App.js | 132 +++++++++++++++++++++ .../src/containers/app/map/MapStage.js | 4 +- .../app/sidebars/project/PortfolioListContainer.js | 6 +- .../sidebars/project/ProjectSidebarContainer.js | 6 +- .../app/sidebars/project/TopologyListContainer.js | 8 +- 5 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/containers/app/App.js (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/App.js b/opendc-web/opendc-web-ui/src/containers/app/App.js new file mode 100644 index 00000000..df159cc2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/App.js @@ -0,0 +1,132 @@ +/* + * 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, { useEffect } from 'react' +import Head from 'next/head' +import { useRouter } from 'next/router' +import { HotKeys } from 'react-hotkeys' +import { useDispatch, useSelector } from 'react-redux' +import { openPortfolioSucceeded } from '../../actions/portfolios' +import { openProjectSucceeded } from '../../actions/projects' +import ToolPanelComponent from '../../components/app/map/controls/ToolPanelComponent' +import LoadingScreen from '../../components/app/map/LoadingScreen' +import ScaleIndicatorContainer from '../../containers/app/map/controls/ScaleIndicatorContainer' +import MapStage from '../../containers/app/map/MapStage' +import TopologySidebarContainer from '../../containers/app/sidebars/topology/TopologySidebarContainer' +import DeleteMachineModal from '../../containers/modals/DeleteMachineModal' +import DeleteRackModal from '../../containers/modals/DeleteRackModal' +import DeleteRoomModal from '../../containers/modals/DeleteRoomModal' +import EditRackNameModal from '../../containers/modals/EditRackNameModal' +import EditRoomNameModal from '../../containers/modals/EditRoomNameModal' +import NewTopologyModal from '../../containers/modals/NewTopologyModal' +import AppNavbarContainer from '../../containers/navigation/AppNavbarContainer' +import ProjectSidebarContainer from '../../containers/app/sidebars/project/ProjectSidebarContainer' +import { openScenarioSucceeded } from '../../actions/scenarios' +import NewPortfolioModal from '../../containers/modals/NewPortfolioModal' +import NewScenarioModal from '../../containers/modals/NewScenarioModal' +import PortfolioResultsContainer from '../../containers/app/results/PortfolioResultsContainer' +import KeymapConfiguration from '../../shortcuts/keymap' +import { useRequireAuth } from '../../auth/hook' + +const App = ({ projectId, portfolioId, scenarioId }) => { + useRequireAuth() + + const projectName = useSelector( + (state) => + state.currentProjectId !== '-1' && + state.objects.project[state.currentProjectId] && + state.objects.project[state.currentProjectId].name + ) + const topologyIsLoading = useSelector((state) => state.currentTopologyIdd === '-1') + + const dispatch = useDispatch() + useEffect(() => { + if (scenarioId) { + dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)) + } else if (portfolioId) { + dispatch(openPortfolioSucceeded(projectId, portfolioId)) + } else { + dispatch(openProjectSucceeded(projectId)) + } + }, [projectId, portfolioId, scenarioId, dispatch]) + + const constructionElements = topologyIsLoading ? ( +
+ +
+ ) : ( +
+ + + + + +
+ ) + + const portfolioElements = ( +
+ +
+ +
+
+ ) + + const scenarioElements = ( +
+ +
+

Scenario loading

+
+
+ ) + + const title = projectName ? projectName + ' - OpenDC' : 'Simulation - OpenDC' + + return ( + + + {title} + + + {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} + + + + + + + + + + ) +} + +App.propTypes = { + projectId: PropTypes.string.isRequired, + portfolioId: PropTypes.string, + scenarioId: PropTypes.string, +} + +export default App diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js index 61d123e8..9394238d 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -4,11 +4,13 @@ import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } fro import MapStageComponent from '../../../components/app/map/MapStageComponent' const MapStage = () => { - const { position, dimensions } = useSelector((state) => state.map) + const position = useSelector((state) => state.map.position) + const dimensions = useSelector((state) => state.map.dimensions) const dispatch = useDispatch() const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height)) + return ( { }) const dispatch = useDispatch() - const history = useHistory() + const router = useRouter() const actions = { onNewPortfolio: () => { dispatch(openNewPortfolioModal()) @@ -37,7 +37,7 @@ const PortfolioListContainer = (props) => { const state = await getState(dispatch) dispatch(deletePortfolio(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - history.push(`/projects/${state.currentProjectId}`) + router.push(`/projects/${state.currentProjectId}`) } }, } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js index 35e6c52b..06c7f0f7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js @@ -1,11 +1,11 @@ import React from 'react' -import { useLocation } from 'react-router-dom' +import { useRouter } from 'next/router' import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' import { isCollapsible } from '../../../../util/sidebar-space' const ProjectSidebarContainer = (props) => { - const location = useLocation() - return + const router = useRouter() + return } export default ProjectSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 954284a6..e9c05f17 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -3,13 +3,13 @@ import { useDispatch, useSelector } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' import { setCurrentTopology } from '../../../../actions/topology/building' import { openNewTopologyModal } from '../../../../actions/modals/topology' -import { useHistory } from 'react-router-dom' +import { useRouter } from 'next/router' import { getState } from '../../../../util/state-utils' import { deleteTopology } from '../../../../actions/topologies' const TopologyListContainer = () => { const dispatch = useDispatch() - const history = useHistory() + const router = useRouter() const topologies = useSelector((state) => { let topologies = state.objects.project[state.currentProjectId] @@ -26,7 +26,7 @@ const TopologyListContainer = () => { const onChooseTopology = async (id) => { dispatch(setCurrentTopology(id)) const state = await getState(dispatch) - history.push(`/projects/${state.currentProjectId}`) + router.push(`/projects/${state.currentProjectId}`) } const onNewTopology = () => { dispatch(openNewTopologyModal()) @@ -36,7 +36,7 @@ const TopologyListContainer = () => { const state = await getState(dispatch) dispatch(deleteTopology(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - history.push(`/projects/${state.currentProjectId}`) + router.push(`/projects/${state.currentProjectId}`) } } -- cgit v1.2.3 From 24147cba0f5723be3525e8f40d1954144841629b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 13 May 2021 13:00:00 +0200 Subject: ui: Address technical dept in frontend --- opendc-web/opendc-web-ui/src/containers/app/App.js | 11 +++-------- opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js | 7 ++++--- .../opendc-web-ui/src/containers/app/map/TopologyContainer.js | 5 ++--- .../containers/app/map/controls/ScaleIndicatorContainer.js | 4 ++-- .../src/containers/app/map/controls/ZoomControlContainer.js | 5 +++-- .../opendc-web-ui/src/containers/app/map/layers/MapLayer.js | 5 +++-- 6 files changed, 17 insertions(+), 20 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/App.js b/opendc-web/opendc-web-ui/src/containers/app/App.js index df159cc2..bb9c5d56 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/App.js +++ b/opendc-web/opendc-web-ui/src/containers/app/App.js @@ -23,7 +23,6 @@ import PropTypes from 'prop-types' import React, { useEffect } from 'react' import Head from 'next/head' -import { useRouter } from 'next/router' import { HotKeys } from 'react-hotkeys' import { useDispatch, useSelector } from 'react-redux' import { openPortfolioSucceeded } from '../../actions/portfolios' @@ -47,17 +46,13 @@ import NewScenarioModal from '../../containers/modals/NewScenarioModal' import PortfolioResultsContainer from '../../containers/app/results/PortfolioResultsContainer' import KeymapConfiguration from '../../shortcuts/keymap' import { useRequireAuth } from '../../auth/hook' +import { useProject } from '../../store/hooks/project' const App = ({ projectId, portfolioId, scenarioId }) => { useRequireAuth() - const projectName = useSelector( - (state) => - state.currentProjectId !== '-1' && - state.objects.project[state.currentProjectId] && - state.objects.project[state.currentProjectId].name - ) - const topologyIsLoading = useSelector((state) => state.currentTopologyIdd === '-1') + const projectName = useProject()?.name + const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') const dispatch = useDispatch() useEffect(() => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js index 9394238d..db9a2dd1 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -1,11 +1,12 @@ import React from 'react' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../actions/map' import MapStageComponent from '../../../components/app/map/MapStageComponent' +import { useMapDimensions, useMapPosition } from '../../../store/hooks/map' const MapStage = () => { - const position = useSelector((state) => state.map.position) - const dimensions = useSelector((state) => state.map.dimensions) + const position = useMapPosition() + const dimensions = useMapDimensions() const dispatch = useDispatch() const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js index 612ca41c..30379490 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js @@ -1,11 +1,10 @@ import React from 'react' import { useSelector } from 'react-redux' import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' +import { useTopology } from '../../../store/hooks/topology' const TopologyContainer = () => { - const topology = useSelector( - (state) => state.currentTopologyId !== '-1' && state.objects.topology[state.currentTopologyId] - ) + const topology = useTopology() const interactionLevel = useSelector((state) => state.interactionLevel) return diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js index e9d58b9f..03834188 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js @@ -1,9 +1,9 @@ import React from 'react' -import { useSelector } from 'react-redux' import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' +import { useMapScale } from '../../../../store/hooks/map' const ScaleIndicatorContainer = (props) => { - const scale = useSelector((state) => state.map.scale) + const scale = useMapScale() return } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js index a18dfd5b..797bdf7f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js @@ -1,11 +1,12 @@ import React from 'react' -import { useDispatch, useSelector } from 'react-redux' +import { useDispatch } from 'react-redux' import { zoomInOnCenter } from '../../../../actions/map' import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent' +import { useMapScale } from '../../../../store/hooks/map' const ZoomControlContainer = () => { const dispatch = useDispatch() - const scale = useSelector((state) => state.map.scale) + const scale = useMapScale() return dispatch(zoomInOnCenter(zoomIn))} /> } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js index 5f701b4b..ccd0ea8f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js @@ -1,9 +1,10 @@ import React from 'react' -import { useSelector } from 'react-redux' import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' +import { useMapPosition, useMapScale } from '../../../../store/hooks/map' const MapLayer = (props) => { - const { position, scale } = useSelector((state) => state.map) + const position = useMapPosition() + const scale = useMapScale() return } -- cgit v1.2.3 From 1edbae1a0224e30bafb98638f419e1f967a9286f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 13 May 2021 17:42:53 +0200 Subject: ui: Move modal state outside of Redux This change updates the frontend so that the modal state is not stored inside Redux but instead is stored using the useState hook. This simplifies the design of the modal components. --- opendc-web/opendc-web-ui/src/containers/app/App.js | 20 +----- .../src/containers/app/map/TopologyContainer.js | 4 +- .../app/sidebars/project/PortfolioListContainer.js | 56 ++++++++------- .../app/sidebars/project/ScenarioListContainer.js | 79 ++++++++++++++-------- .../app/sidebars/project/TopologyListContainer.js | 63 ++++++++++------- .../topology/machine/DeleteMachineContainer.js | 31 +++++++-- .../topology/machine/MachineNameContainer.js | 5 +- .../sidebars/topology/rack/DeleteRackContainer.js | 31 +++++++-- .../sidebars/topology/rack/RackNameContainer.js | 29 ++++++-- .../sidebars/topology/room/DeleteRoomContainer.js | 32 +++++++-- .../sidebars/topology/room/EditRoomContainer.js | 28 +++++--- .../sidebars/topology/room/RoomNameContainer.js | 30 ++++++-- 12 files changed, 272 insertions(+), 136 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/App.js b/opendc-web/opendc-web-ui/src/containers/app/App.js index bb9c5d56..432435cf 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/App.js +++ b/opendc-web/opendc-web-ui/src/containers/app/App.js @@ -32,26 +32,18 @@ import LoadingScreen from '../../components/app/map/LoadingScreen' import ScaleIndicatorContainer from '../../containers/app/map/controls/ScaleIndicatorContainer' import MapStage from '../../containers/app/map/MapStage' import TopologySidebarContainer from '../../containers/app/sidebars/topology/TopologySidebarContainer' -import DeleteMachineModal from '../../containers/modals/DeleteMachineModal' -import DeleteRackModal from '../../containers/modals/DeleteRackModal' -import DeleteRoomModal from '../../containers/modals/DeleteRoomModal' -import EditRackNameModal from '../../containers/modals/EditRackNameModal' -import EditRoomNameModal from '../../containers/modals/EditRoomNameModal' -import NewTopologyModal from '../../containers/modals/NewTopologyModal' import AppNavbarContainer from '../../containers/navigation/AppNavbarContainer' import ProjectSidebarContainer from '../../containers/app/sidebars/project/ProjectSidebarContainer' import { openScenarioSucceeded } from '../../actions/scenarios' -import NewPortfolioModal from '../../containers/modals/NewPortfolioModal' -import NewScenarioModal from '../../containers/modals/NewScenarioModal' import PortfolioResultsContainer from '../../containers/app/results/PortfolioResultsContainer' import KeymapConfiguration from '../../shortcuts/keymap' import { useRequireAuth } from '../../auth/hook' -import { useProject } from '../../store/hooks/project' +import { useActiveProject } from '../../store/hooks/project' const App = ({ projectId, portfolioId, scenarioId }) => { useRequireAuth() - const projectName = useProject()?.name + const projectName = useActiveProject()?.name const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') const dispatch = useDispatch() @@ -106,14 +98,6 @@ const App = ({ projectId, portfolioId, scenarioId }) => { {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} - - - - - - - - ) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js index 30379490..25fbe3c0 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js @@ -1,10 +1,10 @@ import React from 'react' import { useSelector } from 'react-redux' import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -import { useTopology } from '../../../store/hooks/topology' +import { useActiveTopology } from '../../../store/hooks/topology' const TopologyContainer = () => { - const topology = useTopology() + const topology = useActiveTopology() const interactionLevel = useSelector((state) => state.interactionLevel) return diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index ce295f03..dca7d7db 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -1,34 +1,23 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' import { useRouter } from 'next/router' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' -import { deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios' -import { openNewPortfolioModal } from '../../../../actions/modals/portfolios' +import { addPortfolio, deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios' import { getState } from '../../../../util/state-utils' import { setCurrentTopology } from '../../../../actions/topology/building' +import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' +import { useActivePortfolio, useActiveProject, usePortfolios } from '../../../../store/hooks/project' -const PortfolioListContainer = (props) => { - const state = useSelector((state) => { - let portfolios = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t]) - : [] - if (portfolios.filter((t) => !t).length > 0) { - portfolios = [] - } - - return { - currentProjectId: state.currentProjectId, - currentPortfolioId: state.currentPortfolioId, - portfolios, - } - }) +const PortfolioListContainer = () => { + const currentProjectId = useActiveProject()?._id + const currentPortfolioId = useActivePortfolio()?._id + const portfolios = usePortfolios(currentProjectId) const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) const router = useRouter() const actions = { - onNewPortfolio: () => { - dispatch(openNewPortfolioModal()) - }, + onNewPortfolio: () => setVisible(true), onChoosePortfolio: (portfolioId) => { dispatch(setCurrentPortfolio(portfolioId)) }, @@ -41,7 +30,28 @@ const PortfolioListContainer = (props) => { } }, } - return + const callback = (name, targets) => { + if (name) { + dispatch( + addPortfolio({ + name, + targets, + }) + ) + } + setVisible(false) + } + return ( + <> + + + + ) } export default PortfolioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 18d0735e..5d747820 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -1,28 +1,27 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' -import { openNewScenarioModal } from '../../../../actions/modals/scenarios' -import { deleteScenario, setCurrentScenario } from '../../../../actions/scenarios' +import { addScenario, deleteScenario, setCurrentScenario } from '../../../../actions/scenarios' import { setCurrentPortfolio } from '../../../../actions/portfolios' +import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' +import { useProjectTopologies } from '../../../../store/hooks/topology' +import { useActiveScenario, useActiveProject, useScenarios } from '../../../../store/hooks/project' +import { useSchedulers, useTraces } from '../../../../store/hooks/experiments' -const ScenarioListContainer = ({ portfolioId, children }) => { - const currentProjectId = useSelector((state) => state.currentProjectId) - const currentScenarioId = useSelector((state) => state.currentScenarioId) - const scenarios = useSelector((state) => { - let scenarios = state.objects.portfolio[portfolioId] - ? state.objects.portfolio[portfolioId].scenarioIds.map((t) => state.objects.scenario[t]) - : [] - if (scenarios.filter((t) => !t).length > 0) { - scenarios = [] - } - - return scenarios - }) +const ScenarioListContainer = ({ portfolioId }) => { + const currentProjectId = useActiveProject()?._id + const currentScenarioId = useActiveScenario()?._id + const scenarios = useScenarios(portfolioId) + const topologies = useProjectTopologies() + const traces = useTraces() + const schedulers = useSchedulers() const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const onNewScenario = (currentPortfolioId) => { dispatch(setCurrentPortfolio(currentPortfolioId)) - dispatch(openNewScenarioModal()) + setVisible(true) } const onChooseScenario = (portfolioId, scenarioId) => { dispatch(setCurrentScenario(portfolioId, scenarioId)) @@ -32,17 +31,43 @@ const ScenarioListContainer = ({ portfolioId, children }) => { dispatch(deleteScenario(id)) } } + const callback = (name, portfolioId, trace, topology, operational) => { + if (name) { + dispatch( + addScenario({ + portfolioId, + name, + trace, + topology, + operational, + }) + ) + } + + setVisible(false) + } return ( - + <> + + s._id)} + traces={traces} + schedulers={schedulers} + topologies={topologies} + callback={callback} + /> + ) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index e9c05f17..3779705a 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -1,36 +1,25 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' +import React, { useState } from 'react' +import { useDispatch } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' import { setCurrentTopology } from '../../../../actions/topology/building' -import { openNewTopologyModal } from '../../../../actions/modals/topology' import { useRouter } from 'next/router' import { getState } from '../../../../util/state-utils' -import { deleteTopology } from '../../../../actions/topologies' +import { addTopology, deleteTopology } from '../../../../actions/topologies' +import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' +import { useActiveTopology, useProjectTopologies } from '../../../../store/hooks/topology' const TopologyListContainer = () => { const dispatch = useDispatch() const router = useRouter() - - const topologies = useSelector((state) => { - let topologies = state.objects.project[state.currentProjectId] - ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) - : [] - if (topologies.filter((t) => !t).length > 0) { - topologies = [] - } - - return topologies - }) - const currentTopologyId = useSelector((state) => state.currentTopologyId) + const topologies = useProjectTopologies() + const currentTopologyId = useActiveTopology()?._id + const [isVisible, setVisible] = useState(false) const onChooseTopology = async (id) => { dispatch(setCurrentTopology(id)) const state = await getState(dispatch) router.push(`/projects/${state.currentProjectId}`) } - const onNewTopology = () => { - dispatch(openNewTopologyModal()) - } const onDeleteTopology = async (id) => { if (id) { const state = await getState(dispatch) @@ -39,15 +28,37 @@ const TopologyListContainer = () => { router.push(`/projects/${state.currentProjectId}`) } } + const onCreateTopology = (name) => { + if (name) { + dispatch(addTopology(name, undefined)) + } + setVisible(false) + } + const onDuplicateTopology = (name, id) => { + if (name) { + dispatch(addTopology(name, id)) + } + setVisible(false) + } + const onCancel = () => setVisible(false) return ( - + <> + setVisible(true)} + onDeleteTopology={onDeleteTopology} + /> + + ) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js index 1510a436..2f171ce8 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -1,11 +1,32 @@ -import React from 'react' +import React, { useState } from 'react' import { useDispatch } from 'react-redux' -import { openDeleteMachineModal } from '../../../../../actions/modals/topology' -import DeleteMachineComponent from '../../../../../components/app/sidebars/topology/machine/DeleteMachineComponent' +import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' +import { deleteMachine } from '../../../../../actions/topology/machine' +import { Button } from 'reactstrap' -const DeleteMachineContainer = (props) => { +const DeleteMachineContainer = () => { const dispatch = useDispatch() - return dispatch(openDeleteMachineModal())} /> + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteMachine()) + } + setVisible(false) + } + return ( + <> + + + + ) } export default DeleteMachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js index 6f4285b2..9cbb32c5 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js @@ -1,10 +1,9 @@ import React from 'react' import { useSelector } from 'react-redux' -import MachineNameComponent from '../../../../../components/app/sidebars/topology/machine/MachineNameComponent' -const MachineNameContainer = (props) => { +const MachineNameContainer = () => { const position = useSelector((state) => state.interactionLevel.position) - return + return

Machine at slot {position}

} export default MachineNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js index de46e491..4c7fd8bf 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js @@ -1,11 +1,32 @@ -import React from 'react' +import React, { useState } from 'react' import { useDispatch } from 'react-redux' -import { openDeleteRackModal } from '../../../../../actions/modals/topology' -import DeleteRackComponent from '../../../../../components/app/sidebars/topology/rack/DeleteRackComponent' +import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' +import { deleteRack } from '../../../../../actions/topology/rack' +import { Button } from 'reactstrap' -const DeleteRackContainer = (props) => { +const DeleteRackContainer = () => { const dispatch = useDispatch() - return dispatch(openDeleteRackModal())} /> + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRack()) + } + setVisible(false) + } + return ( + <> + + + + ) } export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js index 7dfdb473..dd9b05fc 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js @@ -1,14 +1,33 @@ -import React from 'react' +import React, { useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { openEditRackNameModal } from '../../../../../actions/modals/topology' -import RackNameComponent from '../../../../../components/app/sidebars/topology/rack/RackNameComponent' +import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' +import TextInputModal from '../../../../../components/modals/TextInputModal' +import { editRackName } from '../../../../../actions/topology/rack' -const RackNameContainer = (props) => { +const RackNameContainer = () => { + const [isVisible, setVisible] = useState(false) const rackName = useSelector( (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name ) const dispatch = useDispatch() - return dispatch(openEditRackNameModal())} /> + const callback = (name) => { + if (name) { + dispatch(editRackName(name)) + } + setVisible(false) + } + return ( + <> + setVisible(true)} /> + + + ) } export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js index 6a80e9b0..2062462f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js @@ -1,12 +1,32 @@ -import React from 'react' +import React, { useState } from 'react' import { useDispatch } from 'react-redux' -import { openDeleteRoomModal } from '../../../../../actions/modals/topology' -import DeleteRoomComponent from '../../../../../components/app/sidebars/topology/room/DeleteRoomComponent' +import { Button } from 'reactstrap' +import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' +import { deleteRoom } from '../../../../../actions/topology/room' -const DeleteRoomContainer = (props) => { +const DeleteRoomContainer = () => { const dispatch = useDispatch() - const onClick = () => dispatch(openDeleteRoomModal()) - return + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRoom()) + } + setVisible(false) + } + return ( + <> + + + + ) } export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js index 37027fc5..f03b0efb 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js @@ -1,9 +1,9 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { finishRoomEdit, startRoomEdit } from '../../../../../actions/topology/building' -import EditRoomComponent from '../../../../../components/app/sidebars/topology/room/EditRoomComponent' +import { Button } from 'reactstrap' -const EditRoomContainer = (props) => { +const EditRoomContainer = () => { const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) @@ -11,14 +11,22 @@ const EditRoomContainer = (props) => { const onEdit = () => dispatch(startRoomEdit()) const onFinish = () => dispatch(finishRoomEdit()) - return ( - + return isEditing ? ( + + ) : ( + ) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js index 1f53aeb6..946bb864 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js @@ -1,13 +1,31 @@ -import React from 'react' +import React, { useState } from 'react' import { useDispatch, useSelector } from 'react-redux' -import { openEditRoomNameModal } from '../../../../../actions/modals/topology' -import RoomNameComponent from '../../../../../components/app/sidebars/topology/room/RoomNameComponent' +import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' +import TextInputModal from '../../../../../components/modals/TextInputModal' +import { editRoomName } from '../../../../../actions/topology/room' -const RoomNameContainer = (props) => { +const RoomNameContainer = () => { + const [isVisible, setVisible] = useState(false) const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name) const dispatch = useDispatch() - const onEdit = () => dispatch(openEditRoomNameModal()) - return + const callback = (name) => { + if (name) { + dispatch(editRoomName(name)) + } + setVisible(false) + } + return ( + <> + setVisible(true)} /> + + + ) } export default RoomNameContainer -- cgit v1.2.3 From d9e65dceb38cdb8dc4e464d388755f9456620566 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 17:07:58 +0200 Subject: ui: Restructure OpenDC frontend This change updates the structure of the OpenDC frontend in order to improve the maintainability of the frontend. --- opendc-web/opendc-web-ui/src/containers/app/App.js | 12 ++++++------ .../opendc-web-ui/src/containers/app/map/GrayContainer.js | 2 +- opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js | 4 ++-- .../opendc-web-ui/src/containers/app/map/RoomContainer.js | 2 +- .../opendc-web-ui/src/containers/app/map/TileContainer.js | 2 +- .../src/containers/app/map/TopologyContainer.js | 2 +- .../containers/app/map/controls/ScaleIndicatorContainer.js | 2 +- .../src/containers/app/map/controls/ZoomControlContainer.js | 4 ++-- .../opendc-web-ui/src/containers/app/map/layers/MapLayer.js | 2 +- .../src/containers/app/map/layers/ObjectHoverLayer.js | 2 +- .../src/containers/app/map/layers/RoomHoverLayer.js | 2 +- .../app/sidebars/project/PortfolioListContainer.js | 6 +++--- .../containers/app/sidebars/project/ScenarioListContainer.js | 10 +++++----- .../containers/app/sidebars/project/TopologyListContainer.js | 6 +++--- .../topology/building/NewRoomConstructionContainer.js | 2 +- .../app/sidebars/topology/machine/BackToRackContainer.js | 2 +- .../app/sidebars/topology/machine/DeleteMachineContainer.js | 2 +- .../app/sidebars/topology/machine/UnitAddContainer.js | 2 +- .../app/sidebars/topology/machine/UnitContainer.js | 2 +- .../app/sidebars/topology/rack/AddPrefabContainer.js | 2 +- .../app/sidebars/topology/rack/BackToRoomContainer.js | 2 +- .../app/sidebars/topology/rack/DeleteRackContainer.js | 2 +- .../app/sidebars/topology/rack/EmptySlotContainer.js | 2 +- .../app/sidebars/topology/rack/MachineContainer.js | 2 +- .../app/sidebars/topology/rack/RackNameContainer.js | 2 +- .../app/sidebars/topology/room/BackToBuildingContainer.js | 2 +- .../app/sidebars/topology/room/DeleteRoomContainer.js | 2 +- .../app/sidebars/topology/room/EditRoomContainer.js | 2 +- .../app/sidebars/topology/room/RackConstructionContainer.js | 2 +- .../app/sidebars/topology/room/RoomNameContainer.js | 2 +- 30 files changed, 45 insertions(+), 45 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/App.js b/opendc-web/opendc-web-ui/src/containers/app/App.js index 432435cf..ec9714ce 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/App.js +++ b/opendc-web/opendc-web-ui/src/containers/app/App.js @@ -25,8 +25,8 @@ import React, { useEffect } from 'react' import Head from 'next/head' import { HotKeys } from 'react-hotkeys' import { useDispatch, useSelector } from 'react-redux' -import { openPortfolioSucceeded } from '../../actions/portfolios' -import { openProjectSucceeded } from '../../actions/projects' +import { openPortfolioSucceeded } from '../../redux/actions/portfolios' +import { openProjectSucceeded } from '../../redux/actions/projects' import ToolPanelComponent from '../../components/app/map/controls/ToolPanelComponent' import LoadingScreen from '../../components/app/map/LoadingScreen' import ScaleIndicatorContainer from '../../containers/app/map/controls/ScaleIndicatorContainer' @@ -34,11 +34,11 @@ import MapStage from '../../containers/app/map/MapStage' import TopologySidebarContainer from '../../containers/app/sidebars/topology/TopologySidebarContainer' import AppNavbarContainer from '../../containers/navigation/AppNavbarContainer' import ProjectSidebarContainer from '../../containers/app/sidebars/project/ProjectSidebarContainer' -import { openScenarioSucceeded } from '../../actions/scenarios' +import { openScenarioSucceeded } from '../../redux/actions/scenarios' import PortfolioResultsContainer from '../../containers/app/results/PortfolioResultsContainer' -import KeymapConfiguration from '../../shortcuts/keymap' -import { useRequireAuth } from '../../auth/hook' -import { useActiveProject } from '../../store/hooks/project' +import { KeymapConfiguration } from '../../hotkeys' +import { useRequireAuth } from '../../auth' +import { useActiveProject } from '../../data/project' const App = ({ projectId, portfolioId, scenarioId }) => { useRequireAuth() diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js index 651b3459..bac24c8b 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../actions/interaction-level' +import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' import GrayLayer from '../../../components/app/map/elements/GrayLayer' const GrayContainer = () => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js index db9a2dd1..91ceb35d 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -1,8 +1,8 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../actions/map' +import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../redux/actions/map' import MapStageComponent from '../../../components/app/map/MapStageComponent' -import { useMapDimensions, useMapPosition } from '../../../store/hooks/map' +import { useMapDimensions, useMapPosition } from '../../../data/map' const MapStage = () => { const position = useMapPosition() diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js index 877233fc..52d48317 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { goFromBuildingToRoom } from '../../../actions/interaction-level' +import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' import RoomGroup from '../../../components/app/map/groups/RoomGroup' const RoomContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js index ad7301a7..f97e89a1 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { goFromRoomToRack } from '../../../actions/interaction-level' +import { goFromRoomToRack } from '../../../redux/actions/interaction-level' import TileGroup from '../../../components/app/map/groups/TileGroup' const TileContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js index 25fbe3c0..e7ab3c72 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js @@ -1,7 +1,7 @@ import React from 'react' import { useSelector } from 'react-redux' import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -import { useActiveTopology } from '../../../store/hooks/topology' +import { useActiveTopology } from '../../../data/topology' const TopologyContainer = () => { const topology = useActiveTopology() diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js index 03834188..a10eea22 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js @@ -1,6 +1,6 @@ import React from 'react' import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' -import { useMapScale } from '../../../../store/hooks/map' +import { useMapScale } from '../../../../data/map' const ScaleIndicatorContainer = (props) => { const scale = useMapScale() diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js index 797bdf7f..a39c6077 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js @@ -1,8 +1,8 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { zoomInOnCenter } from '../../../../actions/map' +import { zoomInOnCenter } from '../../../../redux/actions/map' import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent' -import { useMapScale } from '../../../../store/hooks/map' +import { useMapScale } from '../../../../data/map' const ZoomControlContainer = () => { const dispatch = useDispatch() diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js index ccd0ea8f..633ebcc7 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js @@ -1,6 +1,6 @@ import React from 'react' import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' -import { useMapPosition, useMapScale } from '../../../../store/hooks/map' +import { useMapPosition, useMapScale } from '../../../../data/map' const MapLayer = (props) => { const position = useMapPosition() diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js index cefdf35c..8e934a01 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { addRackToTile } from '../../../../actions/topology/room' +import { addRackToTile } from '../../../../redux/actions/topology/room' import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' import { findTileWithPosition } from '../../../../util/tile-calculations' diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js index 2717d890..1bfadb6d 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { toggleTileAtLocation } from '../../../../actions/topology/building' +import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' import { deriveValidNextTilePositions, diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index dca7d7db..a36997ff 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -2,11 +2,11 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import { useRouter } from 'next/router' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' -import { addPortfolio, deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios' +import { addPortfolio, deletePortfolio, setCurrentPortfolio } from '../../../../redux/actions/portfolios' import { getState } from '../../../../util/state-utils' -import { setCurrentTopology } from '../../../../actions/topology/building' +import { setCurrentTopology } from '../../../../redux/actions/topology/building' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { useActivePortfolio, useActiveProject, usePortfolios } from '../../../../store/hooks/project' +import { useActivePortfolio, useActiveProject, usePortfolios } from '../../../../data/project' const PortfolioListContainer = () => { const currentProjectId = useActiveProject()?._id diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 5d747820..7aaa1886 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -1,12 +1,12 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' -import { addScenario, deleteScenario, setCurrentScenario } from '../../../../actions/scenarios' -import { setCurrentPortfolio } from '../../../../actions/portfolios' +import { addScenario, deleteScenario, setCurrentScenario } from '../../../../redux/actions/scenarios' +import { setCurrentPortfolio } from '../../../../redux/actions/portfolios' import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' -import { useProjectTopologies } from '../../../../store/hooks/topology' -import { useActiveScenario, useActiveProject, useScenarios } from '../../../../store/hooks/project' -import { useSchedulers, useTraces } from '../../../../store/hooks/experiments' +import { useProjectTopologies } from '../../../../data/topology' +import { useActiveScenario, useActiveProject, useScenarios } from '../../../../data/project' +import { useSchedulers, useTraces } from '../../../../data/experiments' const ScenarioListContainer = ({ portfolioId }) => { const currentProjectId = useActiveProject()?._id diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 3779705a..266ca495 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -1,12 +1,12 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' -import { setCurrentTopology } from '../../../../actions/topology/building' +import { setCurrentTopology } from '../../../../redux/actions/topology/building' import { useRouter } from 'next/router' import { getState } from '../../../../util/state-utils' -import { addTopology, deleteTopology } from '../../../../actions/topologies' +import { addTopology, deleteTopology } from '../../../../redux/actions/topologies' import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' -import { useActiveTopology, useProjectTopologies } from '../../../../store/hooks/topology' +import { useActiveTopology, useProjectTopologies } from '../../../../data/topology' const TopologyListContainer = () => { const dispatch = useDispatch() diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js index ea36539c..96f42a44 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js @@ -4,7 +4,7 @@ import { cancelNewRoomConstruction, finishNewRoomConstruction, startNewRoomConstruction, -} from '../../../../../actions/topology/building' +} from '../../../../../redux/actions/topology/building' import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent' const NewRoomConstructionButton = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js index 46862472..ea250767 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' +import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' import BackToRackComponent from '../../../../../components/app/sidebars/topology/machine/BackToRackComponent' const BackToRackContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js index 2f171ce8..f3344424 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -1,7 +1,7 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteMachine } from '../../../../../actions/topology/machine' +import { deleteMachine } from '../../../../../redux/actions/topology/machine' import { Button } from 'reactstrap' const DeleteMachineContainer = () => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js index 3795cdff..0f85aa76 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { addUnit } from '../../../../../actions/topology/machine' +import { addUnit } from '../../../../../redux/actions/topology/machine' import UnitAddComponent from '../../../../../components/app/sidebars/topology/machine/UnitAddComponent' const UnitAddContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js index 3d24859e..acb16a21 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { deleteUnit } from '../../../../../actions/topology/machine' +import { deleteUnit } from '../../../../../redux/actions/topology/machine' import UnitComponent from '../../../../../components/app/sidebars/topology/machine/UnitComponent' const UnitContainer = ({ unitId, unitType }) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js index 3708e33e..c2a0fc48 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { addPrefab } from '../../../../../actions/prefabs' +import { addPrefab } from '../../../../../redux/actions/prefabs' import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent' const AddPrefabContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js index 93bb749f..a98728a6 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' +import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' import BackToRoomComponent from '../../../../../components/app/sidebars/topology/rack/BackToRoomComponent' const BackToRoomContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js index 4c7fd8bf..290803c2 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js @@ -1,7 +1,7 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRack } from '../../../../../actions/topology/rack' +import { deleteRack } from '../../../../../redux/actions/topology/rack' import { Button } from 'reactstrap' const DeleteRackContainer = () => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js index 5bb2c784..2134e411 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { addMachine } from '../../../../../actions/topology/rack' +import { addMachine } from '../../../../../redux/actions/topology/rack' import EmptySlotComponent from '../../../../../components/app/sidebars/topology/rack/EmptySlotComponent' const EmptySlotContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js index 149b4d18..7d8e32c1 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { goFromRackToMachine } from '../../../../../actions/interaction-level' +import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' import MachineComponent from '../../../../../components/app/sidebars/topology/rack/MachineComponent' const MachineContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js index dd9b05fc..eaa1e78e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js @@ -2,7 +2,7 @@ import React, { useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' import TextInputModal from '../../../../../components/modals/TextInputModal' -import { editRackName } from '../../../../../actions/topology/rack' +import { editRackName } from '../../../../../redux/actions/topology/rack' const RackNameContainer = () => { const [isVisible, setVisible] = useState(false) diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js index a48bf0a7..9fa1e95f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../actions/interaction-level' +import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' import BackToBuildingComponent from '../../../../../components/app/sidebars/topology/room/BackToBuildingComponent' const BackToBuildingContainer = () => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js index 2062462f..3560c381 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js @@ -2,7 +2,7 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import { Button } from 'reactstrap' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRoom } from '../../../../../actions/topology/room' +import { deleteRoom } from '../../../../../redux/actions/topology/room' const DeleteRoomContainer = () => { const dispatch = useDispatch() diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js index f03b0efb..2ecdfbcf 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { finishRoomEdit, startRoomEdit } from '../../../../../actions/topology/building' +import { finishRoomEdit, startRoomEdit } from '../../../../../redux/actions/topology/building' import { Button } from 'reactstrap' const EditRoomContainer = () => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js index 726e9d37..79584e98 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js @@ -1,6 +1,6 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' -import { startRackConstruction, stopRackConstruction } from '../../../../../actions/topology/room' +import { startRackConstruction, stopRackConstruction } from '../../../../../redux/actions/topology/room' import RackConstructionComponent from '../../../../../components/app/sidebars/topology/room/RackConstructionComponent' const RackConstructionContainer = (props) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js index 946bb864..3b35a849 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js @@ -2,7 +2,7 @@ import React, { useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' import TextInputModal from '../../../../../components/modals/TextInputModal' -import { editRoomName } from '../../../../../actions/topology/room' +import { editRoomName } from '../../../../../redux/actions/topology/room' const RoomNameContainer = () => { const [isVisible, setVisible] = useState(false) -- cgit v1.2.3 From a6865b86cc8d710374fc0b6cfcbd2b863f1942a9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 16 May 2021 23:18:02 +0200 Subject: ui: Migrate to Auth0 as Identity Provider This change updates the frontend codebase to move away from the Google login and instead use Auth0 as generic Identity Provider. This allows users to login with other accounts as well. Since Auth0 has a free tier, users can experiment themselves with OpenDC locally without having to pay for the login functionality. The code has been written so that we should be able to migrate away from Auth0 once it is not a suitable Identity Provider for OpenDC anymore. --- .../src/containers/app/sidebars/project/ScenarioListContainer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 7aaa1886..e1be51dc 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -60,7 +60,7 @@ const ScenarioListContainer = ({ portfolioId }) => { /> s._id)} traces={traces} schedulers={schedulers} -- cgit v1.2.3 From 53623fad76274e39206b8e073e371775ea96946b Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 17 May 2021 12:16:10 +0200 Subject: ui: Migrate to FontAwesome 5 React library This change updates the frontend to use the FontAwesome 5 React library that renders SVG icons as opposed to CSS icon fonts. This migration resolves a couple of issues we had with server-side rendering of the previous FontAwesome icons. --- .../app/sidebars/topology/machine/DeleteMachineContainer.js | 4 +++- .../containers/app/sidebars/topology/rack/DeleteRackContainer.js | 4 +++- .../containers/app/sidebars/topology/room/DeleteRoomContainer.js | 4 +++- .../src/containers/app/sidebars/topology/room/EditRoomContainer.js | 6 ++++-- 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js index f3344424..54e406f4 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -3,6 +3,8 @@ import { useDispatch } from 'react-redux' import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' import { deleteMachine } from '../../../../../redux/actions/topology/machine' import { Button } from 'reactstrap' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' +import { faTrash } from '@fortawesome/free-solid-svg-icons' const DeleteMachineContainer = () => { const dispatch = useDispatch() @@ -16,7 +18,7 @@ const DeleteMachineContainer = () => { return ( <> { const dispatch = useDispatch() @@ -16,7 +18,7 @@ const DeleteRackContainer = () => { return ( <> { const dispatch = useDispatch() @@ -16,7 +18,7 @@ const DeleteRoomContainer = () => { return ( <> { const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') @@ -13,7 +15,7 @@ const EditRoomContainer = () => { return isEditing ? ( ) : ( @@ -24,7 +26,7 @@ const EditRoomContainer = () => { disabled={isInRackConstructionMode} onClick={() => (isInRackConstructionMode ? undefined : onEdit())} > - + Edit the tiles of this room ) -- cgit v1.2.3 From 1ce8bf170cda2afab334cd330325cd4fbb97dab4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 11:46:57 +0200 Subject: ui: Split App container into separate components This change splits the App container into separate pages, as a starting point for removing much of the unnecessary state from Redux. --- opendc-web/opendc-web-ui/src/containers/app/App.js | 111 --------------------- .../app/sidebars/project/PortfolioListContainer.js | 7 +- .../app/sidebars/project/ScenarioListContainer.js | 11 +- .../app/sidebars/project/TopologyListContainer.js | 4 +- 4 files changed, 14 insertions(+), 119 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/App.js (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/App.js b/opendc-web/opendc-web-ui/src/containers/app/App.js deleted file mode 100644 index ec9714ce..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/App.js +++ /dev/null @@ -1,111 +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, { useEffect } from 'react' -import Head from 'next/head' -import { HotKeys } from 'react-hotkeys' -import { useDispatch, useSelector } from 'react-redux' -import { openPortfolioSucceeded } from '../../redux/actions/portfolios' -import { openProjectSucceeded } from '../../redux/actions/projects' -import ToolPanelComponent from '../../components/app/map/controls/ToolPanelComponent' -import LoadingScreen from '../../components/app/map/LoadingScreen' -import ScaleIndicatorContainer from '../../containers/app/map/controls/ScaleIndicatorContainer' -import MapStage from '../../containers/app/map/MapStage' -import TopologySidebarContainer from '../../containers/app/sidebars/topology/TopologySidebarContainer' -import AppNavbarContainer from '../../containers/navigation/AppNavbarContainer' -import ProjectSidebarContainer from '../../containers/app/sidebars/project/ProjectSidebarContainer' -import { openScenarioSucceeded } from '../../redux/actions/scenarios' -import PortfolioResultsContainer from '../../containers/app/results/PortfolioResultsContainer' -import { KeymapConfiguration } from '../../hotkeys' -import { useRequireAuth } from '../../auth' -import { useActiveProject } from '../../data/project' - -const App = ({ projectId, portfolioId, scenarioId }) => { - useRequireAuth() - - const projectName = useActiveProject()?.name - const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1') - - const dispatch = useDispatch() - useEffect(() => { - if (scenarioId) { - dispatch(openScenarioSucceeded(projectId, portfolioId, scenarioId)) - } else if (portfolioId) { - dispatch(openPortfolioSucceeded(projectId, portfolioId)) - } else { - dispatch(openProjectSucceeded(projectId)) - } - }, [projectId, portfolioId, scenarioId, dispatch]) - - const constructionElements = topologyIsLoading ? ( -
- -
- ) : ( -
- - - - - -
- ) - - const portfolioElements = ( -
- -
- -
-
- ) - - const scenarioElements = ( -
- -
-

Scenario loading

-
-
- ) - - const title = projectName ? projectName + ' - OpenDC' : 'Simulation - OpenDC' - - return ( - - - {title} - - - {scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements} - - ) -} - -App.propTypes = { - projectId: PropTypes.string.isRequired, - portfolioId: PropTypes.string, - scenarioId: PropTypes.string, -} - -export default App diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index a36997ff..28d7f0d1 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -6,16 +6,15 @@ import { addPortfolio, deletePortfolio, setCurrentPortfolio } from '../../../../ import { getState } from '../../../../util/state-utils' import { setCurrentTopology } from '../../../../redux/actions/topology/building' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { useActivePortfolio, useActiveProject, usePortfolios } from '../../../../data/project' +import { usePortfolios } from '../../../../data/project' const PortfolioListContainer = () => { - const currentProjectId = useActiveProject()?._id - const currentPortfolioId = useActivePortfolio()?._id + const router = useRouter() + const { project: currentProjectId, portfolio: currentPortfolioId } = router.query const portfolios = usePortfolios(currentProjectId) const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) - const router = useRouter() const actions = { onNewPortfolio: () => setVisible(true), onChoosePortfolio: (portfolioId) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index e1be51dc..10743401 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types' import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' @@ -5,11 +6,13 @@ import { addScenario, deleteScenario, setCurrentScenario } from '../../../../red import { setCurrentPortfolio } from '../../../../redux/actions/portfolios' import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' import { useProjectTopologies } from '../../../../data/topology' -import { useActiveScenario, useActiveProject, useScenarios } from '../../../../data/project' +import { useActiveScenario, useScenarios } from '../../../../data/project' import { useSchedulers, useTraces } from '../../../../data/experiments' +import { useRouter } from 'next/router' const ScenarioListContainer = ({ portfolioId }) => { - const currentProjectId = useActiveProject()?._id + const router = useRouter() + const { project: currentProjectId } = router.query const currentScenarioId = useActiveScenario()?._id const scenarios = useScenarios(portfolioId) const topologies = useProjectTopologies() @@ -71,4 +74,8 @@ const ScenarioListContainer = ({ portfolioId }) => { ) } +ScenarioListContainer.propTypes = { + portfolioId: PropTypes.string.isRequired, +} + export default ScenarioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 266ca495..648c4500 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -18,14 +18,14 @@ const TopologyListContainer = () => { const onChooseTopology = async (id) => { dispatch(setCurrentTopology(id)) const state = await getState(dispatch) - router.push(`/projects/${state.currentProjectId}`) + await router.push(`/projects/${state.currentProjectId}/topologies/${id}`) } const onDeleteTopology = async (id) => { if (id) { const state = await getState(dispatch) dispatch(deleteTopology(id)) dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - router.push(`/projects/${state.currentProjectId}`) + await router.push(`/projects/${state.currentProjectId}`) } } const onCreateTopology = (name) => { -- cgit v1.2.3 From aa788a3ad18badfac8beaabdaffc88b9e52f9306 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 15:07:11 +0200 Subject: ui: Remove current ids state from Redux This change removes the current active identifiers from the Redux state. Instead, we use the router query to track the active project, portfolio and topology. --- .../containers/app/results/PortfolioResultsContainer.js | 13 ++++++++----- .../app/sidebars/project/PortfolioListContainer.js | 12 ++++++------ .../app/sidebars/project/ScenarioListContainer.js | 14 +++----------- .../app/sidebars/project/TopologyListContainer.js | 14 ++++++-------- 4 files changed, 23 insertions(+), 30 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js index e60abe18..ce7d5514 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js @@ -1,13 +1,16 @@ import React from 'react' import { useSelector } from 'react-redux' import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' +import { useRouter } from 'next/router' const PortfolioResultsContainer = (props) => { + const router = useRouter() + const { portfolio: currentPortfolioId } = router.query const { scenarios, portfolio } = useSelector((state) => { if ( - state.currentPortfolioId === '-1' || - !state.objects.portfolio[state.currentPortfolioId] || - state.objects.portfolio[state.currentPortfolioId].scenarioIds + !currentPortfolioId || + !state.objects.portfolio[currentPortfolioId] || + state.objects.portfolio[currentPortfolioId].scenarioIds .map((scenarioId) => state.objects.scenario[scenarioId]) .some((s) => s === undefined) ) { @@ -18,8 +21,8 @@ const PortfolioResultsContainer = (props) => { } return { - portfolio: state.objects.portfolio[state.currentPortfolioId], - scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map( + portfolio: state.objects.portfolio[currentPortfolioId], + scenarios: state.objects.portfolio[currentPortfolioId].scenarioIds.map( (scenarioId) => state.objects.scenario[scenarioId] ), } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index 28d7f0d1..b5bade98 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -2,7 +2,7 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import { useRouter } from 'next/router' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' -import { addPortfolio, deletePortfolio, setCurrentPortfolio } from '../../../../redux/actions/portfolios' +import { addPortfolio, deletePortfolio } from '../../../../redux/actions/portfolios' import { getState } from '../../../../util/state-utils' import { setCurrentTopology } from '../../../../redux/actions/topology/building' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' @@ -17,22 +17,22 @@ const PortfolioListContainer = () => { const [isVisible, setVisible] = useState(false) const actions = { onNewPortfolio: () => setVisible(true), - onChoosePortfolio: (portfolioId) => { - dispatch(setCurrentPortfolio(portfolioId)) + onChoosePortfolio: async (portfolioId) => { + await router.push(`/projects/${currentProjectId}/portfolios/${portfolioId}`) }, onDeletePortfolio: async (id) => { if (id) { const state = await getState(dispatch) dispatch(deletePortfolio(id)) - dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - router.push(`/projects/${state.currentProjectId}`) + dispatch(setCurrentTopology(state.objects.project[currentProjectId].topologyIds[0])) + await router.push(`/projects/${currentProjectId}`) } }, } const callback = (name, targets) => { if (name) { dispatch( - addPortfolio({ + addPortfolio(currentProjectId, { name, targets, }) diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 10743401..0eb61026 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -2,18 +2,16 @@ import PropTypes from 'prop-types' import React, { useState } from 'react' import { useDispatch } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' -import { addScenario, deleteScenario, setCurrentScenario } from '../../../../redux/actions/scenarios' -import { setCurrentPortfolio } from '../../../../redux/actions/portfolios' +import { addScenario, deleteScenario } from '../../../../redux/actions/scenarios' import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' import { useProjectTopologies } from '../../../../data/topology' -import { useActiveScenario, useScenarios } from '../../../../data/project' +import { useScenarios } from '../../../../data/project' import { useSchedulers, useTraces } from '../../../../data/experiments' import { useRouter } from 'next/router' const ScenarioListContainer = ({ portfolioId }) => { const router = useRouter() const { project: currentProjectId } = router.query - const currentScenarioId = useActiveScenario()?._id const scenarios = useScenarios(portfolioId) const topologies = useProjectTopologies() const traces = useTraces() @@ -23,12 +21,9 @@ const ScenarioListContainer = ({ portfolioId }) => { const [isVisible, setVisible] = useState(false) const onNewScenario = (currentPortfolioId) => { - dispatch(setCurrentPortfolio(currentPortfolioId)) setVisible(true) } - const onChooseScenario = (portfolioId, scenarioId) => { - dispatch(setCurrentScenario(portfolioId, scenarioId)) - } + const onChooseScenario = (portfolioId, scenarioId) => {} const onDeleteScenario = (id) => { if (id) { dispatch(deleteScenario(id)) @@ -54,11 +49,8 @@ const ScenarioListContainer = ({ portfolioId }) => { <> { const dispatch = useDispatch() const router = useRouter() + const { project: currentProjectId } = router.query const topologies = useProjectTopologies() const currentTopologyId = useActiveTopology()?._id const [isVisible, setVisible] = useState(false) const onChooseTopology = async (id) => { dispatch(setCurrentTopology(id)) - const state = await getState(dispatch) - await router.push(`/projects/${state.currentProjectId}/topologies/${id}`) + await router.push(`/projects/${currentProjectId}/topologies/${id}`) } const onDeleteTopology = async (id) => { if (id) { - const state = await getState(dispatch) dispatch(deleteTopology(id)) - dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) - await router.push(`/projects/${state.currentProjectId}`) + dispatch(setCurrentTopology(state.objects.project[currentProjectId].topologyIds[0])) + await router.push(`/projects/${currentProjectId}`) } } const onCreateTopology = (name) => { if (name) { - dispatch(addTopology(name, undefined)) + dispatch(addTopology(currentProjectId, name, undefined)) } setVisible(false) } const onDuplicateTopology = (name, id) => { if (name) { - dispatch(addTopology(name, id)) + dispatch(addTopology(currentProjectId, name, id)) } setVisible(false) } -- cgit v1.2.3 From e5e5d2c65e583493870bc0b62fb185c5e757c13f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 16:27:49 +0200 Subject: ui: Migrate project APIs to React Query This change updates the OpenDC frontend to use React Query for fetching and mutating project data. Previously, this state was tracked and synchronized via Redux. Migrating to React Query greatly simplifies the state synchronization logic necessary in the frontend. --- .../src/containers/app/sidebars/project/PortfolioListContainer.js | 5 +++-- .../src/containers/app/sidebars/project/ScenarioListContainer.js | 6 +----- .../src/containers/app/sidebars/project/TopologyListContainer.js | 4 +++- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index b5bade98..1b539b8f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -6,11 +6,12 @@ import { addPortfolio, deletePortfolio } from '../../../../redux/actions/portfol import { getState } from '../../../../util/state-utils' import { setCurrentTopology } from '../../../../redux/actions/topology/building' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { usePortfolios } from '../../../../data/project' +import { useActivePortfolioId, useActiveProjectId, usePortfolios, useProject } from '../../../../data/project' const PortfolioListContainer = () => { const router = useRouter() const { project: currentProjectId, portfolio: currentPortfolioId } = router.query + const { data: currentProject } = useProject(currentProjectId) const portfolios = usePortfolios(currentProjectId) const dispatch = useDispatch() @@ -24,7 +25,7 @@ const PortfolioListContainer = () => { if (id) { const state = await getState(dispatch) dispatch(deletePortfolio(id)) - dispatch(setCurrentTopology(state.objects.project[currentProjectId].topologyIds[0])) + dispatch(setCurrentTopology(currentProject.topologyIds[0])) await router.push(`/projects/${currentProjectId}`) } }, diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 0eb61026..c474c56e 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -7,11 +7,8 @@ import NewScenarioModalComponent from '../../../../components/modals/custom-comp import { useProjectTopologies } from '../../../../data/topology' import { useScenarios } from '../../../../data/project' import { useSchedulers, useTraces } from '../../../../data/experiments' -import { useRouter } from 'next/router' const ScenarioListContainer = ({ portfolioId }) => { - const router = useRouter() - const { project: currentProjectId } = router.query const scenarios = useScenarios(portfolioId) const topologies = useProjectTopologies() const traces = useTraces() @@ -23,7 +20,6 @@ const ScenarioListContainer = ({ portfolioId }) => { const onNewScenario = (currentPortfolioId) => { setVisible(true) } - const onChooseScenario = (portfolioId, scenarioId) => {} const onDeleteScenario = (id) => { if (id) { dispatch(deleteScenario(id)) @@ -67,7 +63,7 @@ const ScenarioListContainer = ({ portfolioId }) => { } ScenarioListContainer.propTypes = { - portfolioId: PropTypes.string.isRequired, + portfolioId: PropTypes.string, } export default ScenarioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 69367b5f..55f8bd00 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -6,11 +6,13 @@ import { useRouter } from 'next/router' import { addTopology, deleteTopology } from '../../../../redux/actions/topologies' import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' import { useActiveTopology, useProjectTopologies } from '../../../../data/topology' +import { useProject } from '../../../../data/project' const TopologyListContainer = () => { const dispatch = useDispatch() const router = useRouter() const { project: currentProjectId } = router.query + const { data: currentProject } = useProject(currentProjectId) const topologies = useProjectTopologies() const currentTopologyId = useActiveTopology()?._id const [isVisible, setVisible] = useState(false) @@ -22,7 +24,7 @@ const TopologyListContainer = () => { const onDeleteTopology = async (id) => { if (id) { dispatch(deleteTopology(id)) - dispatch(setCurrentTopology(state.objects.project[currentProjectId].topologyIds[0])) + dispatch(setCurrentTopology(currentProject.topologyIds[0])) await router.push(`/projects/${currentProjectId}`) } } -- cgit v1.2.3 From d28a2f194a75eb86095485ae4f88be349bcc18b6 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 16:36:54 +0200 Subject: ui: Fetch schedulers and traces using React Query This change updates the OpenDC frontend to fetch schedulers and traces using React Query, removing its dependency on Redux. --- .../src/containers/app/sidebars/project/ScenarioListContainer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index c474c56e..7acc13ee 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -11,8 +11,8 @@ import { useSchedulers, useTraces } from '../../../../data/experiments' const ScenarioListContainer = ({ portfolioId }) => { const scenarios = useScenarios(portfolioId) const topologies = useProjectTopologies() - const traces = useTraces() - const schedulers = useSchedulers() + const traces = useTraces().data ?? [] + const schedulers = useSchedulers().data ?? [] const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) -- cgit v1.2.3 From 9c8a987556d0fb0cdf0eb67e0c191a8dcc5593b9 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 17:30:15 +0200 Subject: ui: Fetch scenarios and portfolios using React Query --- .../app/results/PortfolioResultsContainer.js | 27 +++--------- .../app/sidebars/project/PortfolioListContainer.js | 40 +++++++++++------- .../app/sidebars/project/ScenarioListContainer.js | 48 +++++++++++++++------- 3 files changed, 64 insertions(+), 51 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js index ce7d5514..f9a380cb 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js @@ -1,32 +1,15 @@ import React from 'react' -import { useSelector } from 'react-redux' import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' import { useRouter } from 'next/router' +import { usePortfolio, useScenarios } from '../../../data/project' const PortfolioResultsContainer = (props) => { const router = useRouter() const { portfolio: currentPortfolioId } = router.query - const { scenarios, portfolio } = useSelector((state) => { - if ( - !currentPortfolioId || - !state.objects.portfolio[currentPortfolioId] || - state.objects.portfolio[currentPortfolioId].scenarioIds - .map((scenarioId) => state.objects.scenario[scenarioId]) - .some((s) => s === undefined) - ) { - return { - portfolio: undefined, - scenarios: [], - } - } - - return { - portfolio: state.objects.portfolio[currentPortfolioId], - scenarios: state.objects.portfolio[currentPortfolioId].scenarioIds.map( - (scenarioId) => state.objects.scenario[scenarioId] - ), - } - }) + const { data: portfolio } = usePortfolio(currentPortfolioId) + const scenarios = useScenarios(portfolio?.scenarioIds ?? []) + .filter((res) => res.data) + .map((res) => res.data) return } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index 1b539b8f..01183724 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -2,17 +2,36 @@ import React, { useState } from 'react' import { useDispatch } from 'react-redux' import { useRouter } from 'next/router' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' -import { addPortfolio, deletePortfolio } from '../../../../redux/actions/portfolios' -import { getState } from '../../../../util/state-utils' -import { setCurrentTopology } from '../../../../redux/actions/topology/building' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { useActivePortfolioId, useActiveProjectId, usePortfolios, useProject } from '../../../../data/project' +import { usePortfolios, useProject } from '../../../../data/project' +import { useMutation, useQueryClient } from 'react-query' +import { addPortfolio, deletePortfolio } from '../../../../api/portfolios' +import { useAuth } from '../../../../auth' const PortfolioListContainer = () => { const router = useRouter() const { project: currentProjectId, portfolio: currentPortfolioId } = router.query const { data: currentProject } = useProject(currentProjectId) - const portfolios = usePortfolios(currentProjectId) + const portfolios = usePortfolios(currentProject?.portfolioIds ?? []) + .filter((res) => res.data) + .map((res) => res.data) + + const auth = useAuth() + const queryClient = useQueryClient() + const addMutation = useMutation((data) => addPortfolio(auth, data), { + onSuccess: async (result) => { + await queryClient.invalidateQueries(['projects', currentProjectId]) + }, + }) + const deleteMutation = useMutation((id) => deletePortfolio(auth, id), { + onSuccess: async (result) => { + queryClient.setQueryData(['projects', currentProjectId], (old) => ({ + ...old, + portfolioIds: old.portfolioIds.filter((id) => id !== result._id), + })) + queryClient.removeQueries(['portfolios', result._id]) + }, + }) const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) @@ -23,21 +42,14 @@ const PortfolioListContainer = () => { }, onDeletePortfolio: async (id) => { if (id) { - const state = await getState(dispatch) - dispatch(deletePortfolio(id)) - dispatch(setCurrentTopology(currentProject.topologyIds[0])) + await deleteMutation.mutateAsync(id) await router.push(`/projects/${currentProjectId}`) } }, } const callback = (name, targets) => { if (name) { - dispatch( - addPortfolio(currentProjectId, { - name, - targets, - }) - ) + addMutation.mutate({ projectId: currentProjectId, name, targets }) } setVisible(false) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 7acc13ee..6bfc8599 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -1,20 +1,40 @@ import PropTypes from 'prop-types' import React, { useState } from 'react' -import { useDispatch } from 'react-redux' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' -import { addScenario, deleteScenario } from '../../../../redux/actions/scenarios' import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' import { useProjectTopologies } from '../../../../data/topology' -import { useScenarios } from '../../../../data/project' +import { usePortfolio, useScenarios } from '../../../../data/project' import { useSchedulers, useTraces } from '../../../../data/experiments' +import { useAuth } from '../../../../auth' +import { useMutation, useQueryClient } from 'react-query' +import { addScenario, deleteScenario } from '../../../../api/scenarios' const ScenarioListContainer = ({ portfolioId }) => { - const scenarios = useScenarios(portfolioId) + const { data: portfolio } = usePortfolio(portfolioId) + const scenarios = useScenarios(portfolio?.scenarioIds ?? []) + .filter((res) => res.data) + .map((res) => res.data) const topologies = useProjectTopologies() const traces = useTraces().data ?? [] const schedulers = useSchedulers().data ?? [] - const dispatch = useDispatch() + const auth = useAuth() + const queryClient = useQueryClient() + const addMutation = useMutation((data) => addScenario(auth, data), { + onSuccess: async (result) => { + await queryClient.invalidateQueries(['portfolios', portfolioId]) + }, + }) + const deleteMutation = useMutation((id) => deleteScenario(auth, id), { + onSuccess: async (result) => { + queryClient.setQueryData(['portfolios', portfolioId], (old) => ({ + ...old, + scenarioIds: old.scenarioIds.filter((id) => id !== result._id), + })) + queryClient.removeQueries(['scenarios', result._id]) + }, + }) + const [isVisible, setVisible] = useState(false) const onNewScenario = (currentPortfolioId) => { @@ -22,20 +42,18 @@ const ScenarioListContainer = ({ portfolioId }) => { } const onDeleteScenario = (id) => { if (id) { - dispatch(deleteScenario(id)) + deleteMutation.mutate(id) } } const callback = (name, portfolioId, trace, topology, operational) => { if (name) { - dispatch( - addScenario({ - portfolioId, - name, - trace, - topology, - operational, - }) - ) + addMutation.mutate({ + portfolioId, + name, + trace, + topology, + operational, + }) } setVisible(false) -- cgit v1.2.3 From 02a2f0f89cb1f39a5f8856bca1971a4e1b12374f Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 7 Jul 2021 20:13:30 +0200 Subject: ui: Use React Query defaults to reduce duplication --- .../app/sidebars/project/PortfolioListContainer.js | 28 +++----------- .../app/sidebars/project/ScenarioListContainer.js | 43 ++++++---------------- .../app/sidebars/project/TopologyListContainer.js | 14 ++++--- 3 files changed, 26 insertions(+), 59 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index 01183724..1fb88253 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -1,12 +1,9 @@ import React, { useState } from 'react' -import { useDispatch } from 'react-redux' import { useRouter } from 'next/router' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' import { usePortfolios, useProject } from '../../../../data/project' -import { useMutation, useQueryClient } from 'react-query' -import { addPortfolio, deletePortfolio } from '../../../../api/portfolios' -import { useAuth } from '../../../../auth' +import { useMutation } from 'react-query' const PortfolioListContainer = () => { const router = useRouter() @@ -16,24 +13,9 @@ const PortfolioListContainer = () => { .filter((res) => res.data) .map((res) => res.data) - const auth = useAuth() - const queryClient = useQueryClient() - const addMutation = useMutation((data) => addPortfolio(auth, data), { - onSuccess: async (result) => { - await queryClient.invalidateQueries(['projects', currentProjectId]) - }, - }) - const deleteMutation = useMutation((id) => deletePortfolio(auth, id), { - onSuccess: async (result) => { - queryClient.setQueryData(['projects', currentProjectId], (old) => ({ - ...old, - portfolioIds: old.portfolioIds.filter((id) => id !== result._id), - })) - queryClient.removeQueries(['portfolios', result._id]) - }, - }) + const { mutate: addPortfolio } = useMutation('addPortfolio') + const { mutateAsync: deletePortfolio } = useMutation('deletePortfolio') - const dispatch = useDispatch() const [isVisible, setVisible] = useState(false) const actions = { onNewPortfolio: () => setVisible(true), @@ -42,14 +24,14 @@ const PortfolioListContainer = () => { }, onDeletePortfolio: async (id) => { if (id) { - await deleteMutation.mutateAsync(id) + await deletePortfolio(id) await router.push(`/projects/${currentProjectId}`) } }, } const callback = (name, targets) => { if (name) { - addMutation.mutate({ projectId: currentProjectId, name, targets }) + addPortfolio({ projectId: currentProjectId, name, targets }) } setVisible(false) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 6bfc8599..62761583 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -2,52 +2,33 @@ import PropTypes from 'prop-types' import React, { useState } from 'react' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' -import { useProjectTopologies } from '../../../../data/topology' -import { usePortfolio, useScenarios } from '../../../../data/project' +import { useTopologies } from '../../../../data/topology' +import { usePortfolio, useProject, useScenarios } from '../../../../data/project' import { useSchedulers, useTraces } from '../../../../data/experiments' -import { useAuth } from '../../../../auth' -import { useMutation, useQueryClient } from 'react-query' -import { addScenario, deleteScenario } from '../../../../api/scenarios' +import { useMutation } from 'react-query' const ScenarioListContainer = ({ portfolioId }) => { const { data: portfolio } = usePortfolio(portfolioId) + const { data: project } = useProject(portfolio?.projectId) const scenarios = useScenarios(portfolio?.scenarioIds ?? []) .filter((res) => res.data) .map((res) => res.data) - const topologies = useProjectTopologies() + const topologies = useTopologies(project?.topologyIds ?? []) + .filter((res) => res.data) + .map((res) => res.data) const traces = useTraces().data ?? [] const schedulers = useSchedulers().data ?? [] - const auth = useAuth() - const queryClient = useQueryClient() - const addMutation = useMutation((data) => addScenario(auth, data), { - onSuccess: async (result) => { - await queryClient.invalidateQueries(['portfolios', portfolioId]) - }, - }) - const deleteMutation = useMutation((id) => deleteScenario(auth, id), { - onSuccess: async (result) => { - queryClient.setQueryData(['portfolios', portfolioId], (old) => ({ - ...old, - scenarioIds: old.scenarioIds.filter((id) => id !== result._id), - })) - queryClient.removeQueries(['scenarios', result._id]) - }, - }) + const { mutate: addScenario } = useMutation('addScenario') + const { mutate: deleteScenario } = useMutation('deleteScenario') const [isVisible, setVisible] = useState(false) - const onNewScenario = (currentPortfolioId) => { - setVisible(true) - } - const onDeleteScenario = (id) => { - if (id) { - deleteMutation.mutate(id) - } - } + const onNewScenario = () => setVisible(true) + const onDeleteScenario = (id) => id && deleteScenario(id) const callback = (name, portfolioId, trace, topology, operational) => { if (name) { - addMutation.mutate({ + addScenario({ portfolioId, name, trace, diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 55f8bd00..78db166c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -3,28 +3,32 @@ import { useDispatch } from 'react-redux' import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' import { setCurrentTopology } from '../../../../redux/actions/topology/building' import { useRouter } from 'next/router' -import { addTopology, deleteTopology } from '../../../../redux/actions/topologies' +import { addTopology } from '../../../../redux/actions/topologies' import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' -import { useActiveTopology, useProjectTopologies } from '../../../../data/topology' +import { useActiveTopology, useTopologies } from '../../../../data/topology' import { useProject } from '../../../../data/project' +import { useMutation } from 'react-query' const TopologyListContainer = () => { const dispatch = useDispatch() const router = useRouter() const { project: currentProjectId } = router.query const { data: currentProject } = useProject(currentProjectId) - const topologies = useProjectTopologies() + const topologies = useTopologies(currentProject?.topologyIds ?? []) + .filter((res) => res.data) + .map((res) => res.data) const currentTopologyId = useActiveTopology()?._id const [isVisible, setVisible] = useState(false) + const { mutate: deleteTopology } = useMutation('deleteTopology') + const onChooseTopology = async (id) => { dispatch(setCurrentTopology(id)) await router.push(`/projects/${currentProjectId}/topologies/${id}`) } const onDeleteTopology = async (id) => { if (id) { - dispatch(deleteTopology(id)) - dispatch(setCurrentTopology(currentProject.topologyIds[0])) + deleteTopology(id) await router.push(`/projects/${currentProjectId}`) } } -- cgit v1.2.3 From 29196842447d841d2e21462adcfc8c2ed1d851ad Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 8 Jul 2021 13:15:28 +0200 Subject: ui: Simplify normalization of topology This change updates the OpenDC frontend to use the normalizr library for normalizing the user topology. --- .../containers/app/map/RackEnergyFillContainer.js | 12 ++++---- .../containers/app/map/RackSpaceFillContainer.js | 2 +- .../src/containers/app/map/RoomContainer.js | 5 ++++ .../src/containers/app/map/TileContainer.js | 2 +- .../src/containers/app/map/WallContainer.js | 2 +- .../containers/app/map/layers/ObjectHoverLayer.js | 4 +-- .../containers/app/map/layers/RoomHoverLayer.js | 6 ++-- .../app/sidebars/project/ScenarioListContainer.js | 2 +- .../app/sidebars/project/TopologyListContainer.js | 2 +- .../topology/machine/MachineSidebarContainer.js | 2 +- .../app/sidebars/topology/machine/UnitContainer.js | 14 --------- .../sidebars/topology/machine/UnitListContainer.js | 33 ++++++++++++++++------ .../sidebars/topology/rack/EmptySlotContainer.js | 12 -------- .../app/sidebars/topology/rack/MachineContainer.js | 14 --------- .../sidebars/topology/rack/MachineListContainer.js | 27 ++++++++++++++---- .../sidebars/topology/rack/RackNameContainer.js | 2 +- .../sidebars/topology/rack/RackSidebarContainer.js | 2 +- 17 files changed, 71 insertions(+), 72 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js index 00d3152f..d22317a5 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js @@ -5,17 +5,17 @@ import RackFillBar from '../../../components/app/map/elements/RackFillBar' const RackSpaceFillContainer = (props) => { const state = useSelector((state) => { let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[props.tileId].rackId] - const machineIds = rack.machineIds + const rack = state.objects.rack[state.objects.tile[props.tileId].rack] + const machineIds = rack.machines machineIds.forEach((machineId) => { if (machineId !== null) { const machine = state.objects.machine[machineId] - machine.cpuIds.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpuIds.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) - machine.memoryIds.forEach( + machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) + machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) + machine.memories.forEach( (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) ) - machine.storageIds.forEach( + machine.storages.forEach( (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) ) } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js index dc5119fd..8d6f61e0 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js @@ -4,7 +4,7 @@ import RackFillBar from '../../../components/app/map/elements/RackFillBar' const RackSpaceFillContainer = (props) => { const state = useSelector((state) => { - const machineIds = state.objects.rack[state.objects.tile[props.tileId].rackId].machineIds + const machineIds = state.objects.rack[state.objects.tile[props.tileId].rack].machines return { type: 'space', fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js index 52d48317..0a9e1503 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types' import React from 'react' import { useDispatch, useSelector } from 'react-redux' import { goFromBuildingToRoom } from '../../../redux/actions/interaction-level' @@ -15,4 +16,8 @@ const RoomContainer = (props) => { return dispatch(goFromBuildingToRoom(props.roomId))} /> } +RoomContainer.propTypes = { + roomId: PropTypes.string, +} + export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js index f97e89a1..50a2abfd 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js @@ -9,7 +9,7 @@ const TileContainer = (props) => { const dispatch = useDispatch() const onClick = (tile) => { - if (tile.rackId) { + if (tile.rack) { dispatch(goFromRoomToRack(tile._id)) } } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js index 2a469860..67f36396 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js @@ -4,7 +4,7 @@ import WallGroup from '../../../components/app/map/groups/WallGroup' const WallContainer = (props) => { const tiles = useSelector((state) => - state.objects.room[props.roomId].tileIds.map((tileId) => state.objects.tile[tileId]) + state.objects.room[props.roomId].tiles.map((tileId) => state.objects.tile[tileId]) ) return } diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js index 8e934a01..e9a64545 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js @@ -16,10 +16,10 @@ const ObjectHoverLayer = (props) => { } const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tileIds.map((tileId) => state.objects.tile[tileId]) + const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) const tile = findTileWithPosition(tiles, x, y) - return !(tile === null || tile.rackId) + return !(tile === null || tile.rack) }, } }) diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js index 1bfadb6d..4070c766 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js @@ -23,14 +23,14 @@ const RoomHoverLayer = (props) => { .map((id) => Object.assign({}, state.objects.room[id])) .filter( (room) => - state.objects.topology[state.currentTopologyId].roomIds.indexOf(room._id) !== -1 && + state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && room._id !== state.construction.currentRoomInConstruction ) ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tileIds.map((tileId) => state.objects.tile[tileId]) + room.tiles = room.tiles.map((tileId) => state.objects.tile[tileId]) }) - if (newRoom.tileIds.length === 0) { + if (newRoom.tiles.length === 0) { return findPositionInRooms(oldRooms, x, y) === -1 } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index 62761583..fd55582f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -15,7 +15,7 @@ const ScenarioListContainer = ({ portfolioId }) => { .map((res) => res.data) const topologies = useTopologies(project?.topologyIds ?? []) .filter((res) => res.data) - .map((res) => res.data) + .map((res) => ({ _id: res.data._id, name: res.data.name })) const traces = useTraces().data ?? [] const schedulers = useSchedulers().data ?? [] diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 78db166c..55eab23a 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -16,7 +16,7 @@ const TopologyListContainer = () => { const { data: currentProject } = useProject(currentProjectId) const topologies = useTopologies(currentProject?.topologyIds ?? []) .filter((res) => res.data) - .map((res) => res.data) + .map((res) => ({ _id: res.data._id, name: res.data.name })) const currentTopologyId = useActiveTopology()?._id const [isVisible, setVisible] = useState(false) diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js index cb7ec8f9..7553c2fe 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js @@ -5,7 +5,7 @@ import MachineSidebarComponent from '../../../../../components/app/sidebars/topo const MachineSidebarContainer = (props) => { const machineId = useSelector( (state) => - state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ + state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ state.interactionLevel.position - 1 ] ) diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js deleted file mode 100644 index acb16a21..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { deleteUnit } from '../../../../../redux/actions/topology/machine' -import UnitComponent from '../../../../../components/app/sidebars/topology/machine/UnitComponent' - -const UnitContainer = ({ unitId, unitType }) => { - const dispatch = useDispatch() - const unit = useSelector((state) => state.objects[unitType][unitId]) - const onDelete = () => dispatch(deleteUnit(unitType, unitId)) - - return -} - -export default UnitContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js index c5c9444d..cdd7e268 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js @@ -1,17 +1,34 @@ +import PropTypes from 'prop-types' import React from 'react' -import { useSelector } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent' +import { deleteUnit } from '../../../../../redux/actions/topology/machine' -const UnitListContainer = (props) => { - const unitIds = useSelector( - (state) => +const unitMapping = { + cpu: 'cpus', + gpu: 'gpus', + memory: 'memories', + storage: 'storages', +} + +const UnitListContainer = ({ unitType, ...props }) => { + const dispatch = useDispatch() + const units = useSelector((state) => { + const machine = state.objects.machine[ - state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ + state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ state.interactionLevel.position - 1 ] - ][props.unitType + 'Ids'] - ) - return + ] + return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) + }) + const onDelete = (unit, unitType) => dispatch(deleteUnit(unitType, unit._id)) + + return +} + +UnitListContainer.propTypes = { + unitType: PropTypes.string.isRequired, } export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js deleted file mode 100644 index 2134e411..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { addMachine } from '../../../../../redux/actions/topology/rack' -import EmptySlotComponent from '../../../../../components/app/sidebars/topology/rack/EmptySlotComponent' - -const EmptySlotContainer = (props) => { - const dispatch = useDispatch() - const onAdd = () => dispatch(addMachine(props.position)) - return -} - -export default EmptySlotContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js deleted file mode 100644 index 7d8e32c1..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' -import MachineComponent from '../../../../../components/app/sidebars/topology/rack/MachineComponent' - -const MachineContainer = (props) => { - const machine = useSelector((state) => state.objects.machine[props.machineId]) - const dispatch = useDispatch() - return ( - dispatch(goFromRackToMachine(props.position))} machine={machine} /> - ) -} - -export default MachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js index b45300fc..2118d915 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js @@ -1,12 +1,29 @@ -import React from 'react' -import { useSelector } from 'react-redux' +import React, { useMemo } from 'react' +import { useDispatch, useSelector } from 'react-redux' import MachineListComponent from '../../../../../components/app/sidebars/topology/rack/MachineListComponent' +import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' +import { addMachine } from '../../../../../redux/actions/topology/rack' const MachineListContainer = (props) => { - const machineIds = useSelector( - (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds + const rack = useSelector((state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack]) + const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) + const machinesNull = useMemo(() => { + const res = Array(rack.capacity).fill(null) + for (const machine of machines) { + res[machine.position - 1] = machine + } + return res + }, [rack, machines]) + const dispatch = useDispatch() + + return ( + dispatch(addMachine(index))} + onSelect={(index) => dispatch(goFromRackToMachine(index))} + /> ) - return } export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js index eaa1e78e..2c39cf9f 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js @@ -7,7 +7,7 @@ import { editRackName } from '../../../../../redux/actions/topology/rack' const RackNameContainer = () => { const [isVisible, setVisible] = useState(false) const rackName = useSelector( - (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name + (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].name ) const dispatch = useDispatch() const callback = (name) => { diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js index b8fc3bfb..34777125 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js @@ -3,7 +3,7 @@ import { useSelector } from 'react-redux' import RackSidebarComponent from '../../../../../components/app/sidebars/topology/rack/RackSidebarComponent' const RackSidebarContainer = (props) => { - const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rackId) + const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rack) return } -- cgit v1.2.3 From 2c8d675c2cf140eac05988065a9d20fd2773399a Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Thu, 8 Jul 2021 13:36:39 +0200 Subject: ui: Combine fetching of project relations This change updates the OpenDC frontend to combine the fetching of project relations. This means that for a single project, we make only one additional request to retrieve all its topologies. --- .../containers/app/results/PortfolioResultsContainer.js | 7 ++----- .../app/sidebars/project/PortfolioListContainer.js | 7 ++----- .../app/sidebars/project/ScenarioListContainer.js | 17 ++++++++--------- .../app/sidebars/project/TopologyListContainer.js | 10 ++++------ 4 files changed, 16 insertions(+), 25 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js index f9a380cb..a75f15ae 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js @@ -1,16 +1,13 @@ import React from 'react' import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' import { useRouter } from 'next/router' -import { usePortfolio, useScenarios } from '../../../data/project' +import { usePortfolio, usePortfolioScenarios } from '../../../data/project' const PortfolioResultsContainer = (props) => { const router = useRouter() const { portfolio: currentPortfolioId } = router.query const { data: portfolio } = usePortfolio(currentPortfolioId) - const scenarios = useScenarios(portfolio?.scenarioIds ?? []) - .filter((res) => res.data) - .map((res) => res.data) - + const scenarios = usePortfolioScenarios(currentPortfolioId).data ?? [] return } diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js index 1fb88253..60ac666c 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -2,16 +2,13 @@ import React, { useState } from 'react' import { useRouter } from 'next/router' import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { usePortfolios, useProject } from '../../../../data/project' +import { useProjectPortfolios } from '../../../../data/project' import { useMutation } from 'react-query' const PortfolioListContainer = () => { const router = useRouter() const { project: currentProjectId, portfolio: currentPortfolioId } = router.query - const { data: currentProject } = useProject(currentProjectId) - const portfolios = usePortfolios(currentProject?.portfolioIds ?? []) - .filter((res) => res.data) - .map((res) => res.data) + const portfolios = useProjectPortfolios(currentProjectId).data ?? [] const { mutate: addPortfolio } = useMutation('addPortfolio') const { mutateAsync: deletePortfolio } = useMutation('deletePortfolio') diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js index fd55582f..3b68df38 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -2,20 +2,19 @@ import PropTypes from 'prop-types' import React, { useState } from 'react' import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' -import { useTopologies } from '../../../../data/topology' -import { usePortfolio, useProject, useScenarios } from '../../../../data/project' +import { useProjectTopologies } from '../../../../data/topology' +import { usePortfolio, usePortfolioScenarios } from '../../../../data/project' import { useSchedulers, useTraces } from '../../../../data/experiments' import { useMutation } from 'react-query' const ScenarioListContainer = ({ portfolioId }) => { const { data: portfolio } = usePortfolio(portfolioId) - const { data: project } = useProject(portfolio?.projectId) - const scenarios = useScenarios(portfolio?.scenarioIds ?? []) - .filter((res) => res.data) - .map((res) => res.data) - const topologies = useTopologies(project?.topologyIds ?? []) - .filter((res) => res.data) - .map((res) => ({ _id: res.data._id, name: res.data.name })) + const scenarios = usePortfolioScenarios(portfolioId).data ?? [] + const topologies = + useProjectTopologies(portfolio?.projectId).data?.map((topology) => ({ + _id: topology._id, + name: topology.name, + })) ?? [] const traces = useTraces().data ?? [] const schedulers = useSchedulers().data ?? [] diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js index 55eab23a..a2244a30 100644 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -5,18 +5,16 @@ import { setCurrentTopology } from '../../../../redux/actions/topology/building' import { useRouter } from 'next/router' import { addTopology } from '../../../../redux/actions/topologies' import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' -import { useActiveTopology, useTopologies } from '../../../../data/topology' -import { useProject } from '../../../../data/project' +import { useActiveTopology, useProjectTopologies } from '../../../../data/topology' import { useMutation } from 'react-query' const TopologyListContainer = () => { const dispatch = useDispatch() const router = useRouter() const { project: currentProjectId } = router.query - const { data: currentProject } = useProject(currentProjectId) - const topologies = useTopologies(currentProject?.topologyIds ?? []) - .filter((res) => res.data) - .map((res) => ({ _id: res.data._id, name: res.data.name })) + const topologies = + useProjectTopologies(currentProjectId).data?.map((topology) => ({ _id: topology._id, name: topology.name })) ?? + [] const currentTopologyId = useActiveTopology()?._id const [isVisible, setVisible] = useState(false) -- cgit v1.2.3 From 803e13b32cf0ff8b496649fb0a4d6e32400e98a4 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Wed, 14 Jul 2021 22:23:40 +0200 Subject: feat(ui): Migrate to PatternFly 4 design framework This change is a rewrite of the existing OpenDC frontend in order to migrate to the PatternFly 4 design framework. PatternFly is used by Red Hat for various computing related services such as OpenShift, Red Hat Virtualization and Cockpit. Since their design requirements are very similar to those of OpenDC (modeling computing services), migrating to PatternFly 4 allows us to re-use design choices from these services. See https://www.patternfly.org/v4/ for more information about PatternFly. --- .../src/containers/app/map/GrayContainer.js | 12 ---- .../src/containers/app/map/MapStage.js | 26 --------- .../src/containers/app/map/RackContainer.js | 10 ---- .../containers/app/map/RackEnergyFillContainer.js | 32 ----------- .../containers/app/map/RackSpaceFillContainer.js | 16 ------ .../src/containers/app/map/RoomContainer.js | 23 -------- .../src/containers/app/map/TileContainer.js | 19 ------ .../src/containers/app/map/TopologyContainer.js | 13 ----- .../src/containers/app/map/WallContainer.js | 12 ---- .../app/map/controls/ScaleIndicatorContainer.js | 10 ---- .../app/map/controls/ZoomControlContainer.js | 13 ----- .../src/containers/app/map/layers/MapLayer.js | 11 ---- .../containers/app/map/layers/ObjectHoverLayer.js | 32 ----------- .../containers/app/map/layers/RoomHoverLayer.js | 45 --------------- .../app/results/PortfolioResultsContainer.js | 14 ----- .../app/sidebars/project/PortfolioListContainer.js | 48 ---------------- .../sidebars/project/ProjectSidebarContainer.js | 11 ---- .../app/sidebars/project/ScenarioListContainer.js | 67 ---------------------- .../app/sidebars/project/TopologyListContainer.js | 67 ---------------------- .../sidebars/topology/TopologySidebarContainer.js | 10 ---- .../topology/building/BuildingSidebarContainer.js | 5 -- .../building/NewRoomConstructionContainer.js | 28 --------- .../topology/machine/BackToRackContainer.js | 11 ---- .../topology/machine/DeleteMachineContainer.js | 34 ----------- .../topology/machine/MachineNameContainer.js | 9 --- .../topology/machine/MachineSidebarContainer.js | 15 ----- .../sidebars/topology/machine/UnitAddContainer.js | 15 ----- .../sidebars/topology/machine/UnitListContainer.js | 34 ----------- .../sidebars/topology/machine/UnitTabsContainer.js | 5 -- .../sidebars/topology/rack/AddPrefabContainer.js | 11 ---- .../sidebars/topology/rack/BackToRoomContainer.js | 11 ---- .../sidebars/topology/rack/DeleteRackContainer.js | 34 ----------- .../sidebars/topology/rack/MachineListContainer.js | 29 ---------- .../sidebars/topology/rack/RackNameContainer.js | 33 ----------- .../sidebars/topology/rack/RackSidebarContainer.js | 10 ---- .../topology/room/BackToBuildingContainer.js | 12 ---- .../sidebars/topology/room/DeleteRoomContainer.js | 34 ----------- .../sidebars/topology/room/EditRoomContainer.js | 35 ----------- .../topology/room/RackConstructionContainer.js | 24 -------- .../sidebars/topology/room/RoomNameContainer.js | 31 ---------- .../sidebars/topology/room/RoomSidebarContainer.js | 10 ---- 41 files changed, 921 deletions(-) delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js delete mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js (limited to 'opendc-web/opendc-web-ui/src/containers/app') diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js deleted file mode 100644 index bac24c8b..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../redux/actions/interaction-level' -import GrayLayer from '../../../components/app/map/elements/GrayLayer' - -const GrayContainer = () => { - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - return -} - -export default GrayContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js deleted file mode 100644 index 91ceb35d..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { setMapDimensions, setMapPositionWithBoundsCheck, zoomInOnPosition } from '../../../redux/actions/map' -import MapStageComponent from '../../../components/app/map/MapStageComponent' -import { useMapDimensions, useMapPosition } from '../../../data/map' - -const MapStage = () => { - const position = useMapPosition() - const dimensions = useMapDimensions() - const dispatch = useDispatch() - const zoomInOnPositionA = (zoomIn, x, y) => dispatch(zoomInOnPosition(zoomIn, x, y)) - const setMapPositionWithBoundsCheckA = (x, y) => dispatch(setMapPositionWithBoundsCheck(x, y)) - const setMapDimensionsA = (width, height) => dispatch(setMapDimensions(width, height)) - - return ( - - ) -} - -export default MapStage diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js deleted file mode 100644 index e5af5117..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackGroup from '../../../components/app/map/groups/RackGroup' - -const RackContainer = ({ tile }) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - return -} - -export default RackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js deleted file mode 100644 index d22317a5..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackFillBar from '../../../components/app/map/elements/RackFillBar' - -const RackSpaceFillContainer = (props) => { - const state = useSelector((state) => { - let energyConsumptionTotal = 0 - const rack = state.objects.rack[state.objects.tile[props.tileId].rack] - const machineIds = rack.machines - machineIds.forEach((machineId) => { - if (machineId !== null) { - const machine = state.objects.machine[machineId] - machine.cpus.forEach((id) => (energyConsumptionTotal += state.objects.cpu[id].energyConsumptionW)) - machine.gpus.forEach((id) => (energyConsumptionTotal += state.objects.gpu[id].energyConsumptionW)) - machine.memories.forEach( - (id) => (energyConsumptionTotal += state.objects.memory[id].energyConsumptionW) - ) - machine.storages.forEach( - (id) => (energyConsumptionTotal += state.objects.storage[id].energyConsumptionW) - ) - } - }) - - return { - type: 'energy', - fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), - } - }) - return -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js deleted file mode 100644 index 8d6f61e0..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackFillBar from '../../../components/app/map/elements/RackFillBar' - -const RackSpaceFillContainer = (props) => { - const state = useSelector((state) => { - const machineIds = state.objects.rack[state.objects.tile[props.tileId].rack].machines - return { - type: 'space', - fillFraction: machineIds.filter((id) => id !== null).length / machineIds.length, - } - }) - return -} - -export default RackSpaceFillContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js deleted file mode 100644 index 0a9e1503..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js +++ /dev/null @@ -1,23 +0,0 @@ -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 '../../../components/app/map/groups/RoomGroup' - -const RoomContainer = (props) => { - const state = useSelector((state) => { - return { - interactionLevel: state.interactionLevel, - currentRoomInConstruction: state.construction.currentRoomInConstruction, - room: state.objects.room[props.roomId], - } - }) - const dispatch = useDispatch() - return dispatch(goFromBuildingToRoom(props.roomId))} /> -} - -RoomContainer.propTypes = { - roomId: PropTypes.string, -} - -export default RoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js deleted file mode 100644 index 50a2abfd..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js +++ /dev/null @@ -1,19 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { goFromRoomToRack } from '../../../redux/actions/interaction-level' -import TileGroup from '../../../components/app/map/groups/TileGroup' - -const TileContainer = (props) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - const tile = useSelector((state) => state.objects.tile[props.tileId]) - - const dispatch = useDispatch() - const onClick = (tile) => { - if (tile.rack) { - dispatch(goFromRoomToRack(tile._id)) - } - } - return -} - -export default TileContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js deleted file mode 100644 index e7ab3c72..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' -import { useActiveTopology } from '../../../data/topology' - -const TopologyContainer = () => { - const topology = useActiveTopology() - const interactionLevel = useSelector((state) => state.interactionLevel) - - return -} - -export default TopologyContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js deleted file mode 100644 index 67f36396..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import WallGroup from '../../../components/app/map/groups/WallGroup' - -const WallContainer = (props) => { - const tiles = useSelector((state) => - state.objects.room[props.roomId].tiles.map((tileId) => state.objects.tile[tileId]) - ) - return -} - -export default WallContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js deleted file mode 100644 index a10eea22..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' -import { useMapScale } from '../../../../data/map' - -const ScaleIndicatorContainer = (props) => { - const scale = useMapScale() - return -} - -export default ScaleIndicatorContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js deleted file mode 100644 index a39c6077..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { zoomInOnCenter } from '../../../../redux/actions/map' -import ZoomControlComponent from '../../../../components/app/map/controls/ZoomControlComponent' -import { useMapScale } from '../../../../data/map' - -const ZoomControlContainer = () => { - const dispatch = useDispatch() - const scale = useMapScale() - return dispatch(zoomInOnCenter(zoomIn))} /> -} - -export default ZoomControlContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js deleted file mode 100644 index 633ebcc7..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import MapLayerComponent from '../../../../components/app/map/layers/MapLayerComponent' -import { useMapPosition, useMapScale } from '../../../../data/map' - -const MapLayer = (props) => { - const position = useMapPosition() - const scale = useMapScale() - return -} - -export default MapLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js deleted file mode 100644 index e9a64545..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addRackToTile } from '../../../../redux/actions/topology/room' -import ObjectHoverLayerComponent from '../../../../components/app/map/layers/ObjectHoverLayerComponent' -import { findTileWithPosition } from '../../../../util/tile-calculations' - -const ObjectHoverLayer = (props) => { - const state = useSelector((state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.inRackConstructionMode, - isValid: (x, y) => { - if (state.interactionLevel.mode !== 'ROOM') { - return false - } - - const currentRoom = state.objects.room[state.interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => state.objects.tile[tileId]) - const tile = findTileWithPosition(tiles, x, y) - - return !(tile === null || tile.rack) - }, - } - }) - - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(addRackToTile(x, y)) - return -} - -export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js deleted file mode 100644 index 4070c766..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js +++ /dev/null @@ -1,45 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { toggleTileAtLocation } from '../../../../redux/actions/topology/building' -import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' -import { - deriveValidNextTilePositions, - findPositionInPositions, - findPositionInRooms, -} from '../../../../util/tile-calculations' - -const RoomHoverLayer = (props) => { - const dispatch = useDispatch() - const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) - - const state = useSelector((state) => { - return { - mapPosition: state.map.position, - mapScale: state.map.scale, - isEnabled: () => state.construction.currentRoomInConstruction !== '-1', - isValid: (x, y) => { - const newRoom = Object.assign({}, state.objects.room[state.construction.currentRoomInConstruction]) - const oldRooms = Object.keys(state.objects.room) - .map((id) => Object.assign({}, state.objects.room[id])) - .filter( - (room) => - state.objects.topology[state.currentTopologyId].rooms.indexOf(room._id) !== -1 && - room._id !== state.construction.currentRoomInConstruction - ) - - ;[...oldRooms, newRoom].forEach((room) => { - room.tiles = room.tiles.map((tileId) => state.objects.tile[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 -} - -export default RoomHoverLayer diff --git a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js deleted file mode 100644 index a75f15ae..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import PortfolioResultsComponent from '../../../components/app/results/PortfolioResultsComponent' -import { useRouter } from 'next/router' -import { usePortfolio, usePortfolioScenarios } from '../../../data/project' - -const PortfolioResultsContainer = (props) => { - const router = useRouter() - const { portfolio: currentPortfolioId } = router.query - const { data: portfolio } = usePortfolio(currentPortfolioId) - const scenarios = usePortfolioScenarios(currentPortfolioId).data ?? [] - return -} - -export default PortfolioResultsContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js deleted file mode 100644 index 60ac666c..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, { useState } from 'react' -import { useRouter } from 'next/router' -import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent' -import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent' -import { useProjectPortfolios } from '../../../../data/project' -import { useMutation } from 'react-query' - -const PortfolioListContainer = () => { - const router = useRouter() - const { project: currentProjectId, portfolio: currentPortfolioId } = router.query - const portfolios = useProjectPortfolios(currentProjectId).data ?? [] - - const { mutate: addPortfolio } = useMutation('addPortfolio') - const { mutateAsync: deletePortfolio } = useMutation('deletePortfolio') - - const [isVisible, setVisible] = useState(false) - const actions = { - onNewPortfolio: () => setVisible(true), - onChoosePortfolio: async (portfolioId) => { - await router.push(`/projects/${currentProjectId}/portfolios/${portfolioId}`) - }, - onDeletePortfolio: async (id) => { - if (id) { - await deletePortfolio(id) - await router.push(`/projects/${currentProjectId}`) - } - }, - } - const callback = (name, targets) => { - if (name) { - addPortfolio({ projectId: currentProjectId, name, targets }) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default PortfolioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js deleted file mode 100644 index 06c7f0f7..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useRouter } from 'next/router' -import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' -import { isCollapsible } from '../../../../util/sidebar-space' - -const ProjectSidebarContainer = (props) => { - const router = useRouter() - return -} - -export default ProjectSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js deleted file mode 100644 index 3b68df38..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js +++ /dev/null @@ -1,67 +0,0 @@ -import PropTypes from 'prop-types' -import React, { useState } from 'react' -import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent' -import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent' -import { useProjectTopologies } from '../../../../data/topology' -import { usePortfolio, usePortfolioScenarios } from '../../../../data/project' -import { useSchedulers, useTraces } from '../../../../data/experiments' -import { useMutation } from 'react-query' - -const ScenarioListContainer = ({ portfolioId }) => { - const { data: portfolio } = usePortfolio(portfolioId) - const scenarios = usePortfolioScenarios(portfolioId).data ?? [] - const topologies = - useProjectTopologies(portfolio?.projectId).data?.map((topology) => ({ - _id: topology._id, - name: topology.name, - })) ?? [] - const traces = useTraces().data ?? [] - const schedulers = useSchedulers().data ?? [] - - const { mutate: addScenario } = useMutation('addScenario') - const { mutate: deleteScenario } = useMutation('deleteScenario') - - const [isVisible, setVisible] = useState(false) - - const onNewScenario = () => setVisible(true) - const onDeleteScenario = (id) => id && deleteScenario(id) - const callback = (name, portfolioId, trace, topology, operational) => { - if (name) { - addScenario({ - portfolioId, - name, - trace, - topology, - operational, - }) - } - - setVisible(false) - } - - return ( - <> - - s._id)} - traces={traces} - schedulers={schedulers} - topologies={topologies} - callback={callback} - /> - - ) -} - -ScenarioListContainer.propTypes = { - portfolioId: PropTypes.string, -} - -export default ScenarioListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js deleted file mode 100644 index a2244a30..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js +++ /dev/null @@ -1,67 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent' -import { setCurrentTopology } from '../../../../redux/actions/topology/building' -import { useRouter } from 'next/router' -import { addTopology } from '../../../../redux/actions/topologies' -import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent' -import { useActiveTopology, useProjectTopologies } from '../../../../data/topology' -import { useMutation } from 'react-query' - -const TopologyListContainer = () => { - const dispatch = useDispatch() - const router = useRouter() - const { project: currentProjectId } = router.query - const topologies = - useProjectTopologies(currentProjectId).data?.map((topology) => ({ _id: topology._id, name: topology.name })) ?? - [] - const currentTopologyId = useActiveTopology()?._id - const [isVisible, setVisible] = useState(false) - - const { mutate: deleteTopology } = useMutation('deleteTopology') - - const onChooseTopology = async (id) => { - dispatch(setCurrentTopology(id)) - await router.push(`/projects/${currentProjectId}/topologies/${id}`) - } - const onDeleteTopology = async (id) => { - if (id) { - deleteTopology(id) - await router.push(`/projects/${currentProjectId}`) - } - } - const onCreateTopology = (name) => { - if (name) { - dispatch(addTopology(currentProjectId, name, undefined)) - } - setVisible(false) - } - const onDuplicateTopology = (name, id) => { - if (name) { - dispatch(addTopology(currentProjectId, name, id)) - } - setVisible(false) - } - const onCancel = () => setVisible(false) - - return ( - <> - setVisible(true)} - onDeleteTopology={onDeleteTopology} - /> - - - ) -} - -export default TopologyListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js deleted file mode 100644 index 42c81c65..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import TopologySidebarComponent from '../../../../components/app/sidebars/topology/TopologySidebarComponent' - -const TopologySidebarContainer = (props) => { - const interactionLevel = useSelector((state) => state.interactionLevel) - return -} - -export default TopologySidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js deleted file mode 100644 index a0b52e56..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js +++ /dev/null @@ -1,5 +0,0 @@ -import BuildingSidebarComponent from '../../../../../components/app/sidebars/topology/building/BuildingSidebarComponent' - -const BuildingSidebarContainer = BuildingSidebarComponent - -export default BuildingSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js deleted file mode 100644 index 96f42a44..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { - cancelNewRoomConstruction, - finishNewRoomConstruction, - startNewRoomConstruction, -} from '../../../../../redux/actions/topology/building' -import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent' - -const NewRoomConstructionButton = (props) => { - const currentRoomInConstruction = useSelector((state) => state.construction.currentRoomInConstruction) - - const dispatch = useDispatch() - const actions = { - onStart: () => dispatch(startNewRoomConstruction()), - onFinish: () => dispatch(finishNewRoomConstruction()), - onCancel: () => dispatch(cancelNewRoomConstruction()), - } - return ( - - ) -} - -export default NewRoomConstructionButton diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js deleted file mode 100644 index ea250767..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' -import BackToRackComponent from '../../../../../components/app/sidebars/topology/machine/BackToRackComponent' - -const BackToRackContainer = (props) => { - const dispatch = useDispatch() - return dispatch(goDownOneInteractionLevel())} /> -} - -export default BackToRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js deleted file mode 100644 index 54e406f4..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteMachine } from '../../../../../redux/actions/topology/machine' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' - -const DeleteMachineContainer = () => { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteMachine()) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteMachineContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js deleted file mode 100644 index 9cbb32c5..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' - -const MachineNameContainer = () => { - const position = useSelector((state) => state.interactionLevel.position) - return

Machine at slot {position}

-} - -export default MachineNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js deleted file mode 100644 index 7553c2fe..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import MachineSidebarComponent from '../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent' - -const MachineSidebarContainer = (props) => { - const machineId = useSelector( - (state) => - state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ - state.interactionLevel.position - 1 - ] - ) - return -} - -export default MachineSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js deleted file mode 100644 index 0f85aa76..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { addUnit } from '../../../../../redux/actions/topology/machine' -import UnitAddComponent from '../../../../../components/app/sidebars/topology/machine/UnitAddComponent' - -const UnitAddContainer = (props) => { - const units = useSelector((state) => Object.values(state.objects[props.unitType])) - const dispatch = useDispatch() - - const onAdd = (id) => dispatch(addUnit(props.unitType, id)) - - return -} - -export default UnitAddContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js deleted file mode 100644 index cdd7e268..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import PropTypes from 'prop-types' -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent' -import { deleteUnit } from '../../../../../redux/actions/topology/machine' - -const unitMapping = { - cpu: 'cpus', - gpu: 'gpus', - memory: 'memories', - storage: 'storages', -} - -const UnitListContainer = ({ unitType, ...props }) => { - const dispatch = useDispatch() - const units = useSelector((state) => { - const machine = - state.objects.machine[ - state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].machines[ - state.interactionLevel.position - 1 - ] - ] - return machine[unitMapping[unitType]].map((id) => state.objects[unitType][id]) - }) - const onDelete = (unit, unitType) => dispatch(deleteUnit(unitType, unit._id)) - - return -} - -UnitListContainer.propTypes = { - unitType: PropTypes.string.isRequired, -} - -export default UnitListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js deleted file mode 100644 index 00fe4067..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js +++ /dev/null @@ -1,5 +0,0 @@ -import UnitTabsComponent from '../../../../../components/app/sidebars/topology/machine/UnitTabsComponent' - -const UnitTabsContainer = UnitTabsComponent - -export default UnitTabsContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js deleted file mode 100644 index c2a0fc48..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { addPrefab } from '../../../../../redux/actions/prefabs' -import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent' - -const AddPrefabContainer = (props) => { - const dispatch = useDispatch() - return dispatch(addPrefab('name'))} /> -} - -export default AddPrefabContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js deleted file mode 100644 index a98728a6..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' -import BackToRoomComponent from '../../../../../components/app/sidebars/topology/rack/BackToRoomComponent' - -const BackToRoomContainer = (props) => { - const dispatch = useDispatch() - return dispatch(goDownOneInteractionLevel())} /> -} - -export default BackToRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js deleted file mode 100644 index 4463530e..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRack } from '../../../../../redux/actions/topology/rack' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' - -const DeleteRackContainer = () => { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRack()) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js deleted file mode 100644 index 2118d915..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js +++ /dev/null @@ -1,29 +0,0 @@ -import React, { useMemo } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import MachineListComponent from '../../../../../components/app/sidebars/topology/rack/MachineListComponent' -import { goFromRackToMachine } from '../../../../../redux/actions/interaction-level' -import { addMachine } from '../../../../../redux/actions/topology/rack' - -const MachineListContainer = (props) => { - const rack = useSelector((state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack]) - const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) - const machinesNull = useMemo(() => { - const res = Array(rack.capacity).fill(null) - for (const machine of machines) { - res[machine.position - 1] = machine - } - return res - }, [rack, machines]) - const dispatch = useDispatch() - - return ( - dispatch(addMachine(index))} - onSelect={(index) => dispatch(goFromRackToMachine(index))} - /> - ) -} - -export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js deleted file mode 100644 index 2c39cf9f..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js +++ /dev/null @@ -1,33 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' -import TextInputModal from '../../../../../components/modals/TextInputModal' -import { editRackName } from '../../../../../redux/actions/topology/rack' - -const RackNameContainer = () => { - const [isVisible, setVisible] = useState(false) - const rackName = useSelector( - (state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rack].name - ) - const dispatch = useDispatch() - const callback = (name) => { - if (name) { - dispatch(editRackName(name)) - } - setVisible(false) - } - return ( - <> - setVisible(true)} /> - - - ) -} - -export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js deleted file mode 100644 index 34777125..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RackSidebarComponent from '../../../../../components/app/sidebars/topology/rack/RackSidebarComponent' - -const RackSidebarContainer = (props) => { - const rackId = useSelector((state) => state.objects.tile[state.interactionLevel.tileId].rack) - return -} - -export default RackSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js deleted file mode 100644 index 9fa1e95f..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react' -import { useDispatch } from 'react-redux' -import { goDownOneInteractionLevel } from '../../../../../redux/actions/interaction-level' -import BackToBuildingComponent from '../../../../../components/app/sidebars/topology/room/BackToBuildingComponent' - -const BackToBuildingContainer = () => { - const dispatch = useDispatch() - const onClick = () => dispatch(goDownOneInteractionLevel()) - return -} - -export default BackToBuildingContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js deleted file mode 100644 index 0fbbb036..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js +++ /dev/null @@ -1,34 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch } from 'react-redux' -import { Button } from 'reactstrap' -import ConfirmationModal from '../../../../../components/modals/ConfirmationModal' -import { deleteRoom } from '../../../../../redux/actions/topology/room' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faTrash } from '@fortawesome/free-solid-svg-icons' - -const DeleteRoomContainer = () => { - const dispatch = useDispatch() - const [isVisible, setVisible] = useState(false) - const callback = (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteRoom()) - } - setVisible(false) - } - return ( - <> - - - - ) -} - -export default DeleteRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js deleted file mode 100644 index ec4f586b..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { finishRoomEdit, startRoomEdit } from '../../../../../redux/actions/topology/building' -import { Button } from 'reactstrap' -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faCheck, faPencilAlt } from '@fortawesome/free-solid-svg-icons' - -const EditRoomContainer = () => { - const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) - - const dispatch = useDispatch() - const onEdit = () => dispatch(startRoomEdit()) - const onFinish = () => dispatch(finishRoomEdit()) - - return isEditing ? ( - - ) : ( - - ) -} - -export default EditRoomContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js deleted file mode 100644 index 79584e98..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react' -import { useDispatch, useSelector } from 'react-redux' -import { startRackConstruction, stopRackConstruction } from '../../../../../redux/actions/topology/room' -import RackConstructionComponent from '../../../../../components/app/sidebars/topology/room/RackConstructionComponent' - -const RackConstructionContainer = (props) => { - const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) - const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') - - const dispatch = useDispatch() - const onStart = () => dispatch(startRackConstruction()) - const onStop = () => dispatch(stopRackConstruction()) - return ( - - ) -} - -export default RackConstructionContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js deleted file mode 100644 index 3b35a849..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js +++ /dev/null @@ -1,31 +0,0 @@ -import React, { useState } from 'react' -import { useDispatch, useSelector } from 'react-redux' -import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent' -import TextInputModal from '../../../../../components/modals/TextInputModal' -import { editRoomName } from '../../../../../redux/actions/topology/room' - -const RoomNameContainer = () => { - const [isVisible, setVisible] = useState(false) - const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name) - const dispatch = useDispatch() - const callback = (name) => { - if (name) { - dispatch(editRoomName(name)) - } - setVisible(false) - } - return ( - <> - setVisible(true)} /> - - - ) -} - -export default RoomNameContainer diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js deleted file mode 100644 index 252881a0..00000000 --- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js +++ /dev/null @@ -1,10 +0,0 @@ -import React from 'react' -import { useSelector } from 'react-redux' -import RoomSidebarComponent from '../../../../../components/app/sidebars/topology/room/RoomSidebarComponent' - -const RoomSidebarContainer = (props) => { - const roomId = useSelector((state) => state.interactionLevel.roomId) - return -} - -export default RoomSidebarContainer -- cgit v1.2.3