summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actions/interaction-level.js14
-rw-r--r--src/actions/modals/topology.js14
-rw-r--r--src/actions/topology.js18
-rw-r--r--src/components/home/JumbotronHeader.sass3
-rw-r--r--src/components/map/groups/RoomGroup.js3
-rw-r--r--src/components/sidebars/topology/TopologySidebarComponent.js4
-rw-r--r--src/components/sidebars/topology/machine/BackToRackComponent.js9
-rw-r--r--src/components/sidebars/topology/machine/DeleteMachineComponent.js11
-rw-r--r--src/components/sidebars/topology/machine/MachineNameComponent.js7
-rw-r--r--src/components/sidebars/topology/machine/MachineSidebarComponent.js16
-rw-r--r--src/containers/modals/DeleteMachineModal.js36
-rw-r--r--src/containers/sidebars/topology/machine/BackToRackContainer.js16
-rw-r--r--src/containers/sidebars/topology/machine/DeleteMachineContainer.js16
-rw-r--r--src/containers/sidebars/topology/machine/MachineNameContainer.js14
-rw-r--r--src/containers/sidebars/topology/rack/MachineContainer.js5
-rw-r--r--src/pages/App.js2
-rw-r--r--src/reducers/interaction-level.js14
-rw-r--r--src/reducers/modals.js3
-rw-r--r--src/sagas/index.js3
-rw-r--r--src/sagas/topology.js13
20 files changed, 218 insertions, 3 deletions
diff --git a/src/actions/interaction-level.js b/src/actions/interaction-level.js
index 5ceff500..2003f45e 100644
--- a/src/actions/interaction-level.js
+++ b/src/actions/interaction-level.js
@@ -1,5 +1,6 @@
export const GO_FROM_BUILDING_TO_ROOM = "GO_FROM_BUILDING_TO_ROOM";
export const GO_FROM_ROOM_TO_RACK = "GO_FROM_ROOM_TO_RACK";
+export const GO_FROM_RACK_TO_MACHINE = "GO_FROM_RACK_TO_MACHINE";
export const GO_DOWN_ONE_INTERACTION_LEVEL = "GO_DOWN_ONE_INTERACTION_LEVEL";
export function goFromBuildingToRoom(roomId) {
@@ -29,6 +30,19 @@ export function goFromRoomToRack(tileId) {
};
}
+export function goFromRackToMachine(position) {
+ return (dispatch, getState) => {
+ const {interactionLevel} = getState();
+ if (interactionLevel.mode !== "RACK") {
+ return;
+ }
+ dispatch({
+ type: GO_FROM_RACK_TO_MACHINE,
+ position
+ });
+ };
+}
+
export function goDownOneInteractionLevel() {
return {
type: GO_DOWN_ONE_INTERACTION_LEVEL
diff --git a/src/actions/modals/topology.js b/src/actions/modals/topology.js
index 507c1de6..b8e297e0 100644
--- a/src/actions/modals/topology.js
+++ b/src/actions/modals/topology.js
@@ -6,6 +6,8 @@ export const OPEN_EDIT_RACK_NAME_MODAL = "OPEN_EDIT_RACK_NAME_MODAL";
export const CLOSE_EDIT_RACK_NAME_MODAL = "CLOSE_EDIT_RACK_NAME_MODAL";
export const OPEN_DELETE_RACK_MODAL = "OPEN_DELETE_RACK_MODAL";
export const CLOSE_DELETE_RACK_MODAL = "CLOSE_DELETE_RACK_MODAL";
+export const OPEN_DELETE_MACHINE_MODAL = "OPEN_DELETE_MACHINE_MODAL";
+export const CLOSE_DELETE_MACHINE_MODAL = "CLOSE_DELETE_MACHINE_MODAL";
export function openEditRoomNameModal() {
return {
@@ -54,3 +56,15 @@ export function closeDeleteRackModal() {
type: CLOSE_DELETE_RACK_MODAL
};
}
+
+export function openDeleteMachineModal() {
+ return {
+ type: OPEN_DELETE_MACHINE_MODAL
+ };
+}
+
+export function closeDeleteMachineModal() {
+ return {
+ type: CLOSE_DELETE_MACHINE_MODAL
+ };
+}
diff --git a/src/actions/topology.js b/src/actions/topology.js
index 04d9f102..d5812ece 100644
--- a/src/actions/topology.js
+++ b/src/actions/topology.js
@@ -22,6 +22,7 @@ export const START_RACK_CONSTRUCTION = "START_RACK_CONSTRUCTION";
export const STOP_RACK_CONSTRUCTION = "STOP_RACK_CONSTRUCTION";
export const ADD_RACK_TO_TILE = "ADD_RACK_TO_TILE";
export const ADD_MACHINE = "ADD_MACHINE";
+export const DELETE_MACHINE = "DELETE_MACHINE";
export function fetchLatestDatacenter() {
return (dispatch, getState) => {
@@ -249,3 +250,20 @@ export function addMachineSucceeded(machine) {
dispatch(addPropToStoreObject("rack", rack.id, {machineIds}));
};
}
+
+export function deleteMachine() {
+ return {
+ type: DELETE_MACHINE
+ };
+}
+
+export function deleteMachineSucceeded() {
+ return (dispatch, getState) => {
+ const {interactionLevel, objects} = getState();
+ const rack = objects.rack[objects.tile[interactionLevel.tileId].objectId];
+ const machineIds = [...rack.machineIds];
+ machineIds[interactionLevel.position - 1] = null;
+ dispatch(goDownOneInteractionLevel());
+ dispatch(addPropToStoreObject("rack", rack.id, {machineIds}));
+ };
+}
diff --git a/src/components/home/JumbotronHeader.sass b/src/components/home/JumbotronHeader.sass
index 51eb0578..07151cf2 100644
--- a/src/components/home/JumbotronHeader.sass
+++ b/src/components/home/JumbotronHeader.sass
@@ -5,6 +5,9 @@
background-color: inherit
margin-bottom: 0
+ padding-top: 100px
+ padding-bottom: 100px
+
.jumbotron h1
color: #eee
diff --git a/src/components/map/groups/RoomGroup.js b/src/components/map/groups/RoomGroup.js
index 1c42106a..7c8392aa 100644
--- a/src/components/map/groups/RoomGroup.js
+++ b/src/components/map/groups/RoomGroup.js
@@ -19,7 +19,8 @@ const RoomGroup = ({room, interactionLevel, currentRoomInConstruction, onClick})
return (
<Group onClick={onClick}>
{(() => {
- if (interactionLevel.mode === "RACK" && interactionLevel.roomId === room.id) {
+ if ((interactionLevel.mode === "RACK" || interactionLevel.mode === "MACHINE")
+ && interactionLevel.roomId === room.id) {
return [
room.tileIds
.filter(tileId => tileId !== interactionLevel.tileId)
diff --git a/src/components/sidebars/topology/TopologySidebarComponent.js b/src/components/sidebars/topology/TopologySidebarComponent.js
index bc23d320..36f2ecc1 100644
--- a/src/components/sidebars/topology/TopologySidebarComponent.js
+++ b/src/components/sidebars/topology/TopologySidebarComponent.js
@@ -2,6 +2,7 @@ import React from "react";
import BuildingSidebarContainer from "../../../containers/sidebars/topology/building/BuildingSidebarContainer";
import RoomSidebarContainer from "../../../containers/sidebars/topology/room/RoomSidebarContainer";
import Sidebar from "../Sidebar";
+import MachineSidebarComponent from "./machine/MachineSidebarComponent";
import RackSidebarComponent from "./rack/RackSidebarComponent";
const TopologySidebarComponent = ({interactionLevel}) => {
@@ -17,6 +18,9 @@ const TopologySidebarComponent = ({interactionLevel}) => {
case "RACK":
sidebarContent = <RackSidebarComponent/>;
break;
+ case "MACHINE":
+ sidebarContent = <MachineSidebarComponent/>;
+ break;
default:
sidebarContent = "Missing Content";
}
diff --git a/src/components/sidebars/topology/machine/BackToRackComponent.js b/src/components/sidebars/topology/machine/BackToRackComponent.js
new file mode 100644
index 00000000..a602d242
--- /dev/null
+++ b/src/components/sidebars/topology/machine/BackToRackComponent.js
@@ -0,0 +1,9 @@
+import React from "react";
+
+const BackToRackComponent = ({onClick}) => (
+ <div className="btn btn-secondary btn-block" onClick={onClick}>
+ Back to rack
+ </div>
+);
+
+export default BackToRackComponent;
diff --git a/src/components/sidebars/topology/machine/DeleteMachineComponent.js b/src/components/sidebars/topology/machine/DeleteMachineComponent.js
new file mode 100644
index 00000000..f6fd39da
--- /dev/null
+++ b/src/components/sidebars/topology/machine/DeleteMachineComponent.js
@@ -0,0 +1,11 @@
+import React from "react";
+
+const DeleteMachineComponent = ({onClick}) => {
+ return (
+ <div className="btn btn-danger btn-block" onClick={onClick}>
+ Delete this machine
+ </div>
+ );
+};
+
+export default DeleteMachineComponent;
diff --git a/src/components/sidebars/topology/machine/MachineNameComponent.js b/src/components/sidebars/topology/machine/MachineNameComponent.js
new file mode 100644
index 00000000..321e350d
--- /dev/null
+++ b/src/components/sidebars/topology/machine/MachineNameComponent.js
@@ -0,0 +1,7 @@
+import React from "react";
+
+const MachineNameComponent = ({position}) => (
+ <h2>Machine at slot {position}</h2>
+);
+
+export default MachineNameComponent;
diff --git a/src/components/sidebars/topology/machine/MachineSidebarComponent.js b/src/components/sidebars/topology/machine/MachineSidebarComponent.js
new file mode 100644
index 00000000..117db784
--- /dev/null
+++ b/src/components/sidebars/topology/machine/MachineSidebarComponent.js
@@ -0,0 +1,16 @@
+import React from "react";
+import BackToRackContainer from "../../../../containers/sidebars/topology/machine/BackToRackContainer";
+import DeleteMachineContainer from "../../../../containers/sidebars/topology/machine/DeleteMachineContainer";
+import MachineNameContainer from "../../../../containers/sidebars/topology/machine/MachineNameContainer";
+
+const MachineSidebarComponent = () => {
+ return (
+ <div>
+ <MachineNameContainer/>
+ <BackToRackContainer/>
+ <DeleteMachineContainer/>
+ </div>
+ );
+};
+
+export default MachineSidebarComponent;
diff --git a/src/containers/modals/DeleteMachineModal.js b/src/containers/modals/DeleteMachineModal.js
new file mode 100644
index 00000000..aeb42024
--- /dev/null
+++ b/src/containers/modals/DeleteMachineModal.js
@@ -0,0 +1,36 @@
+import React from "react";
+import {connect} from "react-redux";
+import {closeDeleteMachineModal} from "../../actions/modals/topology";
+import {deleteMachine} from "../../actions/topology";
+import ConfirmationModal from "../../components/modals/ConfirmationModal";
+
+const DeleteMachineModalComponent = ({visible, callback}) => (
+ <ConfirmationModal title="Delete this machine"
+ message="Are you sure you want to delete this machine?"
+ show={visible}
+ callback={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/src/containers/sidebars/topology/machine/BackToRackContainer.js b/src/containers/sidebars/topology/machine/BackToRackContainer.js
new file mode 100644
index 00000000..9f31fab9
--- /dev/null
+++ b/src/containers/sidebars/topology/machine/BackToRackContainer.js
@@ -0,0 +1,16 @@
+import {connect} from "react-redux";
+import {goDownOneInteractionLevel} from "../../../../actions/interaction-level";
+import BackToRackComponent from "../../../../components/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/sidebars/topology/machine/DeleteMachineContainer.js b/src/containers/sidebars/topology/machine/DeleteMachineContainer.js
new file mode 100644
index 00000000..0c18598b
--- /dev/null
+++ b/src/containers/sidebars/topology/machine/DeleteMachineContainer.js
@@ -0,0 +1,16 @@
+import {connect} from "react-redux";
+import {openDeleteMachineModal} from "../../../../actions/modals/topology";
+import DeleteMachineComponent from "../../../../components/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/sidebars/topology/machine/MachineNameContainer.js b/src/containers/sidebars/topology/machine/MachineNameContainer.js
new file mode 100644
index 00000000..8e5413ef
--- /dev/null
+++ b/src/containers/sidebars/topology/machine/MachineNameContainer.js
@@ -0,0 +1,14 @@
+import {connect} from "react-redux";
+import MachineNameComponent from "../../../../components/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/sidebars/topology/rack/MachineContainer.js b/src/containers/sidebars/topology/rack/MachineContainer.js
index 74a0bfbc..21ab06c4 100644
--- a/src/containers/sidebars/topology/rack/MachineContainer.js
+++ b/src/containers/sidebars/topology/rack/MachineContainer.js
@@ -1,4 +1,5 @@
import {connect} from "react-redux";
+import {goFromRackToMachine} from "../../../../actions/interaction-level";
import MachineComponent from "../../../../components/sidebars/topology/rack/MachineComponent";
const mapStateToProps = (state, ownProps) => {
@@ -7,9 +8,9 @@ const mapStateToProps = (state, ownProps) => {
};
};
-const mapDispatchToProps = dispatch => {
+const mapDispatchToProps = (dispatch, ownProps) => {
return {
- onClick: () => undefined, // TODO implement transition to MACHINE mode
+ onClick: () => dispatch(goFromRackToMachine(ownProps.position)),
};
};
diff --git a/src/pages/App.js b/src/pages/App.js
index 3aaab454..c8e22775 100644
--- a/src/pages/App.js
+++ b/src/pages/App.js
@@ -6,6 +6,7 @@ import {openSimulationSucceeded} from "../actions/simulations";
import {fetchLatestDatacenter, resetCurrentDatacenter} from "../actions/topology";
import MapStage from "../components/map/MapStage";
import AppNavbar from "../components/navigation/AppNavbar";
+import DeleteMachineModal from "../containers/modals/DeleteMachineModal";
import DeleteRackModal from "../containers/modals/DeleteRackModal";
import DeleteRoomModal from "../containers/modals/DeleteRoomModal";
import EditRackNameModal from "../containers/modals/EditRackNameModal";
@@ -47,6 +48,7 @@ class AppContainer extends React.Component {
<DeleteRoomModal/>
<EditRackNameModal/>
<DeleteRackModal/>
+ <DeleteMachineModal/>
</div>
);
}
diff --git a/src/reducers/interaction-level.js b/src/reducers/interaction-level.js
index b6287aac..a3f3de7f 100644
--- a/src/reducers/interaction-level.js
+++ b/src/reducers/interaction-level.js
@@ -1,6 +1,7 @@
import {
GO_DOWN_ONE_INTERACTION_LEVEL,
GO_FROM_BUILDING_TO_ROOM,
+ GO_FROM_RACK_TO_MACHINE,
GO_FROM_ROOM_TO_RACK
} from "../actions/interaction-level";
@@ -17,6 +18,13 @@ export function interactionLevel(state = {mode: "BUILDING"}, action) {
roomId: state.roomId,
tileId: action.tileId
};
+ case GO_FROM_RACK_TO_MACHINE:
+ return {
+ mode: "MACHINE",
+ roomId: state.roomId,
+ tileId: state.tileId,
+ position: action.position,
+ };
case GO_DOWN_ONE_INTERACTION_LEVEL:
if (state.mode === "ROOM") {
return {
@@ -27,6 +35,12 @@ export function interactionLevel(state = {mode: "BUILDING"}, action) {
mode: "ROOM",
roomId: state.roomId
};
+ } else if (state.mode === "MACHINE") {
+ return {
+ mode: "RACK",
+ roomId: state.roomId,
+ tileId: state.tileId
+ };
} else {
return state;
}
diff --git a/src/reducers/modals.js b/src/reducers/modals.js
index 7a89dae5..0dafcde4 100644
--- a/src/reducers/modals.js
+++ b/src/reducers/modals.js
@@ -2,10 +2,12 @@ import {combineReducers} from "redux";
import {CLOSE_DELETE_PROFILE_MODAL, OPEN_DELETE_PROFILE_MODAL} from "../actions/modals/profile";
import {CLOSE_NEW_SIMULATION_MODAL, OPEN_NEW_SIMULATION_MODAL} from "../actions/modals/simulations";
import {
+ CLOSE_DELETE_MACHINE_MODAL,
CLOSE_DELETE_RACK_MODAL,
CLOSE_DELETE_ROOM_MODAL,
CLOSE_EDIT_RACK_NAME_MODAL,
CLOSE_EDIT_ROOM_NAME_MODAL,
+ OPEN_DELETE_MACHINE_MODAL,
OPEN_DELETE_RACK_MODAL,
OPEN_DELETE_ROOM_MODAL,
OPEN_EDIT_RACK_NAME_MODAL,
@@ -32,4 +34,5 @@ export const modals = combineReducers({
deleteRoomModalVisible: modal(OPEN_DELETE_ROOM_MODAL, CLOSE_DELETE_ROOM_MODAL),
editRackNameModalVisible: modal(OPEN_EDIT_RACK_NAME_MODAL, CLOSE_EDIT_RACK_NAME_MODAL),
deleteRackModalVisible: modal(OPEN_DELETE_RACK_MODAL, CLOSE_DELETE_RACK_MODAL),
+ deleteMachineModalVisible: modal(OPEN_DELETE_MACHINE_MODAL, CLOSE_DELETE_MACHINE_MODAL),
});
diff --git a/src/sagas/index.js b/src/sagas/index.js
index e6c48da4..91b8a024 100644
--- a/src/sagas/index.js
+++ b/src/sagas/index.js
@@ -6,6 +6,7 @@ import {
ADD_RACK_TO_TILE,
ADD_TILE,
CANCEL_NEW_ROOM_CONSTRUCTION,
+ DELETE_MACHINE,
DELETE_RACK,
DELETE_ROOM,
DELETE_TILE,
@@ -22,6 +23,7 @@ import {
onAddRackToTile,
onAddTile,
onCancelNewRoomConstruction,
+ onDeleteMachine,
onDeleteRack,
onDeleteRoom,
onDeleteTile,
@@ -49,4 +51,5 @@ export default function* rootSaga() {
yield takeEvery(DELETE_RACK, onDeleteRack);
yield takeEvery(ADD_RACK_TO_TILE, onAddRackToTile);
yield takeEvery(ADD_MACHINE, onAddMachine);
+ yield takeEvery(DELETE_MACHINE, onDeleteMachine);
}
diff --git a/src/sagas/topology.js b/src/sagas/topology.js
index 87d20e8f..05bebc6c 100644
--- a/src/sagas/topology.js
+++ b/src/sagas/topology.js
@@ -5,6 +5,7 @@ import {
addRackToTileSucceeded,
addTileSucceeded,
cancelNewRoomConstructionSucceeded,
+ deleteMachineSucceeded,
deleteRackSucceeded,
deleteRoomSucceeded,
deleteTileSucceeded,
@@ -18,6 +19,7 @@ import {addTileToRoom, deleteRoom, updateRoom} from "../api/routes/rooms";
import {
addMachineToRackOnTile,
addRackToTile,
+ deleteMachineInRackOnTile,
deleteRackFromTile,
deleteTile,
updateRackOnTile
@@ -253,3 +255,14 @@ export function* onAddMachine(action) {
console.log(error);
}
}
+
+export function* onDeleteMachine() {
+ try {
+ const tileId = yield select(state => state.interactionLevel.tileId);
+ const position = yield select(state => state.interactionLevel.position);
+ yield call(deleteMachineInRackOnTile, tileId, position);
+ yield put(deleteMachineSucceeded());
+ } catch (error) {
+ console.log(error);
+ }
+}