diff options
| -rw-r--r-- | frontend/src/actions/modals/prefabs.js | 14 | ||||
| -rw-r--r-- | frontend/src/actions/prefabs.js | 32 | ||||
| -rw-r--r-- | frontend/src/api/routes/prefabs.js | 40 | ||||
| -rw-r--r-- | frontend/src/components/app/sidebars/topology/rack/AddPrefabComponent.js | 10 | ||||
| -rw-r--r-- | frontend/src/components/app/sidebars/topology/rack/RackSidebarComponent.js | 2 | ||||
| -rw-r--r-- | frontend/src/containers/app/sidebars/topology/rack/AddPrefabContainer.js | 13 | ||||
| -rw-r--r-- | frontend/src/reducers/objects.js | 1 | ||||
| -rw-r--r-- | frontend/src/sagas/index.js | 4 | ||||
| -rw-r--r-- | frontend/src/sagas/objects.js | 83 | ||||
| -rw-r--r-- | frontend/src/sagas/prefabs.js | 15 |
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) + } +} |
