From 17ae0a3fafd806a5a533bf1d51a3ac708a8cf978 Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Fri, 1 Sep 2017 16:42:13 +0200 Subject: Implement room name edit --- src/actions/modals/profile.js | 14 ++++++++ src/actions/modals/simulations.js | 14 ++++++++ src/actions/modals/topology.js | 14 ++++++++ src/actions/profile.js | 13 +------- src/actions/simulations.js | 14 -------- src/actions/topology.js | 27 ++++++++------- src/components/modals/TextInputModal.js | 15 ++++++--- src/components/navigation/Navbar.js | 2 +- src/containers/modals/DeleteProfileModal.js | 36 ++++++++++++++++++++ src/containers/modals/EditRoomNameModal.js | 38 ++++++++++++++++++++++ src/containers/modals/NewSimulationModal.js | 35 ++++++++++++++++++++ src/containers/profile/DeleteProfileModal.js | 36 -------------------- .../sidebars/topology/room/RoomNameContainer.js | 3 +- src/containers/simulations/NewSimulationModal.js | 34 ------------------- src/pages/App.js | 2 ++ src/pages/Profile.js | 4 +-- src/pages/Simulations.js | 5 +-- src/reducers/modals.js | 17 ++++++++-- src/reducers/objects.js | 8 ++++- src/sagas/index.js | 3 ++ src/sagas/topology.js | 15 ++++++++- 21 files changed, 228 insertions(+), 121 deletions(-) create mode 100644 src/actions/modals/profile.js create mode 100644 src/actions/modals/simulations.js create mode 100644 src/actions/modals/topology.js create mode 100644 src/containers/modals/DeleteProfileModal.js create mode 100644 src/containers/modals/EditRoomNameModal.js create mode 100644 src/containers/modals/NewSimulationModal.js delete mode 100644 src/containers/profile/DeleteProfileModal.js delete mode 100644 src/containers/simulations/NewSimulationModal.js diff --git a/src/actions/modals/profile.js b/src/actions/modals/profile.js new file mode 100644 index 00000000..421e7602 --- /dev/null +++ b/src/actions/modals/profile.js @@ -0,0 +1,14 @@ +export const OPEN_DELETE_PROFILE_MODAL = "OPEN_DELETE_PROFILE_MODAL"; +export const CLOSE_DELETE_PROFILE_MODAL = "CLOSE_DELETE_PROFILE_MODAL"; + +export function openDeleteProfileModal() { + return { + type: OPEN_DELETE_PROFILE_MODAL + }; +} + +export function closeDeleteProfileModal() { + return { + type: CLOSE_DELETE_PROFILE_MODAL + }; +} diff --git a/src/actions/modals/simulations.js b/src/actions/modals/simulations.js new file mode 100644 index 00000000..53d2c565 --- /dev/null +++ b/src/actions/modals/simulations.js @@ -0,0 +1,14 @@ +export const OPEN_NEW_SIMULATION_MODAL = "OPEN_NEW_SIMULATION_MODAL"; +export const CLOSE_NEW_SIMULATION_MODAL = "CLOSE_SIMULATION_POPUP"; + +export function openNewSimulationModal() { + return { + type: OPEN_NEW_SIMULATION_MODAL + }; +} + +export function closeNewSimulationModal() { + return { + type: CLOSE_NEW_SIMULATION_MODAL + }; +} diff --git a/src/actions/modals/topology.js b/src/actions/modals/topology.js new file mode 100644 index 00000000..5e3fc803 --- /dev/null +++ b/src/actions/modals/topology.js @@ -0,0 +1,14 @@ +export const OPEN_EDIT_ROOM_NAME_MODAL = "OPEN_EDIT_ROOM_NAME_MODAL"; +export const CLOSE_EDIT_ROOM_NAME_MODAL = "CLOSE_EDIT_ROOM_NAME_MODAL"; + +export function openEditRoomNameModal() { + return { + type: OPEN_EDIT_ROOM_NAME_MODAL + }; +} + +export function closeEditRoomNameModal() { + return { + type: CLOSE_EDIT_ROOM_NAME_MODAL + }; +} diff --git a/src/actions/profile.js b/src/actions/profile.js index 421e7602..b28b04f6 100644 --- a/src/actions/profile.js +++ b/src/actions/profile.js @@ -1,14 +1,3 @@ -export const OPEN_DELETE_PROFILE_MODAL = "OPEN_DELETE_PROFILE_MODAL"; -export const CLOSE_DELETE_PROFILE_MODAL = "CLOSE_DELETE_PROFILE_MODAL"; -export function openDeleteProfileModal() { - return { - type: OPEN_DELETE_PROFILE_MODAL - }; -} -export function closeDeleteProfileModal() { - return { - type: CLOSE_DELETE_PROFILE_MODAL - }; -} + diff --git a/src/actions/simulations.js b/src/actions/simulations.js index 2e722d16..145ceab2 100644 --- a/src/actions/simulations.js +++ b/src/actions/simulations.js @@ -1,6 +1,4 @@ export const SET_AUTH_VISIBILITY_FILTER = "SET_AUTH_VISIBILITY_FILTER"; -export const OPEN_NEW_SIMULATION_MODAL = "OPEN_NEW_SIMULATION_MODAL"; -export const CLOSE_NEW_SIMULATION_MODAL = "CLOSE_SIMULATION_POPUP"; export const ADD_SIMULATION = "ADD_SIMULATION"; export const ADD_SIMULATION_SUCCEEDED = "ADD_SIMULATION_SUCCEEDED"; export const DELETE_SIMULATION = "DELETE_SIMULATION"; @@ -14,18 +12,6 @@ export function setAuthVisibilityFilter(filter) { }; } -export function openNewSimulationModal() { - return { - type: OPEN_NEW_SIMULATION_MODAL - }; -} - -export function closeNewSimulationModal() { - return { - type: CLOSE_NEW_SIMULATION_MODAL - }; -} - export function addSimulation(name) { return (dispatch, getState) => { const {auth} = getState(); diff --git a/src/actions/topology.js b/src/actions/topology.js index 76b1ef27..79f1bfb5 100644 --- a/src/actions/topology.js +++ b/src/actions/topology.js @@ -1,4 +1,4 @@ -import {addIdToStoreObjectListProp, removeIdFromStoreObjectListProp} from "./objects"; +import {addIdToStoreObjectListProp, addPropToStoreObject, removeIdFromStoreObjectListProp} from "./objects"; export const FETCH_TOPOLOGY_OF_DATACENTER = "FETCH_TOPOLOGY_OF_DATACENTER"; export const FETCH_TOPOLOGY_OF_DATACENTER_SUCCEEDED = "FETCH_TOPOLOGY_OF_DATACENTER_SUCCEEDED"; @@ -10,9 +10,8 @@ export const FINISH_NEW_ROOM_CONSTRUCTION = "FINISH_NEW_ROOM_CONSTRUCTION"; export const CANCEL_NEW_ROOM_CONSTRUCTION = "CANCEL_NEW_ROOM_CONSTRUCTION"; export const CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED = "CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED"; export const ADD_TILE = "ADD_TILE"; -export const ADD_TILE_SUCCEEDED = "ADD_TILE_SUCCEEDED"; export const DELETE_TILE = "DELETE_TILE"; -export const DELETE_TILE_SUCCEEDED = "DELETE_TILE_SUCCEEDED"; +export const EDIT_ROOM_NAME = "EDIT_ROOM_NAME"; export function fetchLatestDatacenter() { return (dispatch, getState) => { @@ -107,10 +106,6 @@ export function addTileSucceeded(tileId) { return (dispatch, getState) => { const {currentRoomInConstruction} = getState(); dispatch(addIdToStoreObjectListProp("room", currentRoomInConstruction, "tileIds", tileId)); - dispatch({ - type: ADD_TILE_SUCCEEDED, - tileId - }); }; } @@ -125,9 +120,19 @@ export function deleteTileSucceeded(tileId) { return (dispatch, getState) => { const {currentRoomInConstruction} = getState(); dispatch(removeIdFromStoreObjectListProp("room", currentRoomInConstruction, "tileIds", tileId)); - dispatch({ - type: DELETE_TILE_SUCCEEDED, - tileId - }); + }; +} + +export function editRoomName(name) { + return { + type: EDIT_ROOM_NAME, + name + }; +} + +export function editRoomNameSucceeded(name) { + return (dispatch, getState) => { + const {interactionLevel} = getState(); + dispatch(addPropToStoreObject("room", interactionLevel.roomId, {name})); }; } diff --git a/src/components/modals/TextInputModal.js b/src/components/modals/TextInputModal.js index 97986fe2..e4a55372 100644 --- a/src/components/modals/TextInputModal.js +++ b/src/components/modals/TextInputModal.js @@ -11,14 +11,20 @@ class TextInputModal extends React.Component { initialValue: PropTypes.string, }; + componentDidUpdate() { + if (this.props.initialValue) { + this.textInput.value = this.props.initialValue; + } + } + onSubmit() { - this.props.callback(this.refs.textInput.value); - this.refs.textInput.value = ""; + this.props.callback(this.textInput.value); + this.textInput.value = ""; } onCancel() { this.props.callback(undefined); - this.refs.textInput.value = ""; + this.textInput.value = ""; } render() { @@ -33,7 +39,8 @@ class TextInputModal extends React.Component { }}>
- + this.textInput = textInput}/>
diff --git a/src/components/navigation/Navbar.js b/src/components/navigation/Navbar.js index 68fa2ab1..2358e146 100644 --- a/src/components/navigation/Navbar.js +++ b/src/components/navigation/Navbar.js @@ -7,7 +7,7 @@ import Logout from "../../containers/auth/Logout"; import ProfileName from "../../containers/auth/ProfileName"; import "./Navbar.css"; -export const NAVBAR_HEIGHT = 62; +export const NAVBAR_HEIGHT = 60; export const NavItem = withRouter(props => ); export const LoggedInSection = withRouter(props => ); diff --git a/src/containers/modals/DeleteProfileModal.js b/src/containers/modals/DeleteProfileModal.js new file mode 100644 index 00000000..0108a1eb --- /dev/null +++ b/src/containers/modals/DeleteProfileModal.js @@ -0,0 +1,36 @@ +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 NewSimulationModalComponent = ({visible, callback}) => ( + +); + +const mapStateToProps = state => { + return { + visible: state.modals.deleteProfileModalVisible + }; +}; + +const mapDispatchToProps = dispatch => { + return { + callback: (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteCurrentUser()); + } + dispatch(closeDeleteProfileModal()); + } + }; +}; + +const NewSimulationModal = connect( + mapStateToProps, + mapDispatchToProps +)(NewSimulationModalComponent); + +export default NewSimulationModal; diff --git a/src/containers/modals/EditRoomNameModal.js b/src/containers/modals/EditRoomNameModal.js new file mode 100644 index 00000000..649ffeda --- /dev/null +++ b/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"; +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/src/containers/modals/NewSimulationModal.js b/src/containers/modals/NewSimulationModal.js new file mode 100644 index 00000000..d85b59ef --- /dev/null +++ b/src/containers/modals/NewSimulationModal.js @@ -0,0 +1,35 @@ +import React from "react"; +import {connect} from "react-redux"; +import {closeNewSimulationModal} from "../../actions/modals/simulations"; +import {addSimulation} from "../../actions/simulations"; +import TextInputModal from "../../components/modals/TextInputModal"; + +const NewSimulationModalComponent = ({visible, callback}) => ( + +); + +const mapStateToProps = state => { + return { + visible: state.modals.newSimulationModalVisible + }; +}; + +const mapDispatchToProps = dispatch => { + return { + callback: (text) => { + if (text) { + dispatch(addSimulation(text)); + } + dispatch(closeNewSimulationModal()); + } + }; +}; + +const NewSimulationModal = connect( + mapStateToProps, + mapDispatchToProps +)(NewSimulationModalComponent); + +export default NewSimulationModal; diff --git a/src/containers/profile/DeleteProfileModal.js b/src/containers/profile/DeleteProfileModal.js deleted file mode 100644 index b59db055..00000000 --- a/src/containers/profile/DeleteProfileModal.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from "react"; -import {connect} from "react-redux"; -import {closeDeleteProfileModal} from "../../actions/profile"; -import {deleteCurrentUser} from "../../actions/users"; -import ConfirmationModal from "../../components/modals/ConfirmationModal"; - -const NewSimulationModalComponent = ({visible, callback}) => ( - -); - -const mapStateToProps = state => { - return { - visible: state.modals.deleteProfileModalVisible - }; -}; - -const mapDispatchToProps = dispatch => { - return { - callback: (isConfirmed) => { - if (isConfirmed) { - dispatch(deleteCurrentUser()); - } - dispatch(closeDeleteProfileModal()); - } - }; -}; - -const NewSimulationModal = connect( - mapStateToProps, - mapDispatchToProps -)(NewSimulationModalComponent); - -export default NewSimulationModal; diff --git a/src/containers/sidebars/topology/room/RoomNameContainer.js b/src/containers/sidebars/topology/room/RoomNameContainer.js index 5408cb6c..7b9dc249 100644 --- a/src/containers/sidebars/topology/room/RoomNameContainer.js +++ b/src/containers/sidebars/topology/room/RoomNameContainer.js @@ -1,4 +1,5 @@ import {connect} from "react-redux"; +import {openEditRoomNameModal} from "../../../../actions/modals/topology"; import RoomNameComponent from "../../../../components/sidebars/topology/room/RoomNameComponent"; const mapStateToProps = state => { @@ -9,7 +10,7 @@ const mapStateToProps = state => { const mapDispatchToProps = dispatch => { return { - onEdit: () => dispatch(null), // FIXME + onEdit: () => dispatch(openEditRoomNameModal()), }; }; diff --git a/src/containers/simulations/NewSimulationModal.js b/src/containers/simulations/NewSimulationModal.js deleted file mode 100644 index cb858fed..00000000 --- a/src/containers/simulations/NewSimulationModal.js +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import {connect} from "react-redux"; -import {addSimulation, closeNewSimulationModal} from "../../actions/simulations"; -import TextInputModal from "../../components/modals/TextInputModal"; - -const NewSimulationModalComponent = ({visible, callback}) => ( - -); - -const mapStateToProps = state => { - return { - visible: state.modals.newSimulationModalVisible - }; -}; - -const mapDispatchToProps = dispatch => { - return { - callback: (text) => { - if (text) { - dispatch(addSimulation(text)); - } - dispatch(closeNewSimulationModal()); - } - }; -}; - -const NewSimulationModal = connect( - mapStateToProps, - mapDispatchToProps -)(NewSimulationModalComponent); - -export default NewSimulationModal; diff --git a/src/pages/App.js b/src/pages/App.js index a6f4dad4..7f690002 100644 --- a/src/pages/App.js +++ b/src/pages/App.js @@ -5,6 +5,7 @@ import {openSimulationSucceeded} from "../actions/simulations"; import {fetchLatestDatacenter} from "../actions/topology"; import MapStage from "../components/map/MapStage"; import AppNavbar from "../components/navigation/AppNavbar"; +import EditRoomNameModal from "../containers/modals/EditRoomNameModal"; import TopologySidebar from "../containers/sidebars/topology/TopologySidebar"; class AppContainer extends React.Component { @@ -25,6 +26,7 @@ class AppContainer extends React.Component { + ); } diff --git a/src/pages/Profile.js b/src/pages/Profile.js index 4f69b408..ca09d0f4 100644 --- a/src/pages/Profile.js +++ b/src/pages/Profile.js @@ -1,8 +1,8 @@ import React from 'react'; import {connect} from "react-redux"; -import {openDeleteProfileModal} from "../actions/profile"; +import {openDeleteProfileModal} from "../actions/modals/profile"; import AppNavbar from "../components/navigation/AppNavbar"; -import DeleteProfileModal from "../containers/profile/DeleteProfileModal"; +import DeleteProfileModal from "../containers/modals/DeleteProfileModal"; const ProfileContainer = ({onDelete}) => (
diff --git a/src/pages/Simulations.js b/src/pages/Simulations.js index 52551139..c04c74ae 100644 --- a/src/pages/Simulations.js +++ b/src/pages/Simulations.js @@ -1,11 +1,12 @@ import React from 'react'; import {connect} from "react-redux"; -import {addSimulation, openNewSimulationModal} from "../actions/simulations"; +import {openNewSimulationModal} from "../actions/modals/simulations"; +import {addSimulation} from "../actions/simulations"; import {fetchAuthorizationsOfCurrentUser} from "../actions/users"; import AppNavbar from "../components/navigation/AppNavbar"; import SimulationFilterPanel from "../components/simulations/FilterPanel"; import NewSimulationButton from "../components/simulations/NewSimulationButton"; -import NewSimulationModal from "../containers/simulations/NewSimulationModal"; +import NewSimulationModal from "../containers/modals/NewSimulationModal"; import VisibleSimulationList from "../containers/simulations/VisibleSimulationAuthList"; class SimulationsContainer extends React.Component { diff --git a/src/reducers/modals.js b/src/reducers/modals.js index e74b66b9..1786bb87 100644 --- a/src/reducers/modals.js +++ b/src/reducers/modals.js @@ -1,6 +1,7 @@ import {combineReducers} from "redux"; -import {CLOSE_DELETE_PROFILE_MODAL, OPEN_DELETE_PROFILE_MODAL} from "../actions/profile"; -import {CLOSE_NEW_SIMULATION_MODAL, OPEN_NEW_SIMULATION_MODAL} from "../actions/simulations"; +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_EDIT_ROOM_NAME_MODAL, OPEN_EDIT_ROOM_NAME_MODAL} from "../actions/modals/topology"; function newSimulationModalVisible(state = false, action) { switch (action.type) { @@ -24,7 +25,19 @@ function deleteProfileModalVisible(state = false, action) { } } +function editRoomNameModalVisible(state = false, action) { + switch (action.type) { + case OPEN_EDIT_ROOM_NAME_MODAL: + return true; + case CLOSE_EDIT_ROOM_NAME_MODAL: + return false; + default: + return state; + } +} + export const modals = combineReducers({ newSimulationModalVisible, deleteProfileModalVisible, + editRoomNameModalVisible, }); diff --git a/src/reducers/objects.js b/src/reducers/objects.js index 801a5456..b75e9ae6 100644 --- a/src/reducers/objects.js +++ b/src/reducers/objects.js @@ -46,7 +46,13 @@ function objectWithId(type, getId) { return Object.assign( {}, state, - {[action.objectId]: Object.assign(state[action.objectId], action.propObject)} + { + [action.objectId]: Object.assign( + {}, + state[action.objectId], + action.propObject + ) + } ); } else if (action.type === ADD_ID_TO_STORE_OBJECT_LIST_PROP) { return Object.assign( diff --git a/src/sagas/index.js b/src/sagas/index.js index 7c1d921f..a076736c 100644 --- a/src/sagas/index.js +++ b/src/sagas/index.js @@ -5,6 +5,7 @@ import { ADD_TILE, CANCEL_NEW_ROOM_CONSTRUCTION, DELETE_TILE, + EDIT_ROOM_NAME, FETCH_LATEST_DATACENTER, START_NEW_ROOM_CONSTRUCTION } from "../actions/topology"; @@ -15,6 +16,7 @@ import { onAddTile, onCancelNewRoomConstruction, onDeleteTile, + onEditRoomName, onFetchLatestDatacenter, onStartNewRoomConstruction } from "./topology"; @@ -31,4 +33,5 @@ export default function* rootSaga() { yield takeEvery(CANCEL_NEW_ROOM_CONSTRUCTION, onCancelNewRoomConstruction); yield takeEvery(ADD_TILE, onAddTile); yield takeEvery(DELETE_TILE, onDeleteTile); + yield takeEvery(EDIT_ROOM_NAME, onEditRoomName); } diff --git a/src/sagas/topology.js b/src/sagas/topology.js index 815cd842..c029c861 100644 --- a/src/sagas/topology.js +++ b/src/sagas/topology.js @@ -4,11 +4,12 @@ import { addTileSucceeded, cancelNewRoomConstructionSucceeded, deleteTileSucceeded, + editRoomNameSucceeded, fetchLatestDatacenterSucceeded, startNewRoomConstructionSucceeded } from "../actions/topology"; import {addRoomToDatacenter} from "../api/routes/datacenters"; -import {addTileToRoom, deleteRoom} from "../api/routes/rooms"; +import {addTileToRoom, deleteRoom, updateRoom} from "../api/routes/rooms"; import {deleteTile} from "../api/routes/tiles"; import { fetchAndStoreCoolingItem, @@ -129,3 +130,15 @@ export function* onDeleteTile(action) { console.log(error); } } + +export function* onEditRoomName(action) { + try { + const roomId = yield select(state => state.interactionLevel.roomId); + const room = Object.assign({}, yield select(state => state.objects.room[roomId])); + room.name = action.name; + yield call(updateRoom, room); + yield put(editRoomNameSucceeded(action.name)); + } catch (error) { + console.log(error); + } +} -- cgit v1.2.3