summaryrefslogtreecommitdiff
path: root/src/containers/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/containers/app')
-rw-r--r--src/containers/app/map/DatacenterContainer.js19
-rw-r--r--src/containers/app/map/GrayContainer.js16
-rw-r--r--src/containers/app/map/MapStage.js26
-rw-r--r--src/containers/app/map/RackContainer.js26
-rw-r--r--src/containers/app/map/RackEnergyFillContainer.js28
-rw-r--r--src/containers/app/map/RackSpaceFillContainer.js16
-rw-r--r--src/containers/app/map/RoomContainer.js24
-rw-r--r--src/containers/app/map/TileContainer.js40
-rw-r--r--src/containers/app/map/WallContainer.js14
-rw-r--r--src/containers/app/map/controls/ScaleIndicatorContainer.js14
-rw-r--r--src/containers/app/map/controls/ZoomControlContainer.js22
-rw-r--r--src/containers/app/map/layers/MapLayer.js15
-rw-r--r--src/containers/app/map/layers/ObjectHoverLayer.js37
-rw-r--r--src/containers/app/map/layers/RoomHoverLayer.js50
-rw-r--r--src/containers/app/sidebars/elements/LoadBarContainer.js25
-rw-r--r--src/containers/app/sidebars/elements/LoadChartContainer.js27
-rw-r--r--src/containers/app/sidebars/simulation/ExperimentMetadataContainer.js29
-rw-r--r--src/containers/app/sidebars/simulation/LoadMetricContainer.js14
-rw-r--r--src/containers/app/sidebars/simulation/TaskContainer.js23
-rw-r--r--src/containers/app/sidebars/simulation/TraceContainer.js22
-rw-r--r--src/containers/app/sidebars/topology/TopologySidebar.js14
-rw-r--r--src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js14
-rw-r--r--src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js28
-rw-r--r--src/containers/app/sidebars/topology/machine/BackToRackContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/machine/MachineNameContainer.js14
-rw-r--r--src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/machine/UnitAddContainer.js22
-rw-r--r--src/containers/app/sidebars/topology/machine/UnitContainer.js23
-rw-r--r--src/containers/app/sidebars/topology/machine/UnitListContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/machine/UnitTabsContainer.js14
-rw-r--r--src/containers/app/sidebars/topology/rack/BackToRoomContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/rack/DeleteRackContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/rack/EmptySlotContainer.js22
-rw-r--r--src/containers/app/sidebars/topology/rack/MachineContainer.js35
-rw-r--r--src/containers/app/sidebars/topology/rack/MachineListContainer.js14
-rw-r--r--src/containers/app/sidebars/topology/rack/RackNameContainer.js22
-rw-r--r--src/containers/app/sidebars/topology/rack/RackSidebarContainer.js15
-rw-r--r--src/containers/app/sidebars/topology/room/BackToBuildingContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/room/DeleteRoomContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/room/RackConstructionContainer.js23
-rw-r--r--src/containers/app/sidebars/topology/room/RoomNameContainer.js22
-rw-r--r--src/containers/app/sidebars/topology/room/RoomSidebarContainer.js16
-rw-r--r--src/containers/app/sidebars/topology/room/RoomTypeContainer.js14
-rw-r--r--src/containers/app/timeline/PlayButtonContainer.js23
-rw-r--r--src/containers/app/timeline/TimelineContainer.js39
-rw-r--r--src/containers/app/timeline/TimelineControlsContainer.js34
-rw-r--r--src/containers/app/timeline/TimelineLabelsContainer.js15
48 files changed, 1038 insertions, 0 deletions
diff --git a/src/containers/app/map/DatacenterContainer.js b/src/containers/app/map/DatacenterContainer.js
new file mode 100644
index 00000000..6859f2d8
--- /dev/null
+++ b/src/containers/app/map/DatacenterContainer.js
@@ -0,0 +1,19 @@
+import {connect} from "react-redux";
+import DatacenterGroup from "../../../components/app/map/groups/DatacenterGroup";
+
+const mapStateToProps = state => {
+ if (state.currentDatacenterId === -1) {
+ return {};
+ }
+
+ return {
+ datacenter: state.objects.datacenter[state.currentDatacenterId],
+ interactionLevel: state.interactionLevel,
+ };
+};
+
+const DatacenterContainer = connect(
+ mapStateToProps
+)(DatacenterGroup);
+
+export default DatacenterContainer;
diff --git a/src/containers/app/map/GrayContainer.js b/src/containers/app/map/GrayContainer.js
new file mode 100644
index 00000000..a22ef3c8
--- /dev/null
+++ b/src/containers/app/map/GrayContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/map/MapStage.js b/src/containers/app/map/MapStage.js
new file mode 100644
index 00000000..e0c85651
--- /dev/null
+++ b/src/containers/app/map/MapStage.js
@@ -0,0 +1,26 @@
+import {connect} from "react-redux";
+import {setMapDimensions, setMapPosition, setMapScale} from "../../../actions/map";
+import MapStageComponent from "../../../components/app/map/MapStageComponent";
+
+const mapStateToProps = state => {
+ return {
+ mapPosition: state.map.position,
+ mapDimensions: state.map.dimensions,
+ mapScale: state.map.scale,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ setMapPosition: (x, y) => dispatch(setMapPosition(x, y)),
+ setMapDimensions: (width, height) => dispatch(setMapDimensions(width, height)),
+ setMapScale: (scale) => dispatch(setMapScale(scale)),
+ };
+};
+
+const MapStage = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(MapStageComponent);
+
+export default MapStage;
diff --git a/src/containers/app/map/RackContainer.js b/src/containers/app/map/RackContainer.js
new file mode 100644
index 00000000..38f01efc
--- /dev/null
+++ b/src/containers/app/map/RackContainer.js
@@ -0,0 +1,26 @@
+import {connect} from "react-redux";
+import RackGroup from "../../../components/app/map/groups/RackGroup";
+import {getStateLoad} from "../../../util/simulation-load";
+
+const mapStateToProps = (state, ownProps) => {
+ const inSimulation = state.currentExperimentId !== -1;
+
+ let rackLoad = undefined;
+ if (inSimulation) {
+ if (state.states.rack[state.currentTick] && state.states.rack[state.currentTick][ownProps.tile.objectId]) {
+ rackLoad = getStateLoad(state.loadMetric, state.states.rack[state.currentTick][ownProps.tile.objectId]);
+ }
+ }
+
+ return {
+ interactionLevel: state.interactionLevel,
+ inSimulation,
+ rackLoad,
+ };
+};
+
+const RackContainer = connect(
+ mapStateToProps
+)(RackGroup);
+
+export default RackContainer;
diff --git a/src/containers/app/map/RackEnergyFillContainer.js b/src/containers/app/map/RackEnergyFillContainer.js
new file mode 100644
index 00000000..d83dc386
--- /dev/null
+++ b/src/containers/app/map/RackEnergyFillContainer.js
@@ -0,0 +1,28 @@
+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].objectId];
+ 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/src/containers/app/map/RackSpaceFillContainer.js b/src/containers/app/map/RackSpaceFillContainer.js
new file mode 100644
index 00000000..bbcf4e2e
--- /dev/null
+++ b/src/containers/app/map/RackSpaceFillContainer.js
@@ -0,0 +1,16 @@
+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].objectId].machineIds;
+ return {
+ type: "space",
+ fillFraction: machineIds.filter(id => id !== null).length / machineIds.length,
+ };
+};
+
+const RackSpaceFillContainer = connect(
+ mapStateToProps
+)(RackFillBar);
+
+export default RackSpaceFillContainer;
diff --git a/src/containers/app/map/RoomContainer.js b/src/containers/app/map/RoomContainer.js
new file mode 100644
index 00000000..c8e146d6
--- /dev/null
+++ b/src/containers/app/map/RoomContainer.js
@@ -0,0 +1,24 @@
+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/src/containers/app/map/TileContainer.js b/src/containers/app/map/TileContainer.js
new file mode 100644
index 00000000..299016d1
--- /dev/null
+++ b/src/containers/app/map/TileContainer.js
@@ -0,0 +1,40 @@
+import {connect} from "react-redux";
+import {goFromRoomToRack} from "../../../actions/interaction-level";
+import TileGroup from "../../../components/app/map/groups/TileGroup";
+import {getStateLoad} from "../../../util/simulation-load";
+
+const mapStateToProps = (state, ownProps) => {
+ const tile = state.objects.tile[ownProps.tileId];
+ const inSimulation = state.currentExperimentId !== -1;
+
+ let roomLoad = undefined;
+ if (inSimulation) {
+ if (state.states.room[state.currentTick] && state.states.room[state.currentTick][tile.roomId]) {
+ roomLoad = getStateLoad(state.loadMetric, state.states.room[state.currentTick][tile.roomId]);
+ }
+ }
+
+ return {
+ interactionLevel: state.interactionLevel,
+ tile,
+ inSimulation,
+ roomLoad,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onClick: tile => {
+ if (tile.objectType) {
+ dispatch(goFromRoomToRack(tile.id))
+ }
+ }
+ };
+};
+
+const TileContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(TileGroup);
+
+export default TileContainer;
diff --git a/src/containers/app/map/WallContainer.js b/src/containers/app/map/WallContainer.js
new file mode 100644
index 00000000..0ce8875a
--- /dev/null
+++ b/src/containers/app/map/WallContainer.js
@@ -0,0 +1,14 @@
+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/src/containers/app/map/controls/ScaleIndicatorContainer.js b/src/containers/app/map/controls/ScaleIndicatorContainer.js
new file mode 100644
index 00000000..12596c9c
--- /dev/null
+++ b/src/containers/app/map/controls/ScaleIndicatorContainer.js
@@ -0,0 +1,14 @@
+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/src/containers/app/map/controls/ZoomControlContainer.js b/src/containers/app/map/controls/ZoomControlContainer.js
new file mode 100644
index 00000000..b9cf0a63
--- /dev/null
+++ b/src/containers/app/map/controls/ZoomControlContainer.js
@@ -0,0 +1,22 @@
+import {connect} from "react-redux";
+import {setMapScale} from "../../../../actions/map";
+import ZoomControlComponent from "../../../../components/app/map/controls/ZoomControlComponent";
+
+const mapStateToProps = state => {
+ return {
+ mapScale: state.map.scale,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ setMapScale: scale => dispatch(setMapScale(scale)),
+ };
+};
+
+const ZoomControlContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ZoomControlComponent);
+
+export default ZoomControlContainer;
diff --git a/src/containers/app/map/layers/MapLayer.js b/src/containers/app/map/layers/MapLayer.js
new file mode 100644
index 00000000..ea3a0b57
--- /dev/null
+++ b/src/containers/app/map/layers/MapLayer.js
@@ -0,0 +1,15 @@
+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/src/containers/app/map/layers/ObjectHoverLayer.js b/src/containers/app/map/layers/ObjectHoverLayer.js
new file mode 100644
index 00000000..d905fd42
--- /dev/null
+++ b/src/containers/app/map/layers/ObjectHoverLayer.js
@@ -0,0 +1,37 @@
+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.objectType);
+
+ },
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onClick: (x, y) => dispatch(addRackToTile(x, y)),
+ };
+};
+
+const ObjectHoverLayer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ObjectHoverLayerComponent);
+
+export default ObjectHoverLayer;
diff --git a/src/containers/app/map/layers/RoomHoverLayer.js b/src/containers/app/map/layers/RoomHoverLayer.js
new file mode 100644
index 00000000..801ce549
--- /dev/null
+++ b/src/containers/app/map/layers/RoomHoverLayer.js
@@ -0,0 +1,50 @@
+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) => {
+ if (state.interactionLevel.mode !== "BUILDING") {
+ return false;
+ }
+
+ 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 => room.datacenterId === state.currentDatacenterId
+ && 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/src/containers/app/sidebars/elements/LoadBarContainer.js b/src/containers/app/sidebars/elements/LoadBarContainer.js
new file mode 100644
index 00000000..ccaf1729
--- /dev/null
+++ b/src/containers/app/sidebars/elements/LoadBarContainer.js
@@ -0,0 +1,25 @@
+import {connect} from "react-redux";
+import LoadBarComponent from "../../../../components/app/sidebars/elements/LoadBarComponent";
+import {getStateLoad} from "../../../../util/simulation-load";
+
+const mapStateToProps = (state, ownProps) => {
+ let percent = 0;
+ let enabled = false;
+
+ const objectStates = state.states[ownProps.objectType];
+ if (objectStates[state.currentTick] && objectStates[state.currentTick][ownProps.objectId]) {
+ percent = Math.floor(100 * getStateLoad(state.loadMetric, objectStates[state.currentTick][ownProps.objectId]));
+ enabled = true;
+ }
+
+ return {
+ percent,
+ enabled
+ };
+};
+
+const LoadBarContainer = connect(
+ mapStateToProps
+)(LoadBarComponent);
+
+export default LoadBarContainer;
diff --git a/src/containers/app/sidebars/elements/LoadChartContainer.js b/src/containers/app/sidebars/elements/LoadChartContainer.js
new file mode 100644
index 00000000..227a4fd5
--- /dev/null
+++ b/src/containers/app/sidebars/elements/LoadChartContainer.js
@@ -0,0 +1,27 @@
+import {connect} from "react-redux";
+import LoadChartComponent from "../../../../components/app/sidebars/elements/LoadChartComponent";
+import {getStateLoad} from "../../../../util/simulation-load";
+
+const mapStateToProps = (state, ownProps) => {
+ const data = [];
+
+ if (state.lastSimulatedTick !== -1) {
+ const objectStates = state.states[ownProps.objectType];
+ Object.keys(objectStates).forEach(tick => {
+ if (objectStates[tick][ownProps.objectId]) {
+ data.push({x: tick, y: getStateLoad(state.loadMetric, objectStates[tick][ownProps.objectId])});
+ }
+ });
+ }
+
+ return {
+ data,
+ currentTick: state.currentTick,
+ };
+};
+
+const LoadChartContainer = connect(
+ mapStateToProps
+)(LoadChartComponent);
+
+export default LoadChartContainer;
diff --git a/src/containers/app/sidebars/simulation/ExperimentMetadataContainer.js b/src/containers/app/sidebars/simulation/ExperimentMetadataContainer.js
new file mode 100644
index 00000000..a5e403ce
--- /dev/null
+++ b/src/containers/app/sidebars/simulation/ExperimentMetadataContainer.js
@@ -0,0 +1,29 @@
+import {connect} from "react-redux";
+import ExperimentMetadataComponent from "../../../../components/app/sidebars/simulation/ExperimentMetadataComponent";
+
+const mapStateToProps = state => {
+ if (!state.objects.experiment[state.currentExperimentId]) {
+ return {
+ experimentName: "Loading experiment",
+ pathName: "",
+ traceName: "",
+ schedulerName: "",
+ }
+ }
+
+ const path = state.objects.path[state.objects.experiment[state.currentExperimentId].pathId];
+ const pathName = path.name ? path.name : "Path " + path.id;
+
+ return {
+ experimentName: state.objects.experiment[state.currentExperimentId].name,
+ pathName,
+ traceName: state.objects.trace[state.objects.experiment[state.currentExperimentId].traceId].name,
+ schedulerName: state.objects.scheduler[state.objects.experiment[state.currentExperimentId].schedulerName].name,
+ };
+};
+
+const ExperimentMetadataContainer = connect(
+ mapStateToProps
+)(ExperimentMetadataComponent);
+
+export default ExperimentMetadataContainer;
diff --git a/src/containers/app/sidebars/simulation/LoadMetricContainer.js b/src/containers/app/sidebars/simulation/LoadMetricContainer.js
new file mode 100644
index 00000000..5ce3542c
--- /dev/null
+++ b/src/containers/app/sidebars/simulation/LoadMetricContainer.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import LoadMetricComponent from "../../../../components/app/sidebars/simulation/LoadMetricComponent";
+
+const mapStateToProps = state => {
+ return {
+ loadMetric: state.loadMetric,
+ }
+};
+
+const LoadMetricContainer = connect(
+ mapStateToProps
+)(LoadMetricComponent);
+
+export default LoadMetricContainer;
diff --git a/src/containers/app/sidebars/simulation/TaskContainer.js b/src/containers/app/sidebars/simulation/TaskContainer.js
new file mode 100644
index 00000000..357bd7ed
--- /dev/null
+++ b/src/containers/app/sidebars/simulation/TaskContainer.js
@@ -0,0 +1,23 @@
+import {connect} from "react-redux";
+import TaskComponent from "../../../../components/app/sidebars/simulation/TaskComponent";
+
+const mapStateToProps = (state, ownProps) => {
+ let flopsLeft = state.objects.task[ownProps.taskId].totalFlopCount;
+
+ if (state.states.task[state.currentTick] && state.states.task[state.currentTick][ownProps.taskId]) {
+ flopsLeft = state.states.task[state.currentTick][ownProps.taskId].flopsLeft;
+ } else if (state.objects.task[ownProps.taskId].startTick < state.currentTick) {
+ flopsLeft = 0;
+ }
+
+ return {
+ task: state.objects.task[ownProps.taskId],
+ flopsLeft,
+ };
+};
+
+const TaskContainer = connect(
+ mapStateToProps
+)(TaskComponent);
+
+export default TaskContainer;
diff --git a/src/containers/app/sidebars/simulation/TraceContainer.js b/src/containers/app/sidebars/simulation/TraceContainer.js
new file mode 100644
index 00000000..7955f313
--- /dev/null
+++ b/src/containers/app/sidebars/simulation/TraceContainer.js
@@ -0,0 +1,22 @@
+import {connect} from "react-redux";
+import TraceComponent from "../../../../components/app/sidebars/simulation/TraceComponent";
+
+const mapStateToProps = state => {
+ if (!state.objects.experiment[state.currentExperimentId] ||
+ !state.objects.trace[state.objects.experiment[state.currentExperimentId].traceId].jobIds) {
+ return {
+ jobs: []
+ };
+ }
+
+ return {
+ jobs: state.objects.trace[state.objects.experiment[state.currentExperimentId].traceId].jobIds
+ .map(id => state.objects.job[id]),
+ };
+};
+
+const TraceContainer = connect(
+ mapStateToProps
+)(TraceComponent);
+
+export default TraceContainer;
diff --git a/src/containers/app/sidebars/topology/TopologySidebar.js b/src/containers/app/sidebars/topology/TopologySidebar.js
new file mode 100644
index 00000000..ac59f5cc
--- /dev/null
+++ b/src/containers/app/sidebars/topology/TopologySidebar.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import TopologySidebarComponent from "../../../../components/app/sidebars/topology/TopologySidebarComponent";
+
+const mapStateToProps = state => {
+ return {
+ interactionLevel: state.interactionLevel
+ };
+};
+
+const TopologySidebar = connect(
+ mapStateToProps
+)(TopologySidebarComponent);
+
+export default TopologySidebar;
diff --git a/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js b/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js
new file mode 100644
index 00000000..ce7a308a
--- /dev/null
+++ b/src/containers/app/sidebars/topology/building/BuildingSidebarContainer.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import BuildingSidebarComponent from "../../../../../components/app/sidebars/topology/building/BuildingSidebarComponent";
+
+const mapStateToProps = state => {
+ return {
+ inSimulation: state.currentExperimentId !== -1
+ };
+};
+
+const BuildingSidebarContainer = connect(
+ mapStateToProps
+)(BuildingSidebarComponent);
+
+export default BuildingSidebarContainer;
diff --git a/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js b/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js
new file mode 100644
index 00000000..3ec1349b
--- /dev/null
+++ b/src/containers/app/sidebars/topology/building/NewRoomConstructionContainer.js
@@ -0,0 +1,28 @@
+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/src/containers/app/sidebars/topology/machine/BackToRackContainer.js b/src/containers/app/sidebars/topology/machine/BackToRackContainer.js
new file mode 100644
index 00000000..f0ac9220
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/BackToRackContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
new file mode 100644
index 00000000..bfdde179
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
new file mode 100644
index 00000000..9d23dcb6
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
@@ -0,0 +1,14 @@
+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/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js b/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js
new file mode 100644
index 00000000..5c28248c
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/MachineSidebarContainer.js
@@ -0,0 +1,16 @@
+import {connect} from "react-redux";
+import MachineSidebarComponent from "../../../../../components/app/sidebars/topology/machine/MachineSidebarComponent";
+
+const mapStateToProps = state => {
+ return {
+ inSimulation: state.currentExperimentId !== -1,
+ machineId: state.objects.rack[state.objects.tile[state.interactionLevel.tileId].objectId]
+ .machineIds[state.interactionLevel.position - 1],
+ };
+};
+
+const MachineSidebarContainer = connect(
+ mapStateToProps
+)(MachineSidebarComponent);
+
+export default MachineSidebarContainer;
diff --git a/src/containers/app/sidebars/topology/machine/UnitAddContainer.js b/src/containers/app/sidebars/topology/machine/UnitAddContainer.js
new file mode 100644
index 00000000..f194ebcf
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/UnitAddContainer.js
@@ -0,0 +1,22 @@
+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/src/containers/app/sidebars/topology/machine/UnitContainer.js b/src/containers/app/sidebars/topology/machine/UnitContainer.js
new file mode 100644
index 00000000..12024d5a
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/UnitContainer.js
@@ -0,0 +1,23 @@
+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],
+ inSimulation: state.currentExperimentId !== -1
+ };
+};
+
+const mapDispatchToProps = (dispatch, ownProps) => {
+ return {
+ onDelete: () => dispatch(deleteUnit(ownProps.unitType, ownProps.index)),
+ };
+};
+
+const UnitContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(UnitComponent);
+
+export default UnitContainer;
diff --git a/src/containers/app/sidebars/topology/machine/UnitListContainer.js b/src/containers/app/sidebars/topology/machine/UnitListContainer.js
new file mode 100644
index 00000000..e351c63c
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/UnitListContainer.js
@@ -0,0 +1,16 @@
+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].objectId]
+ .machineIds[state.interactionLevel.position - 1]][ownProps.unitType + "Ids"],
+ inSimulation: state.currentExperimentId !== -1
+ };
+};
+
+const UnitListContainer = connect(
+ mapStateToProps
+)(UnitListComponent);
+
+export default UnitListContainer;
diff --git a/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js b/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js
new file mode 100644
index 00000000..46952c74
--- /dev/null
+++ b/src/containers/app/sidebars/topology/machine/UnitTabsContainer.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import UnitTabsComponent from "../../../../../components/app/sidebars/topology/machine/UnitTabsComponent";
+
+const mapStateToProps = state => {
+ return {
+ inSimulation: state.currentExperimentId !== -1,
+ };
+};
+
+const UnitTabsContainer = connect(
+ mapStateToProps
+)(UnitTabsComponent);
+
+export default UnitTabsContainer;
diff --git a/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js b/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js
new file mode 100644
index 00000000..01653540
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/BackToRoomContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
new file mode 100644
index 00000000..cf225558
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js b/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js
new file mode 100644
index 00000000..b8f5e553
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/EmptySlotContainer.js
@@ -0,0 +1,22 @@
+import {connect} from "react-redux";
+import {addMachine} from "../../../../../actions/topology/rack";
+import EmptySlotComponent from "../../../../../components/app/sidebars/topology/rack/EmptySlotComponent";
+
+const mapStateToProps = state => {
+ return {
+ inSimulation: state.currentExperimentId !== -1
+ };
+};
+
+const mapDispatchToProps = (dispatch, ownProps) => {
+ return {
+ onAdd: () => dispatch(addMachine(ownProps.position)),
+ };
+};
+
+const EmptySlotContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(EmptySlotComponent);
+
+export default EmptySlotContainer;
diff --git a/src/containers/app/sidebars/topology/rack/MachineContainer.js b/src/containers/app/sidebars/topology/rack/MachineContainer.js
new file mode 100644
index 00000000..cd15ddd0
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/MachineContainer.js
@@ -0,0 +1,35 @@
+import {connect} from "react-redux";
+import {goFromRackToMachine} from "../../../../../actions/interaction-level";
+import MachineComponent from "../../../../../components/app/sidebars/topology/rack/MachineComponent";
+import {getStateLoad} from "../../../../../util/simulation-load";
+
+const mapStateToProps = (state, ownProps) => {
+ const machine = state.objects.machine[ownProps.machineId];
+ const inSimulation = state.currentExperimentId !== -1;
+
+ let machineLoad = undefined;
+ if (inSimulation) {
+ if (state.states.machine[state.currentTick] && state.states.machine[state.currentTick][machine.id]) {
+ machineLoad = getStateLoad(state.loadMetric, state.states.machine[state.currentTick][machine.id]);
+ }
+ }
+
+ return {
+ machine,
+ inSimulation,
+ machineLoad
+ };
+};
+
+const mapDispatchToProps = (dispatch, ownProps) => {
+ return {
+ onClick: () => dispatch(goFromRackToMachine(ownProps.position)),
+ };
+};
+
+const MachineContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(MachineComponent);
+
+export default MachineContainer;
diff --git a/src/containers/app/sidebars/topology/rack/MachineListContainer.js b/src/containers/app/sidebars/topology/rack/MachineListContainer.js
new file mode 100644
index 00000000..dbedfbb2
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/MachineListContainer.js
@@ -0,0 +1,14 @@
+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].objectId].machineIds,
+ };
+};
+
+const MachineListContainer = connect(
+ mapStateToProps
+)(MachineListComponent);
+
+export default MachineListContainer;
diff --git a/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/src/containers/app/sidebars/topology/rack/RackNameContainer.js
new file mode 100644
index 00000000..49a58155
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/RackNameContainer.js
@@ -0,0 +1,22 @@
+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].objectId].name,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onEdit: () => dispatch(openEditRackNameModal()),
+ };
+};
+
+const RackNameContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(RackNameComponent);
+
+export default RackNameContainer;
diff --git a/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js b/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js
new file mode 100644
index 00000000..ba51ee4a
--- /dev/null
+++ b/src/containers/app/sidebars/topology/rack/RackSidebarContainer.js
@@ -0,0 +1,15 @@
+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].objectId,
+ inSimulation: state.currentExperimentId !== -1,
+ };
+};
+
+const RackSidebarContainer = connect(
+ mapStateToProps
+)(RackSidebarComponent);
+
+export default RackSidebarContainer;
diff --git a/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js b/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js
new file mode 100644
index 00000000..a6366552
--- /dev/null
+++ b/src/containers/app/sidebars/topology/room/BackToBuildingContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
new file mode 100644
index 00000000..0c9aef1c
--- /dev/null
+++ b/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
@@ -0,0 +1,16 @@
+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/src/containers/app/sidebars/topology/room/RackConstructionContainer.js b/src/containers/app/sidebars/topology/room/RackConstructionContainer.js
new file mode 100644
index 00000000..f06a3ab2
--- /dev/null
+++ b/src/containers/app/sidebars/topology/room/RackConstructionContainer.js
@@ -0,0 +1,23 @@
+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,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onStart: () => dispatch(startRackConstruction()),
+ onStop: () => dispatch(stopRackConstruction()),
+ };
+};
+
+const RackConstructionContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(RackConstructionComponent);
+
+export default RackConstructionContainer;
diff --git a/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/src/containers/app/sidebars/topology/room/RoomNameContainer.js
new file mode 100644
index 00000000..c1f7f397
--- /dev/null
+++ b/src/containers/app/sidebars/topology/room/RoomNameContainer.js
@@ -0,0 +1,22 @@
+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/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js b/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js
new file mode 100644
index 00000000..6371e6a1
--- /dev/null
+++ b/src/containers/app/sidebars/topology/room/RoomSidebarContainer.js
@@ -0,0 +1,16 @@
+import {connect} from "react-redux";
+import RoomSidebarComponent from "../../../../../components/app/sidebars/topology/room/RoomSidebarComponent";
+
+const mapStateToProps = state => {
+ return {
+ roomId: state.interactionLevel.roomId,
+ roomType: state.objects.room[state.interactionLevel.roomId].roomType,
+ inSimulation: state.currentExperimentId !== -1,
+ };
+};
+
+const RoomSidebarContainer = connect(
+ mapStateToProps
+)(RoomSidebarComponent);
+
+export default RoomSidebarContainer;
diff --git a/src/containers/app/sidebars/topology/room/RoomTypeContainer.js b/src/containers/app/sidebars/topology/room/RoomTypeContainer.js
new file mode 100644
index 00000000..8cc1126a
--- /dev/null
+++ b/src/containers/app/sidebars/topology/room/RoomTypeContainer.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import RoomTypeComponent from "../../../../../components/app/sidebars/topology/room/RoomTypeComponent";
+
+const mapStateToProps = state => {
+ return {
+ roomType: state.objects.room[state.interactionLevel.roomId].roomType,
+ };
+};
+
+const RoomNameContainer = connect(
+ mapStateToProps
+)(RoomTypeComponent);
+
+export default RoomNameContainer;
diff --git a/src/containers/app/timeline/PlayButtonContainer.js b/src/containers/app/timeline/PlayButtonContainer.js
new file mode 100644
index 00000000..3db5302c
--- /dev/null
+++ b/src/containers/app/timeline/PlayButtonContainer.js
@@ -0,0 +1,23 @@
+import {connect} from "react-redux";
+import {pauseSimulation, playSimulation} from "../../../actions/simulation/playback";
+import PlayButtonComponent from "../../../components/app/timeline/PlayButtonComponent";
+
+const mapStateToProps = state => {
+ return {
+ isPlaying: state.isPlaying,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ onPlay: () => dispatch(playSimulation()),
+ onPause: () => dispatch(pauseSimulation()),
+ };
+};
+
+const PlayButtonContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(PlayButtonComponent);
+
+export default PlayButtonContainer;
diff --git a/src/containers/app/timeline/TimelineContainer.js b/src/containers/app/timeline/TimelineContainer.js
new file mode 100644
index 00000000..46491f9b
--- /dev/null
+++ b/src/containers/app/timeline/TimelineContainer.js
@@ -0,0 +1,39 @@
+import {connect} from "react-redux";
+import {pauseSimulation} from "../../../actions/simulation/playback";
+import {incrementTick} from "../../../actions/simulation/tick";
+import {setCurrentDatacenter} from "../../../actions/topology/building";
+import TimelineComponent from "../../../components/app/timeline/TimelineComponent";
+
+const mapStateToProps = state => {
+ let sections = [];
+ if (state.currentExperimentId !== -1) {
+ const sectionIds = state.objects.path[state.objects.experiment[state.currentExperimentId].pathId].sectionIds;
+
+ if (sectionIds) {
+ sections = sectionIds.map(sectionId => state.objects.section[sectionId]);
+ }
+ }
+
+ return {
+ isPlaying: state.isPlaying,
+ currentTick: state.currentTick,
+ lastSimulatedTick: state.lastSimulatedTick,
+ currentDatacenterId: state.currentDatacenterId,
+ sections,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ incrementTick: () => dispatch(incrementTick()),
+ pauseSimulation: () => dispatch(pauseSimulation()),
+ setCurrentDatacenter: id => dispatch(setCurrentDatacenter(id))
+ };
+};
+
+const TimelineContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(TimelineComponent);
+
+export default TimelineContainer;
diff --git a/src/containers/app/timeline/TimelineControlsContainer.js b/src/containers/app/timeline/TimelineControlsContainer.js
new file mode 100644
index 00000000..e91a0aca
--- /dev/null
+++ b/src/containers/app/timeline/TimelineControlsContainer.js
@@ -0,0 +1,34 @@
+import {connect} from "react-redux";
+import {goToTick} from "../../../actions/simulation/tick";
+import TimelineControlsComponent from "../../../components/app/timeline/TimelineControlsComponent";
+
+const mapStateToProps = state => {
+ let sectionTicks = [];
+ if (state.currentExperimentId !== -1) {
+ const sectionIds = state.objects.path[state.objects.experiment[state.currentExperimentId].pathId].sectionIds;
+ if (sectionIds) {
+ sectionTicks = sectionIds
+ .filter(sectionId => state.objects.section[sectionId].startTick !== 0)
+ .map(sectionId => state.objects.section[sectionId].startTick);
+ }
+ }
+
+ return {
+ currentTick: state.currentTick,
+ lastSimulatedTick: state.lastSimulatedTick,
+ sectionTicks,
+ };
+};
+
+const mapDispatchToProps = dispatch => {
+ return {
+ goToTick: (tick) => dispatch(goToTick(tick)),
+ };
+};
+
+const TimelineControlsContainer = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(TimelineControlsComponent);
+
+export default TimelineControlsContainer;
diff --git a/src/containers/app/timeline/TimelineLabelsContainer.js b/src/containers/app/timeline/TimelineLabelsContainer.js
new file mode 100644
index 00000000..3dfad9f2
--- /dev/null
+++ b/src/containers/app/timeline/TimelineLabelsContainer.js
@@ -0,0 +1,15 @@
+import {connect} from "react-redux";
+import TimelineLabelsComponent from "../../../components/app/timeline/TimelineLabelsComponent";
+
+const mapStateToProps = state => {
+ return {
+ currentTick: state.currentTick,
+ lastSimulatedTick: state.lastSimulatedTick,
+ };
+};
+
+const TimelineLabelsContainer = connect(
+ mapStateToProps
+)(TimelineLabelsComponent);
+
+export default TimelineLabelsContainer;