summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Andreadis <info@gandreadis.com>2020-07-29 17:45:18 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2020-08-24 19:48:47 +0200
commit780e81c5ea7bc5c7988ae2c49bc8e6808337ff25 (patch)
tree92de51eae02e26fdbf0a703320626c13115e7a58
parentceaddeb0f6927e0f99f7b140aba6a85dac0106fb (diff)
parentac5b33c83f38f9b2799c0f2a871b86052121e8ac (diff)
Merge pull request #18 from atlarge-research/prefabs_wip
Add support for prefabs
-rw-r--r--frontend/src/actions/modals/prefabs.js14
-rw-r--r--frontend/src/actions/prefabs.js32
-rw-r--r--frontend/src/api/routes/prefabs.js40
-rw-r--r--frontend/src/components/app/sidebars/topology/rack/AddPrefabComponent.js10
-rw-r--r--frontend/src/components/app/sidebars/topology/rack/RackSidebarComponent.js2
-rw-r--r--frontend/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js13
-rw-r--r--frontend/src/reducers/objects.js1
-rw-r--r--frontend/src/sagas/index.js4
-rw-r--r--frontend/src/sagas/objects.js83
-rw-r--r--frontend/src/sagas/prefabs.js15
10 files changed, 186 insertions, 28 deletions
diff --git a/frontend/src/actions/modals/prefabs.js b/frontend/src/actions/modals/prefabs.js
new file mode 100644
index 00000000..826565d2
--- /dev/null
+++ b/frontend/src/actions/modals/prefabs.js
@@ -0,0 +1,14 @@
+export const OPEN_NEW_PREFAB_MODAL = 'OPEN_NEW_PREFAB_MODAL'
+export const CLOSE_NEW_PREFAB_MODAL = 'CLOSE_PREFAB_MODAL'
+
+export function openNewPrefabModal() {
+ return {
+ type: OPEN_NEW_PREFAB_MODAL,
+ }
+}
+
+export function closeNewPrefabModal() {
+ return {
+ type: CLOSE_NEW_PREFAB_MODAL,
+ }
+}
diff --git a/frontend/src/actions/prefabs.js b/frontend/src/actions/prefabs.js
new file mode 100644
index 00000000..c112feed
--- /dev/null
+++ b/frontend/src/actions/prefabs.js
@@ -0,0 +1,32 @@
+export const ADD_PREFAB = 'ADD_PREFAB'
+export const DELETE_PREFAB = 'DELETE_PREFAB'
+export const DELETE_PREFAB_SUCCEEDED = 'DELETE_PREFAB_SUCCEEDED'
+export const OPEN_PREFAB_SUCCEEDED = 'OPEN_PREFAB_SUCCEEDED'
+
+export function addPrefab(name) {
+ return {
+ type: ADD_PREFAB,
+ name,
+ }
+}
+
+export function deletePrefab(id) {
+ return {
+ type: DELETE_PREFAB,
+ id,
+ }
+}
+
+export function deletePrefabSucceeded(id) {
+ return {
+ type: DELETE_PREFAB_SUCCEEDED,
+ id,
+ }
+}
+
+export function openPrefabSucceeded(id) {
+ return {
+ type: OPEN_PREFAB_SUCCEEDED,
+ id,
+ }
+}
diff --git a/frontend/src/api/routes/prefabs.js b/frontend/src/api/routes/prefabs.js
new file mode 100644
index 00000000..8a1debfa
--- /dev/null
+++ b/frontend/src/api/routes/prefabs.js
@@ -0,0 +1,40 @@
+import { sendRequest } from '../index'
+import { deleteById, getById } from './util'
+
+export function getPrefab(prefabId) {
+ return getById('/prefabs/{prefabId}', { prefabId })
+}
+
+export function addPrefab(prefab) {
+ return sendRequest({
+ path: '/prefabs',
+ method: 'POST',
+ parameters: {
+ body: {
+ prefab,
+ },
+ path: {},
+ query: {},
+ },
+ })
+}
+
+export function updatePrefab(prefab) {
+ return sendRequest({
+ path: '/prefabs/{prefabId}',
+ method: 'PUT',
+ parameters: {
+ body: {
+ prefab,
+ },
+ path: {
+ prefabId: prefab._id,
+ },
+ query: {},
+ },
+ })
+}
+
+export function deletePrefab(prefabId) {
+ return deleteById('/prefabs/{prefabId}', { prefabId })
+}
diff --git a/frontend/src/components/app/sidebars/topology/rack/AddPrefabComponent.js b/frontend/src/components/app/sidebars/topology/rack/AddPrefabComponent.js
new file mode 100644
index 00000000..75418f9d
--- /dev/null
+++ b/frontend/src/components/app/sidebars/topology/rack/AddPrefabComponent.js
@@ -0,0 +1,10 @@
+import React from 'react'
+
+const AddPrefabComponent = ({ onClick }) => (
+ <div className="btn btn-primary btn-block" onClick={onClick}>
+ <span className="fa fa-floppy-o mr-2" />
+ Save this rack to a prefab
+ </div>
+)
+
+export default AddPrefabComponent
diff --git a/frontend/src/components/app/sidebars/topology/rack/RackSidebarComponent.js b/frontend/src/components/app/sidebars/topology/rack/RackSidebarComponent.js
index c04e46d8..d7127114 100644
--- a/frontend/src/components/app/sidebars/topology/rack/RackSidebarComponent.js
+++ b/frontend/src/components/app/sidebars/topology/rack/RackSidebarComponent.js
@@ -4,6 +4,7 @@ import DeleteRackContainer from '../../../../../containers/app/sidebars/topology
import MachineListContainer from '../../../../../containers/app/sidebars/topology/rack/MachineListContainer'
import RackNameContainer from '../../../../../containers/app/sidebars/topology/rack/RackNameContainer'
import './RackSidebarComponent.css'
+import AddPrefabContainer from '../../../../../containers/app/sidebars/topology/rack/AddPrefabContainer'
const RackSidebarComponent = () => {
return (
@@ -11,6 +12,7 @@ const RackSidebarComponent = () => {
<div className="rack-sidebar-header-container">
<RackNameContainer />
<BackToRoomContainer />
+ <AddPrefabContainer />
<DeleteRackContainer />
</div>
<div className="machine-list-container mt-2">
diff --git a/frontend/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js b/frontend/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js
new file mode 100644
index 00000000..c941e745
--- /dev/null
+++ b/frontend/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js
@@ -0,0 +1,13 @@
+import { connect } from 'react-redux'
+import { addPrefab } from '../../../../../actions/prefabs'
+import AddPrefabComponent from '../../../../../components/app/sidebars/topology/rack/AddPrefabComponent'
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onClick: () => dispatch(addPrefab('name')),
+ }
+}
+
+const AddPrefabContainer = connect(undefined, mapDispatchToProps)(AddPrefabComponent)
+
+export default AddPrefabContainer
diff --git a/frontend/src/reducers/objects.js b/frontend/src/reducers/objects.js
index b4db0a6b..1f721b2e 100644
--- a/frontend/src/reducers/objects.js
+++ b/frontend/src/reducers/objects.js
@@ -24,6 +24,7 @@ export const objects = combineReducers({
scheduler: object('scheduler'),
portfolio: object('portfolio'),
scenario: object('scenario'),
+ prefab: object('prefab'),
})
function object(type, defaultState = {}) {
diff --git a/frontend/src/sagas/index.js b/frontend/src/sagas/index.js
index 9f6c4809..6332b2fb 100644
--- a/frontend/src/sagas/index.js
+++ b/frontend/src/sagas/index.js
@@ -36,6 +36,8 @@ import { onFetchAuthorizationsOfCurrentUser, onFetchLoggedInUser } from './users
import { ADD_TOPOLOGY, DELETE_TOPOLOGY } from '../actions/topologies'
import { ADD_SCENARIO, DELETE_SCENARIO, OPEN_SCENARIO_SUCCEEDED, UPDATE_SCENARIO } from '../actions/scenarios'
import { onAddScenario, onDeleteScenario, onOpenScenarioSucceeded, onUpdateScenario } from './scenarios'
+import { onAddPrefab } from './prefabs'
+import { ADD_PREFAB } from '../actions/prefabs'
export default function* rootSaga() {
yield takeEvery(LOG_IN, onFetchLoggedInUser)
@@ -73,4 +75,6 @@ export default function* rootSaga() {
yield takeEvery(ADD_SCENARIO, onAddScenario)
yield takeEvery(UPDATE_SCENARIO, onUpdateScenario)
yield takeEvery(DELETE_SCENARIO, onDeleteScenario)
+
+ yield takeEvery(ADD_PREFAB, onAddPrefab)
}
diff --git a/frontend/src/sagas/objects.js b/frontend/src/sagas/objects.js
index 83d71a42..ebce1f0a 100644
--- a/frontend/src/sagas/objects.js
+++ b/frontend/src/sagas/objects.js
@@ -148,8 +148,50 @@ export const updateTopologyOnServer = function* (id) {
export const getTopologyAsObject = function* (id, keepIds) {
const topologyStore = yield select(OBJECT_SELECTORS['topology'])
+ const rooms = yield getAllRooms(topologyStore[id].roomIds, keepIds)
+ return {
+ _id: keepIds ? id : undefined,
+ name: topologyStore[id].name,
+ rooms: rooms,
+ }
+}
+
+export const getAllRooms = function* (roomIds, keepIds) {
const roomStore = yield select(OBJECT_SELECTORS['room'])
+
+ let rooms = []
+
+ for (let i in roomIds) {
+ let tiles = yield getAllRoomTiles(roomStore[roomIds[i]], keepIds)
+ rooms.push({
+ _id: keepIds ? i : undefined,
+ name: roomStore[roomIds[i]].name,
+ tiles: tiles,
+ })
+ }
+ return rooms
+}
+
+export const getAllRoomTiles = function* (roomStore, keepIds) {
+ let tiles = []
+
+ for (let i in roomStore.tileIds) {
+ tiles.push(yield getTileById(roomStore.tileIds[i], keepIds))
+ }
+ return tiles
+}
+
+export const getTileById = function* (id, keepIds) {
const tileStore = yield select(OBJECT_SELECTORS['tile'])
+ return {
+ _id: keepIds ? id : undefined,
+ positionX: tileStore[id].positionX,
+ positionY: tileStore[id].positionY,
+ rack: !tileStore[id].rackId ? undefined : yield getRackById(tileStore[id].rackId, keepIds),
+ }
+}
+
+export const getRackById = function* (id, keepIds) {
const rackStore = yield select(OBJECT_SELECTORS['rack'])
const machineStore = yield select(OBJECT_SELECTORS['machine'])
const cpuStore = yield select(OBJECT_SELECTORS['cpu'])
@@ -158,35 +200,20 @@ export const getTopologyAsObject = function* (id, keepIds) {
const storageStore = yield select(OBJECT_SELECTORS['storage'])
return {
- _id: keepIds ? id : undefined,
- name: topologyStore[id].name,
- rooms: topologyStore[id].roomIds.map((roomId) => ({
- _id: keepIds ? roomId : undefined,
- name: roomStore[roomId].name,
- tiles: roomStore[roomId].tileIds.map((tileId) => ({
- _id: keepIds ? tileId : undefined,
- positionX: tileStore[tileId].positionX,
- positionY: tileStore[tileId].positionY,
- rack: !tileStore[tileId].rackId
- ? undefined
- : {
- _id: keepIds ? rackStore[tileStore[tileId].rackId]._id : undefined,
- name: rackStore[tileStore[tileId].rackId].name,
- capacity: rackStore[tileStore[tileId].rackId].capacity,
- powerCapacityW: rackStore[tileStore[tileId].rackId].powerCapacityW,
- machines: rackStore[tileStore[tileId].rackId].machineIds
- .filter((m) => m !== null)
- .map((machineId) => ({
- _id: keepIds ? machineId : undefined,
- position: machineStore[machineId].position,
- cpus: machineStore[machineId].cpuIds.map((id) => cpuStore[id]),
- gpus: machineStore[machineId].gpuIds.map((id) => gpuStore[id]),
- memories: machineStore[machineId].memoryIds.map((id) => memoryStore[id]),
- storages: machineStore[machineId].storageIds.map((id) => storageStore[id]),
- })),
- },
+ _id: keepIds ? rackStore[id]._id : undefined,
+ name: rackStore[id].name,
+ capacity: rackStore[id].capacity,
+ powerCapacityW: rackStore[id].powerCapacityW,
+ machines: rackStore[id].machineIds
+ .filter((m) => m !== null)
+ .map((machineId) => ({
+ _id: keepIds ? machineId : undefined,
+ position: machineStore[machineId].position,
+ cpus: machineStore[machineId].cpuIds.map((id) => cpuStore[id]),
+ gpus: machineStore[machineId].gpuIds.map((id) => gpuStore[id]),
+ memories: machineStore[machineId].memoryIds.map((id) => memoryStore[id]),
+ storages: machineStore[machineId].storageIds.map((id) => storageStore[id]),
})),
- })),
}
}
diff --git a/frontend/src/sagas/prefabs.js b/frontend/src/sagas/prefabs.js
new file mode 100644
index 00000000..16cf3d62
--- /dev/null
+++ b/frontend/src/sagas/prefabs.js
@@ -0,0 +1,15 @@
+import { call, put, select } from 'redux-saga/effects'
+import { addToStore } from '../actions/objects'
+import { addPrefab } from '../api/routes/prefabs'
+import { getRackById } from './objects'
+
+export function* onAddPrefab(action) {
+ try {
+ const currentRackId = yield select((state) => state.objects.tile[state.interactionLevel.tileId].rackId)
+ const currentRackJson = yield getRackById(currentRackId, false)
+ const prefab = yield call(addPrefab, { name: action.name, rack: currentRackJson })
+ yield put(addToStore('prefab', prefab))
+ } catch (error) {
+ console.error(error)
+ }
+}