summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/redux/sagas/topology.js
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-ui/src/redux/sagas/topology.js')
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/topology.js311
1 files changed, 311 insertions, 0 deletions
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js
new file mode 100644
index 00000000..65f97cc9
--- /dev/null
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js
@@ -0,0 +1,311 @@
+import { call, put, select } from 'redux-saga/effects'
+import { goDownOneInteractionLevel } from '../actions/interaction-level'
+import {
+ addIdToStoreObjectListProp,
+ addPropToStoreObject,
+ addToStore,
+ removeIdFromStoreObjectListProp,
+} from '../actions/objects'
+import {
+ cancelNewRoomConstructionSucceeded,
+ setCurrentTopology,
+ startNewRoomConstructionSucceeded,
+} from '../actions/topology/building'
+import {
+ DEFAULT_RACK_POWER_CAPACITY,
+ DEFAULT_RACK_SLOT_CAPACITY,
+ MAX_NUM_UNITS_PER_MACHINE,
+} from '../../components/app/map/MapConstants'
+import { fetchAndStoreTopology, getTopologyAsObject, updateTopologyOnServer } from './objects'
+import { uuid } from 'uuidv4'
+import { addTopology, deleteTopology } from '../../api/topologies'
+
+export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = false) {
+ try {
+ const project = yield select((state) => state.objects.project[projectId])
+
+ for (let i in project.topologyIds) {
+ yield fetchAndStoreTopology(project.topologyIds[i])
+ }
+
+ if (setTopology) {
+ yield put(setCurrentTopology(project.topologyIds[0]))
+ }
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onAddTopology(action) {
+ try {
+ const currentProjectId = yield select((state) => state.currentProjectId)
+
+ let topologyToBeCreated
+ if (action.duplicateId) {
+ topologyToBeCreated = yield getTopologyAsObject(action.duplicateId, false)
+ topologyToBeCreated = Object.assign({}, topologyToBeCreated, {
+ name: action.name,
+ })
+ } else {
+ topologyToBeCreated = { name: action.name, rooms: [] }
+ }
+
+ const topology = yield call(
+ addTopology,
+ Object.assign({}, topologyToBeCreated, {
+ projectId: currentProjectId,
+ })
+ )
+ yield fetchAndStoreTopology(topology._id)
+
+ const topologyIds = yield select((state) => state.objects.project[currentProjectId].topologyIds)
+ yield put(
+ addPropToStoreObject('project', currentProjectId, {
+ topologyIds: topologyIds.concat([topology._id]),
+ })
+ )
+ yield put(setCurrentTopology(topology._id))
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onDeleteTopology(action) {
+ try {
+ const currentProjectId = yield select((state) => state.currentProjectId)
+ const topologyIds = yield select((state) => state.objects.project[currentProjectId].topologyIds)
+ const currentTopologyId = yield select((state) => state.currentTopologyId)
+ if (currentTopologyId === action.id) {
+ yield put(setCurrentTopology(topologyIds.filter((t) => t !== action.id)[0]))
+ }
+
+ yield call(deleteTopology, action.id)
+
+ yield put(
+ addPropToStoreObject('project', currentProjectId, {
+ topologyIds: topologyIds.filter((id) => id !== action.id),
+ })
+ )
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onStartNewRoomConstruction() {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const room = {
+ _id: uuid(),
+ name: 'Room',
+ topologyId,
+ tileIds: [],
+ }
+ yield put(addToStore('room', room))
+ yield put(addIdToStoreObjectListProp('topology', topologyId, 'roomIds', room._id))
+ yield updateTopologyOnServer(topologyId)
+ yield put(startNewRoomConstructionSucceeded(room._id))
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onCancelNewRoomConstruction() {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const roomId = yield select((state) => state.construction.currentRoomInConstruction)
+ yield put(removeIdFromStoreObjectListProp('topology', topologyId, 'roomIds', roomId))
+ // TODO remove room from store, too
+ yield updateTopologyOnServer(topologyId)
+ yield put(cancelNewRoomConstructionSucceeded())
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onAddTile(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const roomId = yield select((state) => state.construction.currentRoomInConstruction)
+ const tile = {
+ _id: uuid(),
+ roomId,
+ positionX: action.positionX,
+ positionY: action.positionY,
+ }
+ yield put(addToStore('tile', tile))
+ yield put(addIdToStoreObjectListProp('room', roomId, 'tileIds', tile._id))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onDeleteTile(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const roomId = yield select((state) => state.construction.currentRoomInConstruction)
+ yield put(removeIdFromStoreObjectListProp('room', roomId, 'tileIds', action.tileId))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onEditRoomName(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const roomId = yield select((state) => state.interactionLevel.roomId)
+ const room = Object.assign({}, yield select((state) => state.objects.room[roomId]))
+ room.name = action.name
+ yield put(addPropToStoreObject('room', roomId, { name: action.name }))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onDeleteRoom() {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const roomId = yield select((state) => state.interactionLevel.roomId)
+ yield put(goDownOneInteractionLevel())
+ yield put(removeIdFromStoreObjectListProp('topology', topologyId, 'roomIds', roomId))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onEditRackName(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const rackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rackId)
+ const rack = Object.assign({}, yield select((state) => state.objects.rack[rackId]))
+ rack.name = action.name
+ yield put(addPropToStoreObject('rack', rackId, { name: action.name }))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onDeleteRack() {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const tileId = yield select((state) => state.interactionLevel.tileId)
+ yield put(goDownOneInteractionLevel())
+ yield put(addPropToStoreObject('tile', tileId, { rackId: undefined }))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onAddRackToTile(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const rack = {
+ _id: uuid(),
+ name: 'Rack',
+ capacity: DEFAULT_RACK_SLOT_CAPACITY,
+ powerCapacityW: DEFAULT_RACK_POWER_CAPACITY,
+ }
+ rack.machineIds = new Array(rack.capacity).fill(null)
+ yield put(addToStore('rack', rack))
+ yield put(addPropToStoreObject('tile', action.tileId, { rackId: rack._id }))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onAddMachine(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const rackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rackId)
+ const rack = yield select((state) => state.objects.rack[rackId])
+
+ const machine = {
+ _id: uuid(),
+ rackId,
+ position: action.position,
+ cpuIds: [],
+ gpuIds: [],
+ memoryIds: [],
+ storageIds: [],
+ }
+ yield put(addToStore('machine', machine))
+
+ const machineIds = [...rack.machineIds]
+ machineIds[machine.position - 1] = machine._id
+ yield put(addPropToStoreObject('rack', rackId, { machineIds }))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onDeleteMachine() {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const tileId = yield select((state) => state.interactionLevel.tileId)
+ const position = yield select((state) => state.interactionLevel.position)
+ const rack = yield select((state) => state.objects.rack[state.objects.tile[tileId].rackId])
+ const machineIds = [...rack.machineIds]
+ machineIds[position - 1] = null
+ yield put(goDownOneInteractionLevel())
+ yield put(addPropToStoreObject('rack', rack._id, { machineIds }))
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onAddUnit(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const tileId = yield select((state) => state.interactionLevel.tileId)
+ const position = yield select((state) => state.interactionLevel.position)
+ const machine = yield select(
+ (state) =>
+ state.objects.machine[state.objects.rack[state.objects.tile[tileId].rackId].machineIds[position - 1]]
+ )
+
+ if (machine[action.unitType + 'Ids'].length >= MAX_NUM_UNITS_PER_MACHINE) {
+ return
+ }
+
+ const units = [...machine[action.unitType + 'Ids'], action.id]
+ yield put(
+ addPropToStoreObject('machine', machine._id, {
+ [action.unitType + 'Ids']: units,
+ })
+ )
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* onDeleteUnit(action) {
+ try {
+ const topologyId = yield select((state) => state.currentTopologyId)
+ const tileId = yield select((state) => state.interactionLevel.tileId)
+ const position = yield select((state) => state.interactionLevel.position)
+ const machine = yield select(
+ (state) =>
+ state.objects.machine[state.objects.rack[state.objects.tile[tileId].rackId].machineIds[position - 1]]
+ )
+ const unitIds = machine[action.unitType + 'Ids'].slice()
+ unitIds.splice(action.index, 1)
+
+ yield put(
+ addPropToStoreObject('machine', machine._id, {
+ [action.unitType + 'Ids']: unitIds,
+ })
+ )
+ yield updateTopologyOnServer(topologyId)
+ } catch (error) {
+ console.error(error)
+ }
+}