From cd0b45627f0d8da8c8dc4edde223f3c36e9bcfbf Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 25 Apr 2021 16:01:14 +0200 Subject: build: Migrate to flat project structure This change updates the project structure to become flattened. Previously, the simulator, frontend and API each lived into their own directory. With this change, all modules of the project live in the top-level directory of the repository. This should improve discoverability of modules of the project. --- .../src/containers/app/map/GrayContainer.js | 13 +++++ .../src/containers/app/map/MapStage.js | 22 ++++++++ .../src/containers/app/map/RackContainer.js | 12 +++++ .../containers/app/map/RackEnergyFillContainer.js | 26 +++++++++ .../containers/app/map/RackSpaceFillContainer.js | 14 +++++ .../src/containers/app/map/RoomContainer.js | 21 ++++++++ .../src/containers/app/map/TileContainer.js | 26 +++++++++ .../src/containers/app/map/TopologyContainer.js | 17 ++++++ .../src/containers/app/map/WallContainer.js | 12 +++++ .../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 | 33 ++++++++++++ .../containers/app/map/layers/RoomHoverLayer.js | 46 ++++++++++++++++ .../app/results/PortfolioResultsContainer.js | 28 ++++++++++ .../app/sidebars/project/PortfolioListContainer.js | 45 ++++++++++++++++ .../sidebars/project/ProjectSidebarContainer.js | 10 ++++ .../app/sidebars/project/ScenarioListContainer.js | 41 ++++++++++++++ .../app/sidebars/project/TopologyListContainer.js | 46 ++++++++++++++++ .../sidebars/topology/TopologySidebarContainer.js | 12 +++++ .../topology/building/BuildingSidebarContainer.js | 5 ++ .../building/NewRoomConstructionContainer.js | 25 +++++++++ .../topology/machine/BackToRackContainer.js | 13 +++++ .../topology/machine/DeleteMachineContainer.js | 13 +++++ .../topology/machine/MachineNameContainer.js | 12 +++++ .../topology/machine/MachineSidebarContainer.js | 15 ++++++ .../sidebars/topology/machine/UnitAddContainer.js | 19 +++++++ .../app/sidebars/topology/machine/UnitContainer.js | 20 +++++++ .../sidebars/topology/machine/UnitListContainer.js | 17 ++++++ .../sidebars/topology/machine/UnitTabsContainer.js | 5 ++ .../sidebars/topology/rack/AddPrefabContainer.js | 13 +++++ .../sidebars/topology/rack/BackToRoomContainer.js | 13 +++++ .../sidebars/topology/rack/DeleteRackContainer.js | 13 +++++ .../sidebars/topology/rack/EmptySlotContainer.js | 13 +++++ .../app/sidebars/topology/rack/MachineContainer.js | 19 +++++++ .../sidebars/topology/rack/MachineListContainer.js | 12 +++++ .../sidebars/topology/rack/RackNameContainer.js | 19 +++++++ .../sidebars/topology/rack/RackSidebarContainer.js | 12 +++++ .../topology/room/BackToBuildingContainer.js | 13 +++++ .../sidebars/topology/room/DeleteRoomContainer.js | 13 +++++ .../sidebars/topology/room/EditRoomContainer.js | 21 ++++++++ .../topology/room/RackConstructionContainer.js | 21 ++++++++ .../sidebars/topology/room/RoomNameContainer.js | 19 +++++++ .../sidebars/topology/room/RoomSidebarContainer.js | 12 +++++ .../opendc-web-ui/src/containers/auth/Login.js | 62 ++++++++++++++++++++++ .../opendc-web-ui/src/containers/auth/Logout.js | 13 +++++ .../src/containers/auth/ProfileName.js | 14 +++++ .../src/containers/modals/DeleteMachineModal.js | 35 ++++++++++++ .../src/containers/modals/DeleteProfileModal.js | 35 ++++++++++++ .../src/containers/modals/DeleteRackModal.js | 35 ++++++++++++ .../src/containers/modals/DeleteRoomModal.js | 35 ++++++++++++ .../src/containers/modals/EditRackNameModal.js | 40 ++++++++++++++ .../src/containers/modals/EditRoomNameModal.js | 38 +++++++++++++ .../src/containers/modals/NewPortfolioModal.js | 30 +++++++++++ .../src/containers/modals/NewProjectModal.js | 30 +++++++++++ .../src/containers/modals/NewScenarioModal.js | 50 +++++++++++++++++ .../src/containers/modals/NewTopologyModal.js | 42 +++++++++++++++ .../containers/navigation/AppNavbarContainer.js | 12 +++++ .../src/containers/projects/FilterLink.js | 19 +++++++ .../projects/NewProjectButtonContainer.js | 13 +++++ .../src/containers/projects/ProjectActions.js | 20 +++++++ .../containers/projects/VisibleProjectAuthList.js | 32 +++++++++++ 62 files changed, 1380 insertions(+) create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/auth/Login.js create mode 100644 opendc-web/opendc-web-ui/src/containers/auth/Logout.js create mode 100644 opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js create mode 100644 opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js create mode 100644 opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js (limited to 'opendc-web/opendc-web-ui/src/containers') 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 new file mode 100644 index 00000000..9e4a6969 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/GrayContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..23c920b6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/MapStage.js @@ -0,0 +1,22 @@ +import { connect } 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 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 new file mode 100644 index 00000000..40077608 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackContainer.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import RackGroup from '../../../components/app/map/groups/RackGroup' + +const mapStateToProps = (state) => { + return { + interactionLevel: state.interactionLevel, + } +} + +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 new file mode 100644 index 00000000..53746271 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackEnergyFillContainer.js @@ -0,0 +1,26 @@ +import { connect } 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)) + } + }) + + return { + type: 'energy', + fillFraction: Math.min(1, energyConsumptionTotal / rack.powerCapacityW), + } +} + +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 new file mode 100644 index 00000000..0509a5a5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RackSpaceFillContainer.js @@ -0,0 +1,14 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..91bf4e5d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/RoomContainer.js @@ -0,0 +1,21 @@ +import { connect } 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 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 new file mode 100644 index 00000000..04d6c8d6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TileContainer.js @@ -0,0 +1,26 @@ +import { connect } 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] + + return { + interactionLevel: state.interactionLevel, + tile, + } +} + +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 new file mode 100644 index 00000000..de43a151 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js @@ -0,0 +1,17 @@ +import { connect } from 'react-redux' +import TopologyGroup from '../../../components/app/map/groups/TopologyGroup' + +const mapStateToProps = (state) => { + if (state.currentTopologyId === '-1') { + return {} + } + + return { + topology: state.objects.topology[state.currentTopologyId], + interactionLevel: state.interactionLevel, + } +} + +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 new file mode 100644 index 00000000..67f8a242 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/WallContainer.js @@ -0,0 +1,12 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..fa3b9d22 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ScaleIndicatorContainer.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import ScaleIndicatorComponent from '../../../../components/app/map/controls/ScaleIndicatorComponent' + +const mapStateToProps = (state) => { + return { + scale: state.map.scale, + } +} + +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 new file mode 100644 index 00000000..ddc68cc7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/controls/ZoomControlContainer.js @@ -0,0 +1,19 @@ +import { connect } 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 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 new file mode 100644 index 00000000..8596cb9c --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/MapLayer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..a4927862 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/ObjectHoverLayer.js @@ -0,0 +1,33 @@ +import { connect } 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 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) + }, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onClick: (x, y) => dispatch(addRackToTile(x, y)), + } +} + +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 new file mode 100644 index 00000000..66404f9e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/map/layers/RoomHoverLayer.js @@ -0,0 +1,46 @@ +import { connect } from 'react-redux' +import { toggleTileAtLocation } from '../../../../actions/topology/building' +import RoomHoverLayerComponent from '../../../../components/app/map/layers/RoomHoverLayerComponent' +import { + deriveValidNextTilePositions, + findPositionInPositions, + 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 + ) + + ;[...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 validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles) + return findPositionInPositions(validNextPositions, x, y) !== -1 + }, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onClick: (x, y) => dispatch(toggleTileAtLocation(x, y)), + } +} + +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 new file mode 100644 index 00000000..4b430e54 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/results/PortfolioResultsContainer.js @@ -0,0 +1,28 @@ +import { connect } 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) + ) { + return { + portfolio: undefined, + scenarios: [], + } + } + + return { + portfolio: state.objects.portfolio[state.currentPortfolioId], + scenarios: state.objects.portfolio[state.currentPortfolioId].scenarioIds.map( + (scenarioId) => state.objects.scenario[scenarioId] + ), + } +} + +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 new file mode 100644 index 00000000..b32c8b1d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js @@ -0,0 +1,45 @@ +import { connect } from 'react-redux' +import { withRouter } 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 = [] + } + + return { + currentProjectId: state.currentProjectId, + currentPortfolioId: state.currentPortfolioId, + portfolios, + } +} + +const mapDispatchToProps = (dispatch, ownProps) => { + return { + onNewPortfolio: () => { + dispatch(openNewPortfolioModal()) + }, + onChoosePortfolio: (portfolioId) => { + dispatch(setCurrentPortfolio(portfolioId)) + }, + onDeletePortfolio: async (id) => { + if (id) { + const state = await getState(dispatch) + dispatch(deletePortfolio(id)) + dispatch(setCurrentTopology(state.objects.project[state.currentProjectId].topologyIds[0])) + ownProps.history.push(`/projects/${state.currentProjectId}`) + } + }, + } +} + +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 new file mode 100644 index 00000000..49001099 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ProjectSidebarContainer.js @@ -0,0 +1,10 @@ +import React from 'react' +import { withRouter } from 'react-router-dom' +import ProjectSidebarComponent from '../../../../components/app/sidebars/project/ProjectSidebarComponent' +import { isCollapsible } from '../../../../util/sidebar-space' + +const ProjectSidebarContainer = withRouter(({ location, ...props }) => ( + +)) + +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 new file mode 100644 index 00000000..415e2792 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js @@ -0,0 +1,41 @@ +import { connect } 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 = [] + } + + return { + currentProjectId: state.currentProjectId, + currentScenarioId: state.currentScenarioId, + 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 ScenarioListContainer = connect(mapStateToProps, mapDispatchToProps)(ScenarioListComponent) + +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 new file mode 100644 index 00000000..e1de18f9 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js @@ -0,0 +1,46 @@ +import { connect } 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 { 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 = [] + } + + return { + currentTopologyId: state.currentTopologyId, + topologies, + } +} + +const mapDispatchToProps = (dispatch, ownProps) => { + return { + onChooseTopology: async (id) => { + dispatch(setCurrentTopology(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}`) + } + }, + } +} + +const TopologyListContainer = withRouter(connect(mapStateToProps, mapDispatchToProps)(TopologyListComponent)) + +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 new file mode 100644 index 00000000..fe7c02fd --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/TopologySidebarContainer.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import TopologySidebarComponent from '../../../../components/app/sidebars/topology/TopologySidebarComponent' + +const mapStateToProps = (state) => { + return { + interactionLevel: state.interactionLevel, + } +} + +const TopologySidebarContainer = connect(mapStateToProps)(TopologySidebarComponent) + +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 new file mode 100644 index 00000000..a0b52e56 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000..ea9e9e60 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js @@ -0,0 +1,25 @@ +import { connect } from 'react-redux' +import { + cancelNewRoomConstruction, + finishNewRoomConstruction, + startNewRoomConstruction, +} from '../../../../../actions/topology/building' +import StartNewRoomConstructionComponent from '../../../../../components/app/sidebars/topology/building/NewRoomConstructionComponent' + +const mapStateToProps = (state) => { + return { + currentRoomInConstruction: state.construction.currentRoomInConstruction, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onStart: () => dispatch(startNewRoomConstruction()), + onFinish: () => dispatch(finishNewRoomConstruction()), + onCancel: () => dispatch(cancelNewRoomConstruction()), + } +} + +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 new file mode 100644 index 00000000..24287ab0 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/BackToRackContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..65e683e6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..1cf35b05 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import MachineNameComponent from '../../../../../components/app/sidebars/topology/machine/MachineNameComponent' + +const mapStateToProps = (state) => { + return { + position: state.interactionLevel.position, + } +} + +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 new file mode 100644 index 00000000..b04e3118 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js @@ -0,0 +1,15 @@ +import { connect } from 'react-redux' +import MachineSidebarComponent from '../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent' + +const mapStateToProps = (state) => { + return { + machineId: + state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ + state.interactionLevel.position - 1 + ], + } +} + +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 new file mode 100644 index 00000000..29e48016 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitAddContainer.js @@ -0,0 +1,19 @@ +import { connect } 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 mapDispatchToProps = (dispatch, ownProps) => { + return { + onAdd: (id) => dispatch(addUnit(ownProps.unitType, id)), + } +} + +const UnitAddContainer = connect(mapStateToProps, mapDispatchToProps)(UnitAddComponent) + +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 new file mode 100644 index 00000000..f334f9f2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitContainer.js @@ -0,0 +1,20 @@ +import { connect } 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 mapDispatchToProps = (dispatch, ownProps) => { + return { + onDelete: () => dispatch(deleteUnit(ownProps.unitType, ownProps.index)), + } +} + +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 new file mode 100644 index 00000000..f382ff74 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitListContainer.js @@ -0,0 +1,17 @@ +import { connect } from 'react-redux' +import UnitListComponent from '../../../../../components/app/sidebars/topology/machine/UnitListComponent' + +const mapStateToProps = (state, ownProps) => { + return { + unitIds: + state.objects.machine[ + state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].machineIds[ + state.interactionLevel.position - 1 + ] + ][ownProps.unitType + 'Ids'], + } +} + +const UnitListContainer = connect(mapStateToProps)(UnitListComponent) + +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 new file mode 100644 index 00000000..00fe4067 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js @@ -0,0 +1,5 @@ +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 new file mode 100644 index 00000000..c941e745 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..58c3b082 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..8229a359 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..cf341da9 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..fe12827d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineContainer.js @@ -0,0 +1,19 @@ +import { connect } 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 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 new file mode 100644 index 00000000..bc5a285a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/MachineListContainer.js @@ -0,0 +1,12 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..504dbc61 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js @@ -0,0 +1,19 @@ +import { connect } 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 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 new file mode 100644 index 00000000..453d7e41 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js @@ -0,0 +1,12 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..4c1ab99d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..636fa5c5 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js @@ -0,0 +1,13 @@ +import { connect } 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 = 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 new file mode 100644 index 00000000..d17a45d1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js @@ -0,0 +1,21 @@ +import { connect } 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 mapDispatchToProps = (dispatch) => { + return { + onEdit: () => dispatch(startRoomEdit()), + onFinish: () => dispatch(finishRoomEdit()), + } +} + +const EditRoomContainer = connect(mapStateToProps, mapDispatchToProps)(EditRoomComponent) + +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 new file mode 100644 index 00000000..cd8319de --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RackConstructionContainer.js @@ -0,0 +1,21 @@ +import { connect } 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 mapDispatchToProps = (dispatch) => { + return { + onStart: () => dispatch(startRackConstruction()), + onStop: () => dispatch(stopRackConstruction()), + } +} + +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 new file mode 100644 index 00000000..cab16016 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js @@ -0,0 +1,19 @@ +import { connect } 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 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 new file mode 100644 index 00000000..8c3ca8ab --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import RoomSidebarComponent from '../../../../../components/app/sidebars/topology/room/RoomSidebarComponent' + +const mapStateToProps = (state) => { + return { + roomId: state.interactionLevel.roomId, + } +} + +const RoomSidebarContainer = connect(mapStateToProps)(RoomSidebarComponent) + +export default RoomSidebarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Login.js b/opendc-web/opendc-web-ui/src/containers/auth/Login.js new file mode 100644 index 00000000..2f9726bf --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/auth/Login.js @@ -0,0 +1,62 @@ +import PropTypes from 'prop-types' +import React from 'react' +import GoogleLogin from 'react-google-login' +import { connect } from 'react-redux' +import { logIn } from '../../actions/auth' + +class LoginContainer extends React.Component { + static propTypes = { + visible: PropTypes.bool.isRequired, + onLogin: PropTypes.func.isRequired, + } + + onAuthResponse(response) { + this.props.onLogin({ + email: response.getBasicProfile().getEmail(), + givenName: response.getBasicProfile().getGivenName(), + familyName: response.getBasicProfile().getFamilyName(), + googleId: response.googleId, + authToken: response.getAuthResponse().id_token, + expiresAt: response.getAuthResponse().expires_at, + }) + } + + onAuthFailure(error) { + console.error(error) + } + + render() { + if (!this.props.visible) { + return + } + + return ( + ( + + Login with Google + + )} + > + ) + } +} + +const mapStateToProps = (state, ownProps) => { + return { + visible: ownProps.visible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onLogin: (payload) => dispatch(logIn(payload)), + } +} + +const Login = connect(mapStateToProps, mapDispatchToProps)(LoginContainer) + +export default Login diff --git a/opendc-web/opendc-web-ui/src/containers/auth/Logout.js b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js new file mode 100644 index 00000000..22400381 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/auth/Logout.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux' +import { logOut } from '../../actions/auth' +import LogoutButton from '../../components/navigation/LogoutButton' + +const mapDispatchToProps = (dispatch) => { + return { + onLogout: () => dispatch(logOut()), + } +} + +const Logout = connect(undefined, mapDispatchToProps)(LogoutButton) + +export default Logout diff --git a/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js new file mode 100644 index 00000000..06da75ab --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/auth/ProfileName.js @@ -0,0 +1,14 @@ +import React from 'react' +import { connect } from 'react-redux' + +const mapStateToProps = (state) => { + return { + text: state.auth.givenName + ' ' + state.auth.familyName, + } +} + +const SpanElement = ({ text }) => {text} + +const ProfileName = connect(mapStateToProps)(SpanElement) + +export default ProfileName diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js new file mode 100644 index 00000000..f30febdb --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteMachineModal.js @@ -0,0 +1,35 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeDeleteMachineModal } from '../../actions/modals/topology' +import { deleteMachine } from '../../actions/topology/machine' +import ConfirmationModal from '../../components/modals/ConfirmationModal' + +const DeleteMachineModalComponent = ({ visible, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.deleteMachineModalVisible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteMachine()) + } + dispatch(closeDeleteMachineModal()) + }, + } +} + +const DeleteMachineModal = connect(mapStateToProps, mapDispatchToProps)(DeleteMachineModalComponent) + +export default DeleteMachineModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js new file mode 100644 index 00000000..e7c4014d --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteProfileModal.js @@ -0,0 +1,35 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeDeleteProfileModal } from '../../actions/modals/profile' +import { deleteCurrentUser } from '../../actions/users' +import ConfirmationModal from '../../components/modals/ConfirmationModal' + +const DeleteProfileModalComponent = ({ visible, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.deleteProfileModalVisible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteCurrentUser()) + } + dispatch(closeDeleteProfileModal()) + }, + } +} + +const DeleteProfileModal = connect(mapStateToProps, mapDispatchToProps)(DeleteProfileModalComponent) + +export default DeleteProfileModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js new file mode 100644 index 00000000..0cb22a7e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRackModal.js @@ -0,0 +1,35 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeDeleteRackModal } from '../../actions/modals/topology' +import { deleteRack } from '../../actions/topology/rack' +import ConfirmationModal from '../../components/modals/ConfirmationModal' + +const DeleteRackModalComponent = ({ visible, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.deleteRackModalVisible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRack()) + } + dispatch(closeDeleteRackModal()) + }, + } +} + +const DeleteRackModal = connect(mapStateToProps, mapDispatchToProps)(DeleteRackModalComponent) + +export default DeleteRackModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js new file mode 100644 index 00000000..1f6eef92 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/DeleteRoomModal.js @@ -0,0 +1,35 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeDeleteRoomModal } from '../../actions/modals/topology' +import { deleteRoom } from '../../actions/topology/room' +import ConfirmationModal from '../../components/modals/ConfirmationModal' + +const DeleteRoomModalComponent = ({ visible, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.deleteRoomModalVisible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRoom()) + } + dispatch(closeDeleteRoomModal()) + }, + } +} + +const DeleteRoomModal = connect(mapStateToProps, mapDispatchToProps)(DeleteRoomModalComponent) + +export default DeleteRoomModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js b/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js new file mode 100644 index 00000000..9128f449 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/EditRackNameModal.js @@ -0,0 +1,40 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeEditRackNameModal } from '../../actions/modals/topology' +import { editRackName } from '../../actions/topology/rack' +import TextInputModal from '../../components/modals/TextInputModal' + +const EditRackNameModalComponent = ({ visible, previousName, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.editRackNameModalVisible, + previousName: + state.interactionLevel.mode === 'RACK' + ? state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name + : '', + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (name) => { + if (name) { + dispatch(editRackName(name)) + } + dispatch(closeEditRackNameModal()) + }, + } +} + +const EditRackNameModal = connect(mapStateToProps, mapDispatchToProps)(EditRackNameModalComponent) + +export default EditRackNameModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js b/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js new file mode 100644 index 00000000..8032a5d1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/EditRoomNameModal.js @@ -0,0 +1,38 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeEditRoomNameModal } from '../../actions/modals/topology' +import { editRoomName } from '../../actions/topology/room' +import TextInputModal from '../../components/modals/TextInputModal' + +const EditRoomNameModalComponent = ({ visible, previousName, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.editRoomNameModalVisible, + previousName: + state.interactionLevel.mode === 'ROOM' ? state.objects.room[state.interactionLevel.roomId].name : '', + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (name) => { + if (name) { + dispatch(editRoomName(name)) + } + dispatch(closeEditRoomNameModal()) + }, + } +} + +const EditRoomNameModal = connect(mapStateToProps, mapDispatchToProps)(EditRoomNameModalComponent) + +export default EditRoomNameModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js new file mode 100644 index 00000000..6cf12d8e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewPortfolioModal.js @@ -0,0 +1,30 @@ +import { connect } from 'react-redux' +import NewPortfolioModalComponent from '../../components/modals/custom-components/NewPortfolioModalComponent' +import { addPortfolio } from '../../actions/portfolios' +import { closeNewPortfolioModal } from '../../actions/modals/portfolios' + +const mapStateToProps = (state) => { + return { + show: state.modals.newPortfolioModalVisible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (name, targets) => { + if (name) { + dispatch( + addPortfolio({ + name, + targets, + }) + ) + } + dispatch(closeNewPortfolioModal()) + }, + } +} + +const NewPortfolioModal = connect(mapStateToProps, mapDispatchToProps)(NewPortfolioModalComponent) + +export default NewPortfolioModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js new file mode 100644 index 00000000..d306dc45 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewProjectModal.js @@ -0,0 +1,30 @@ +import React from 'react' +import { connect } from 'react-redux' +import { closeNewProjectModal } from '../../actions/modals/projects' +import { addProject } from '../../actions/projects' +import TextInputModal from '../../components/modals/TextInputModal' + +const NewProjectModalComponent = ({ visible, callback }) => ( + +) + +const mapStateToProps = (state) => { + return { + visible: state.modals.newProjectModalVisible, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (text) => { + if (text) { + dispatch(addProject(text)) + } + dispatch(closeNewProjectModal()) + }, + } +} + +const NewProjectModal = connect(mapStateToProps, mapDispatchToProps)(NewProjectModalComponent) + +export default NewProjectModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js new file mode 100644 index 00000000..7d774fa4 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewScenarioModal.js @@ -0,0 +1,50 @@ +import { connect } from 'react-redux' +import NewScenarioModalComponent from '../../components/modals/custom-components/NewScenarioModalComponent' +import { addScenario } from '../../actions/scenarios' +import { closeNewScenarioModal } from '../../actions/modals/scenarios' + +const mapStateToProps = (state) => { + let topologies = + state.currentProjectId !== '-1' + ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t]) + : [] + if (topologies.filter((t) => !t).length > 0) { + topologies = [] + } + + return { + show: state.modals.newScenarioModalVisible, + currentPortfolioId: state.currentPortfolioId, + currentPortfolioScenarioIds: + state.currentPortfolioId !== '-1' && state.objects.portfolio[state.currentPortfolioId] + ? state.objects.portfolio[state.currentPortfolioId].scenarioIds + : [], + traces: Object.values(state.objects.trace), + topologies, + schedulers: Object.values(state.objects.scheduler), + } +} + +const mapDispatchToProps = (dispatch) => { + return { + callback: (name, portfolioId, trace, topology, operational) => { + if (name) { + dispatch( + addScenario({ + portfolioId, + name, + trace, + topology, + operational, + }) + ) + } + + dispatch(closeNewScenarioModal()) + }, + } +} + +const NewScenarioModal = connect(mapStateToProps, mapDispatchToProps)(NewScenarioModalComponent) + +export default NewScenarioModal diff --git a/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js b/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js new file mode 100644 index 00000000..0acf6cf2 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/modals/NewTopologyModal.js @@ -0,0 +1,42 @@ +import { connect } from 'react-redux' +import NewTopologyModalComponent from '../../components/modals/custom-components/NewTopologyModalComponent' +import { closeNewTopologyModal } from '../../actions/modals/topology' +import { addTopology } 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 = [] + } + + return { + show: state.modals.changeTopologyModalVisible, + topologies, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onCreateTopology: (name) => { + if (name) { + dispatch(addTopology(name, undefined)) + } + dispatch(closeNewTopologyModal()) + }, + onDuplicateTopology: (name, id) => { + if (name) { + dispatch(addTopology(name, id)) + } + dispatch(closeNewTopologyModal()) + }, + onCancel: () => { + dispatch(closeNewTopologyModal()) + }, + } +} + +const NewTopologyModal = connect(mapStateToProps, mapDispatchToProps)(NewTopologyModalComponent) + +export default NewTopologyModal diff --git a/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js new file mode 100644 index 00000000..845d54e1 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/navigation/AppNavbarContainer.js @@ -0,0 +1,12 @@ +import { connect } from 'react-redux' +import AppNavbarComponent from '../../components/navigation/AppNavbarComponent' + +const mapStateToProps = (state) => { + return { + project: state.currentProjectId !== '-1' ? state.objects.project[state.currentProjectId] : undefined, + } +} + +const AppNavbarContainer = connect(mapStateToProps)(AppNavbarComponent) + +export default AppNavbarContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js new file mode 100644 index 00000000..dfd6affe --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/projects/FilterLink.js @@ -0,0 +1,19 @@ +import { connect } from 'react-redux' +import { setAuthVisibilityFilter } from '../../actions/projects' +import FilterButton from '../../components/projects/FilterButton' + +const mapStateToProps = (state, ownProps) => { + return { + active: state.projectList.authVisibilityFilter === ownProps.filter, + } +} + +const mapDispatchToProps = (dispatch, ownProps) => { + return { + onClick: () => dispatch(setAuthVisibilityFilter(ownProps.filter)), + } +} + +const FilterLink = connect(mapStateToProps, mapDispatchToProps)(FilterButton) + +export default FilterLink diff --git a/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js new file mode 100644 index 00000000..ffd4a4a3 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/projects/NewProjectButtonContainer.js @@ -0,0 +1,13 @@ +import { connect } from 'react-redux' +import { openNewProjectModal } from '../../actions/modals/projects' +import NewProjectButtonComponent from '../../components/projects/NewProjectButtonComponent' + +const mapDispatchToProps = (dispatch) => { + return { + onClick: () => dispatch(openNewProjectModal()), + } +} + +const NewProjectButtonContainer = connect(undefined, mapDispatchToProps)(NewProjectButtonComponent) + +export default NewProjectButtonContainer diff --git a/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js new file mode 100644 index 00000000..8bcbb7fd --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/projects/ProjectActions.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux' +import { deleteProject } from '../../actions/projects' +import ProjectActionButtons from '../../components/projects/ProjectActionButtons' + +const mapStateToProps = (state, ownProps) => { + return { + projectId: ownProps.projectId, + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onViewUsers: (id) => {}, // TODO implement user viewing + onDelete: (id) => dispatch(deleteProject(id)), + } +} + +const ProjectActions = connect(mapStateToProps, mapDispatchToProps)(ProjectActionButtons) + +export default ProjectActions diff --git a/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js new file mode 100644 index 00000000..f0010540 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/containers/projects/VisibleProjectAuthList.js @@ -0,0 +1,32 @@ +import { connect } from 'react-redux' +import ProjectList from '../../components/projects/ProjectAuthList' + +const getVisibleProjectAuths = (projectAuths, filter) => { + switch (filter) { + case 'SHOW_ALL': + return projectAuths + case 'SHOW_OWN': + return projectAuths.filter((projectAuth) => projectAuth.authorizationLevel === 'OWN') + case 'SHOW_SHARED': + return projectAuths.filter((projectAuth) => projectAuth.authorizationLevel !== 'OWN') + default: + return projectAuths + } +} + +const mapStateToProps = (state) => { + const denormalizedAuthorizations = state.projectList.authorizationsOfCurrentUser.map((authorizationIds) => { + const authorization = state.objects.authorization[authorizationIds] + authorization.user = state.objects.user[authorization.userId] + authorization.project = state.objects.project[authorization.projectId] + return authorization + }) + + return { + authorizations: getVisibleProjectAuths(denormalizedAuthorizations, state.projectList.authVisibilityFilter), + } +} + +const VisibleProjectAuthList = connect(mapStateToProps)(ProjectList) + +export default VisibleProjectAuthList -- cgit v1.2.3