summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/containers/app
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-05-13 17:42:53 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-05-17 17:06:50 +0200
commit1edbae1a0224e30bafb98638f419e1f967a9286f (patch)
tree2047c5a684379dfd395891e9447199f6001cef9b /opendc-web/opendc-web-ui/src/containers/app
parent1891a6f3963d3ddeae0ea093f9a7e3608a97b4d7 (diff)
ui: Move modal state outside of Redux
This change updates the frontend so that the modal state is not stored inside Redux but instead is stored using the useState hook. This simplifies the design of the modal components.
Diffstat (limited to 'opendc-web/opendc-web-ui/src/containers/app')
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/App.js20
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js4
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js56
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js79
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js63
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js31
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js5
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js31
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js29
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js32
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js28
-rw-r--r--opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js30
12 files changed, 272 insertions, 136 deletions
diff --git a/opendc-web/opendc-web-ui/src/containers/app/App.js b/opendc-web/opendc-web-ui/src/containers/app/App.js
index bb9c5d56..432435cf 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/App.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/App.js
@@ -32,26 +32,18 @@ import LoadingScreen from '../../components/app/map/LoadingScreen'
import ScaleIndicatorContainer from '../../containers/app/map/controls/ScaleIndicatorContainer'
import MapStage from '../../containers/app/map/MapStage'
import TopologySidebarContainer from '../../containers/app/sidebars/topology/TopologySidebarContainer'
-import DeleteMachineModal from '../../containers/modals/DeleteMachineModal'
-import DeleteRackModal from '../../containers/modals/DeleteRackModal'
-import DeleteRoomModal from '../../containers/modals/DeleteRoomModal'
-import EditRackNameModal from '../../containers/modals/EditRackNameModal'
-import EditRoomNameModal from '../../containers/modals/EditRoomNameModal'
-import NewTopologyModal from '../../containers/modals/NewTopologyModal'
import AppNavbarContainer from '../../containers/navigation/AppNavbarContainer'
import ProjectSidebarContainer from '../../containers/app/sidebars/project/ProjectSidebarContainer'
import { openScenarioSucceeded } from '../../actions/scenarios'
-import NewPortfolioModal from '../../containers/modals/NewPortfolioModal'
-import NewScenarioModal from '../../containers/modals/NewScenarioModal'
import PortfolioResultsContainer from '../../containers/app/results/PortfolioResultsContainer'
import KeymapConfiguration from '../../shortcuts/keymap'
import { useRequireAuth } from '../../auth/hook'
-import { useProject } from '../../store/hooks/project'
+import { useActiveProject } from '../../store/hooks/project'
const App = ({ projectId, portfolioId, scenarioId }) => {
useRequireAuth()
- const projectName = useProject()?.name
+ const projectName = useActiveProject()?.name
const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1')
const dispatch = useDispatch()
@@ -106,14 +98,6 @@ const App = ({ projectId, portfolioId, scenarioId }) => {
</Head>
<AppNavbarContainer fullWidth={true} />
{scenarioId ? scenarioElements : portfolioId ? portfolioElements : constructionElements}
- <NewTopologyModal />
- <NewPortfolioModal />
- <NewScenarioModal />
- <EditRoomNameModal />
- <DeleteRoomModal />
- <EditRackNameModal />
- <DeleteRackModal />
- <DeleteMachineModal />
</HotKeys>
)
}
diff --git a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js
index 30379490..25fbe3c0 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/map/TopologyContainer.js
@@ -1,10 +1,10 @@
import React from 'react'
import { useSelector } from 'react-redux'
import TopologyGroup from '../../../components/app/map/groups/TopologyGroup'
-import { useTopology } from '../../../store/hooks/topology'
+import { useActiveTopology } from '../../../store/hooks/topology'
const TopologyContainer = () => {
- const topology = useTopology()
+ const topology = useActiveTopology()
const interactionLevel = useSelector((state) => state.interactionLevel)
return <TopologyGroup topology={topology} interactionLevel={interactionLevel} />
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js
index ce295f03..dca7d7db 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/PortfolioListContainer.js
@@ -1,34 +1,23 @@
-import React from 'react'
-import { useDispatch, useSelector } from 'react-redux'
+import React, { useState } from 'react'
+import { useDispatch } from 'react-redux'
import { useRouter } from 'next/router'
import PortfolioListComponent from '../../../../components/app/sidebars/project/PortfolioListComponent'
-import { deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios'
-import { openNewPortfolioModal } from '../../../../actions/modals/portfolios'
+import { addPortfolio, deletePortfolio, setCurrentPortfolio } from '../../../../actions/portfolios'
import { getState } from '../../../../util/state-utils'
import { setCurrentTopology } from '../../../../actions/topology/building'
+import NewPortfolioModalComponent from '../../../../components/modals/custom-components/NewPortfolioModalComponent'
+import { useActivePortfolio, useActiveProject, usePortfolios } from '../../../../store/hooks/project'
-const PortfolioListContainer = (props) => {
- const state = useSelector((state) => {
- let portfolios = state.objects.project[state.currentProjectId]
- ? state.objects.project[state.currentProjectId].portfolioIds.map((t) => state.objects.portfolio[t])
- : []
- if (portfolios.filter((t) => !t).length > 0) {
- portfolios = []
- }
-
- return {
- currentProjectId: state.currentProjectId,
- currentPortfolioId: state.currentPortfolioId,
- portfolios,
- }
- })
+const PortfolioListContainer = () => {
+ const currentProjectId = useActiveProject()?._id
+ const currentPortfolioId = useActivePortfolio()?._id
+ const portfolios = usePortfolios(currentProjectId)
const dispatch = useDispatch()
+ const [isVisible, setVisible] = useState(false)
const router = useRouter()
const actions = {
- onNewPortfolio: () => {
- dispatch(openNewPortfolioModal())
- },
+ onNewPortfolio: () => setVisible(true),
onChoosePortfolio: (portfolioId) => {
dispatch(setCurrentPortfolio(portfolioId))
},
@@ -41,7 +30,28 @@ const PortfolioListContainer = (props) => {
}
},
}
- return <PortfolioListComponent {...props} {...state} {...actions} />
+ const callback = (name, targets) => {
+ if (name) {
+ dispatch(
+ addPortfolio({
+ name,
+ targets,
+ })
+ )
+ }
+ setVisible(false)
+ }
+ return (
+ <>
+ <PortfolioListComponent
+ currentProjectId={currentProjectId}
+ currentPortfolioId={currentPortfolioId}
+ portfolios={portfolios}
+ {...actions}
+ />
+ <NewPortfolioModalComponent callback={callback} show={isVisible} />
+ </>
+ )
}
export default PortfolioListContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js
index 18d0735e..5d747820 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/ScenarioListContainer.js
@@ -1,28 +1,27 @@
-import React from 'react'
-import { useDispatch, useSelector } from 'react-redux'
+import React, { useState } from 'react'
+import { useDispatch } from 'react-redux'
import ScenarioListComponent from '../../../../components/app/sidebars/project/ScenarioListComponent'
-import { openNewScenarioModal } from '../../../../actions/modals/scenarios'
-import { deleteScenario, setCurrentScenario } from '../../../../actions/scenarios'
+import { addScenario, deleteScenario, setCurrentScenario } from '../../../../actions/scenarios'
import { setCurrentPortfolio } from '../../../../actions/portfolios'
+import NewScenarioModalComponent from '../../../../components/modals/custom-components/NewScenarioModalComponent'
+import { useProjectTopologies } from '../../../../store/hooks/topology'
+import { useActiveScenario, useActiveProject, useScenarios } from '../../../../store/hooks/project'
+import { useSchedulers, useTraces } from '../../../../store/hooks/experiments'
-const ScenarioListContainer = ({ portfolioId, children }) => {
- const currentProjectId = useSelector((state) => state.currentProjectId)
- const currentScenarioId = useSelector((state) => state.currentScenarioId)
- const scenarios = useSelector((state) => {
- let scenarios = state.objects.portfolio[portfolioId]
- ? state.objects.portfolio[portfolioId].scenarioIds.map((t) => state.objects.scenario[t])
- : []
- if (scenarios.filter((t) => !t).length > 0) {
- scenarios = []
- }
-
- return scenarios
- })
+const ScenarioListContainer = ({ portfolioId }) => {
+ const currentProjectId = useActiveProject()?._id
+ const currentScenarioId = useActiveScenario()?._id
+ const scenarios = useScenarios(portfolioId)
+ const topologies = useProjectTopologies()
+ const traces = useTraces()
+ const schedulers = useSchedulers()
const dispatch = useDispatch()
+ const [isVisible, setVisible] = useState(false)
+
const onNewScenario = (currentPortfolioId) => {
dispatch(setCurrentPortfolio(currentPortfolioId))
- dispatch(openNewScenarioModal())
+ setVisible(true)
}
const onChooseScenario = (portfolioId, scenarioId) => {
dispatch(setCurrentScenario(portfolioId, scenarioId))
@@ -32,17 +31,43 @@ const ScenarioListContainer = ({ portfolioId, children }) => {
dispatch(deleteScenario(id))
}
}
+ const callback = (name, portfolioId, trace, topology, operational) => {
+ if (name) {
+ dispatch(
+ addScenario({
+ portfolioId,
+ name,
+ trace,
+ topology,
+ operational,
+ })
+ )
+ }
+
+ setVisible(false)
+ }
return (
- <ScenarioListComponent
- portfolioId={portfolioId}
- currentProjectId={currentProjectId}
- currentScenarioId={currentScenarioId}
- scenarios={scenarios}
- onNewScenario={onNewScenario}
- onChooseScenario={onChooseScenario}
- onDeleteScenario={onDeleteScenario}
- />
+ <>
+ <ScenarioListComponent
+ portfolioId={portfolioId}
+ currentProjectId={currentProjectId}
+ currentScenarioId={currentScenarioId}
+ scenarios={scenarios}
+ onNewScenario={onNewScenario}
+ onChooseScenario={onChooseScenario}
+ onDeleteScenario={onDeleteScenario}
+ />
+ <NewScenarioModalComponent
+ show={isVisible}
+ currentPortfolioId={currentProjectId}
+ currentPortfolioScenarioIds={scenarios.map((s) => s._id)}
+ traces={traces}
+ schedulers={schedulers}
+ topologies={topologies}
+ callback={callback}
+ />
+ </>
)
}
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js
index e9c05f17..3779705a 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/project/TopologyListContainer.js
@@ -1,36 +1,25 @@
-import React from 'react'
-import { useDispatch, useSelector } from 'react-redux'
+import React, { useState } from 'react'
+import { useDispatch } from 'react-redux'
import TopologyListComponent from '../../../../components/app/sidebars/project/TopologyListComponent'
import { setCurrentTopology } from '../../../../actions/topology/building'
-import { openNewTopologyModal } from '../../../../actions/modals/topology'
import { useRouter } from 'next/router'
import { getState } from '../../../../util/state-utils'
-import { deleteTopology } from '../../../../actions/topologies'
+import { addTopology, deleteTopology } from '../../../../actions/topologies'
+import NewTopologyModalComponent from '../../../../components/modals/custom-components/NewTopologyModalComponent'
+import { useActiveTopology, useProjectTopologies } from '../../../../store/hooks/topology'
const TopologyListContainer = () => {
const dispatch = useDispatch()
const router = useRouter()
-
- const topologies = useSelector((state) => {
- let topologies = state.objects.project[state.currentProjectId]
- ? state.objects.project[state.currentProjectId].topologyIds.map((t) => state.objects.topology[t])
- : []
- if (topologies.filter((t) => !t).length > 0) {
- topologies = []
- }
-
- return topologies
- })
- const currentTopologyId = useSelector((state) => state.currentTopologyId)
+ const topologies = useProjectTopologies()
+ const currentTopologyId = useActiveTopology()?._id
+ const [isVisible, setVisible] = useState(false)
const onChooseTopology = async (id) => {
dispatch(setCurrentTopology(id))
const state = await getState(dispatch)
router.push(`/projects/${state.currentProjectId}`)
}
- const onNewTopology = () => {
- dispatch(openNewTopologyModal())
- }
const onDeleteTopology = async (id) => {
if (id) {
const state = await getState(dispatch)
@@ -39,15 +28,37 @@ const TopologyListContainer = () => {
router.push(`/projects/${state.currentProjectId}`)
}
}
+ const onCreateTopology = (name) => {
+ if (name) {
+ dispatch(addTopology(name, undefined))
+ }
+ setVisible(false)
+ }
+ const onDuplicateTopology = (name, id) => {
+ if (name) {
+ dispatch(addTopology(name, id))
+ }
+ setVisible(false)
+ }
+ const onCancel = () => setVisible(false)
return (
- <TopologyListComponent
- topologies={topologies}
- currentTopologyId={currentTopologyId}
- onChooseTopology={onChooseTopology}
- onNewTopology={onNewTopology}
- onDeleteTopology={onDeleteTopology}
- />
+ <>
+ <TopologyListComponent
+ topologies={topologies}
+ currentTopologyId={currentTopologyId}
+ onChooseTopology={onChooseTopology}
+ onNewTopology={() => setVisible(true)}
+ onDeleteTopology={onDeleteTopology}
+ />
+ <NewTopologyModalComponent
+ show={isVisible}
+ topologies={topologies}
+ onCreateTopology={onCreateTopology}
+ onDuplicateTopology={onDuplicateTopology}
+ onCancel={onCancel}
+ />
+ </>
)
}
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
index 1510a436..2f171ce8 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/DeleteMachineContainer.js
@@ -1,11 +1,32 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
-import { openDeleteMachineModal } from '../../../../../actions/modals/topology'
-import DeleteMachineComponent from '../../../../../components/app/sidebars/topology/machine/DeleteMachineComponent'
+import ConfirmationModal from '../../../../../components/modals/ConfirmationModal'
+import { deleteMachine } from '../../../../../actions/topology/machine'
+import { Button } from 'reactstrap'
-const DeleteMachineContainer = (props) => {
+const DeleteMachineContainer = () => {
const dispatch = useDispatch()
- return <DeleteMachineComponent {...props} onClick={() => dispatch(openDeleteMachineModal())} />
+ const [isVisible, setVisible] = useState(false)
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteMachine())
+ }
+ setVisible(false)
+ }
+ return (
+ <>
+ <Button color="danger" outline block onClick={() => setVisible(true)}>
+ <span className="fa fa-trash mr-2" />
+ Delete this machine
+ </Button>
+ <ConfirmationModal
+ title="Delete this machine"
+ message="Are you sure you want to delete this machine?"
+ show={isVisible}
+ callback={callback}
+ />
+ </>
+ )
}
export default DeleteMachineContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
index 6f4285b2..9cbb32c5 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/machine/MachineNameContainer.js
@@ -1,10 +1,9 @@
import React from 'react'
import { useSelector } from 'react-redux'
-import MachineNameComponent from '../../../../../components/app/sidebars/topology/machine/MachineNameComponent'
-const MachineNameContainer = (props) => {
+const MachineNameContainer = () => {
const position = useSelector((state) => state.interactionLevel.position)
- return <MachineNameComponent {...props} position={position} />
+ return <h2>Machine at slot {position}</h2>
}
export default MachineNameContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
index de46e491..4c7fd8bf 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/DeleteRackContainer.js
@@ -1,11 +1,32 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
-import { openDeleteRackModal } from '../../../../../actions/modals/topology'
-import DeleteRackComponent from '../../../../../components/app/sidebars/topology/rack/DeleteRackComponent'
+import ConfirmationModal from '../../../../../components/modals/ConfirmationModal'
+import { deleteRack } from '../../../../../actions/topology/rack'
+import { Button } from 'reactstrap'
-const DeleteRackContainer = (props) => {
+const DeleteRackContainer = () => {
const dispatch = useDispatch()
- return <DeleteRackComponent {...props} onClick={() => dispatch(openDeleteRackModal())} />
+ const [isVisible, setVisible] = useState(false)
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteRack())
+ }
+ setVisible(false)
+ }
+ return (
+ <>
+ <Button color="danger" outline block onClick={() => setVisible(true)}>
+ <span className="fa fa-trash mr-2" />
+ Delete this rack
+ </Button>
+ <ConfirmationModal
+ title="Delete this rack"
+ message="Are you sure you want to delete this rack?"
+ show={isVisible}
+ callback={callback}
+ />
+ </>
+ )
}
export default DeleteRackContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js
index 7dfdb473..dd9b05fc 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/rack/RackNameContainer.js
@@ -1,14 +1,33 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
-import { openEditRackNameModal } from '../../../../../actions/modals/topology'
-import RackNameComponent from '../../../../../components/app/sidebars/topology/rack/RackNameComponent'
+import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent'
+import TextInputModal from '../../../../../components/modals/TextInputModal'
+import { editRackName } from '../../../../../actions/topology/rack'
-const RackNameContainer = (props) => {
+const RackNameContainer = () => {
+ const [isVisible, setVisible] = useState(false)
const rackName = useSelector(
(state) => state.objects.rack[state.objects.tile[state.interactionLevel.tileId].rackId].name
)
const dispatch = useDispatch()
- return <RackNameComponent {...props} rackName={rackName} onEdit={() => dispatch(openEditRackNameModal())} />
+ const callback = (name) => {
+ if (name) {
+ dispatch(editRackName(name))
+ }
+ setVisible(false)
+ }
+ return (
+ <>
+ <NameComponent name={rackName} onEdit={() => setVisible(true)} />
+ <TextInputModal
+ title="Edit rack name"
+ label="Rack name"
+ show={isVisible}
+ initialValue={rackName}
+ callback={callback}
+ />
+ </>
+ )
}
export default RackNameContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
index 6a80e9b0..2062462f 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/DeleteRoomContainer.js
@@ -1,12 +1,32 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
-import { openDeleteRoomModal } from '../../../../../actions/modals/topology'
-import DeleteRoomComponent from '../../../../../components/app/sidebars/topology/room/DeleteRoomComponent'
+import { Button } from 'reactstrap'
+import ConfirmationModal from '../../../../../components/modals/ConfirmationModal'
+import { deleteRoom } from '../../../../../actions/topology/room'
-const DeleteRoomContainer = (props) => {
+const DeleteRoomContainer = () => {
const dispatch = useDispatch()
- const onClick = () => dispatch(openDeleteRoomModal())
- return <DeleteRoomComponent {...props} onClick={onClick} />
+ const [isVisible, setVisible] = useState(false)
+ const callback = (isConfirmed) => {
+ if (isConfirmed) {
+ dispatch(deleteRoom())
+ }
+ setVisible(false)
+ }
+ return (
+ <>
+ <Button color="danger" outline block onClick={() => setVisible(true)}>
+ <span className="fa fa-trash mr-2" />
+ Delete this room
+ </Button>
+ <ConfirmationModal
+ title="Delete this room"
+ message="Are you sure you want to delete this room?"
+ show={isVisible}
+ callback={callback}
+ />
+ </>
+ )
}
export default DeleteRoomContainer
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js
index 37027fc5..f03b0efb 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/EditRoomContainer.js
@@ -1,9 +1,9 @@
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { finishRoomEdit, startRoomEdit } from '../../../../../actions/topology/building'
-import EditRoomComponent from '../../../../../components/app/sidebars/topology/room/EditRoomComponent'
+import { Button } from 'reactstrap'
-const EditRoomContainer = (props) => {
+const EditRoomContainer = () => {
const isEditing = useSelector((state) => state.construction.currentRoomInConstruction !== '-1')
const isInRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode)
@@ -11,14 +11,22 @@ const EditRoomContainer = (props) => {
const onEdit = () => dispatch(startRoomEdit())
const onFinish = () => dispatch(finishRoomEdit())
- return (
- <EditRoomComponent
- {...props}
- onEdit={onEdit}
- onFinish={onFinish}
- isEditing={isEditing}
- isInRackConstructionMode={isInRackConstructionMode}
- />
+ return isEditing ? (
+ <Button color="info" outline block onClick={onFinish}>
+ <span className="fa fa-check mr-2" />
+ Finish editing room
+ </Button>
+ ) : (
+ <Button
+ color="info"
+ outline
+ block
+ disabled={isInRackConstructionMode}
+ onClick={() => (isInRackConstructionMode ? undefined : onEdit())}
+ >
+ <span className="fa fa-pencil mr-2" />
+ Edit the tiles of this room
+ </Button>
)
}
diff --git a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js
index 1f53aeb6..946bb864 100644
--- a/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js
+++ b/opendc-web/opendc-web-ui/src/containers/app/sidebars/topology/room/RoomNameContainer.js
@@ -1,13 +1,31 @@
-import React from 'react'
+import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
-import { openEditRoomNameModal } from '../../../../../actions/modals/topology'
-import RoomNameComponent from '../../../../../components/app/sidebars/topology/room/RoomNameComponent'
+import NameComponent from '../../../../../components/app/sidebars/topology/NameComponent'
+import TextInputModal from '../../../../../components/modals/TextInputModal'
+import { editRoomName } from '../../../../../actions/topology/room'
-const RoomNameContainer = (props) => {
+const RoomNameContainer = () => {
+ const [isVisible, setVisible] = useState(false)
const roomName = useSelector((state) => state.objects.room[state.interactionLevel.roomId].name)
const dispatch = useDispatch()
- const onEdit = () => dispatch(openEditRoomNameModal())
- return <RoomNameComponent {...props} onEdit={onEdit} roomName={roomName} />
+ const callback = (name) => {
+ if (name) {
+ dispatch(editRoomName(name))
+ }
+ setVisible(false)
+ }
+ return (
+ <>
+ <NameComponent name={roomName} onEdit={() => setVisible(true)} />
+ <TextInputModal
+ title="Edit room name"
+ label="Room name"
+ show={isVisible}
+ initialValue={roomName}
+ callback={callback}
+ />
+ </>
+ )
}
export default RoomNameContainer