diff options
| author | vincent van beek <vincent@vlogic.nl> | 2026-03-26 14:02:54 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-26 13:02:54 +0000 |
| commit | 0ffde21b0337c606e2d0ece5bd5434a930a87dcd (patch) | |
| tree | 4fd071728a8da6dcf3e6fc9fe9dca5a492100d34 /opendc-web/opendc-web-ui/src/redux | |
| parent | 8bb98c773bc982a0dab9cf9fb20d62f60a36a5d7 (diff) | |
Use Quarkus Quinoa for serving web UI (#391)
* refactor(web): Migrate to Quarkus 3
This commit updates the OpenDC web server to use Quarkus 3, which
changes annotations to use the Jakarta namespace for annotations.
* refactor(web): Configure runtime variables for web UI
This commit updates the web UI to propagate runtime variables via the
next-runtime-env package. Before, we would need to replace the variables
in the generated sources by Next.js, next-runtime-env works by loading a
JavaScript file when opening the OpenDC web UI which contains the
configuration of the web app.
* refactor(web): Migrate to Quarkus Quinoa
This commit updates the OpenDC web server to make use of Quarkus Quinoa
for serving the web UI. This allows us to deprecate the complex Quarkus
extension for serving the web UI.
* refactor(web): Move web UI into Quarkus web app
This commit moves the web UI into the Quarkus web server module to
ensure we follow Quarkus Quinoa's conventions.
* refactor(web): Merge Quarkus extension into single module
This commit merges the existing Quarkus extensions into a single module
to prevent build complexity.
* refactor(web): Migrate web proto to Java
This commit migrates the web protocol to Java and removes the dependency
on Jandex Gradle.
* refactor(web): Migrate to Quarkus 3
This commit updates the OpenDC web server to use Quarkus 3, which
changes annotations to use the Jakarta namespace for annotations.
* enable DB schema migration on DEV server
* webui is not needed anymore
* remove MAINTAINERS is depricated
* fix quarkus.quinoa properties
* revert properties change, install npm in docker image to allow building the frontend
* pin postgres version, this is a best practice. Fix some properties the old ones are depricated. Added properties for local testing
* fix build error
* :opendc-web:opendc-web-proto:spotlessApply
* fix database schema
---------
Co-authored-by: Fabian Mastenbroek <mail.fabianm@gmail.com>
Diffstat (limited to 'opendc-web/opendc-web-ui/src/redux')
18 files changed, 0 insertions, 940 deletions
diff --git a/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js b/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js deleted file mode 100644 index 8381eeef..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/interaction-level.js +++ /dev/null @@ -1,57 +0,0 @@ -export const GO_FROM_BUILDING_TO_ROOM = 'GO_FROM_BUILDING_TO_ROOM' -export const GO_FROM_ROOM_TO_RACK = 'GO_FROM_ROOM_TO_RACK' -export const GO_FROM_RACK_TO_MACHINE = 'GO_FROM_RACK_TO_MACHINE' -export const GO_DOWN_ONE_INTERACTION_LEVEL = 'GO_DOWN_ONE_INTERACTION_LEVEL' - -export function goToRoom(roomId) { - return { - type: GO_FROM_BUILDING_TO_ROOM, - roomId, - } -} - -export function goFromBuildingToRoom(roomId) { - return (dispatch, getState) => { - const { interactionLevel } = getState() - if (interactionLevel.mode !== 'BUILDING') { - return - } - - dispatch({ - type: GO_FROM_BUILDING_TO_ROOM, - roomId, - }) - } -} - -export function goFromRoomToRack(tileId) { - return (dispatch, getState) => { - const { interactionLevel } = getState() - if (interactionLevel.mode !== 'ROOM') { - return - } - dispatch({ - type: GO_FROM_ROOM_TO_RACK, - tileId, - }) - } -} - -export function goFromRackToMachine(position) { - return (dispatch, getState) => { - const { interactionLevel } = getState() - if (interactionLevel.mode !== 'RACK') { - return - } - dispatch({ - type: GO_FROM_RACK_TO_MACHINE, - position, - }) - } -} - -export function goDownOneInteractionLevel() { - return { - type: GO_DOWN_ONE_INTERACTION_LEVEL, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js deleted file mode 100644 index c12417b9..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/building.js +++ /dev/null @@ -1,113 +0,0 @@ -import { v4 as uuid } from 'uuid' -import { addRoom, deleteRoom } from './room' - -export const START_NEW_ROOM_CONSTRUCTION = 'START_NEW_ROOM_CONSTRUCTION' -export const START_NEW_ROOM_CONSTRUCTION_SUCCEEDED = 'START_NEW_ROOM_CONSTRUCTION_SUCCEEDED' -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 START_ROOM_EDIT = 'START_ROOM_EDIT' -export const FINISH_ROOM_EDIT = 'FINISH_ROOM_EDIT' -export const ADD_TILE = 'ADD_TILE' -export const DELETE_TILE = 'DELETE_TILE' - -export function startNewRoomConstruction() { - return (dispatch, getState) => { - const { topology } = getState() - const topologyId = topology.root.id - const room = { - id: uuid(), - name: 'Room', - topologyId, - tiles: [], - } - - dispatch(addRoom(topologyId, room)) - dispatch(startNewRoomConstructionSucceeded(room.id)) - } -} - -export function startNewRoomConstructionSucceeded(roomId) { - return { - type: START_NEW_ROOM_CONSTRUCTION_SUCCEEDED, - roomId, - } -} - -export function finishNewRoomConstruction() { - return (dispatch, getState) => { - const { topology, construction } = getState() - if (topology.rooms[construction.currentRoomInConstruction].tiles.length === 0) { - dispatch(cancelNewRoomConstruction()) - return - } - - dispatch({ - type: FINISH_NEW_ROOM_CONSTRUCTION, - }) - } -} - -export function cancelNewRoomConstruction() { - return (dispatch, getState) => { - const { construction } = getState() - const roomId = construction.currentRoomInConstruction - dispatch(deleteRoom(roomId)) - dispatch(cancelNewRoomConstructionSucceeded()) - } -} - -export function cancelNewRoomConstructionSucceeded() { - return { - type: CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED, - } -} - -export function startRoomEdit(roomId) { - return { - type: START_ROOM_EDIT, - roomId: roomId, - } -} - -export function finishRoomEdit() { - return { - type: FINISH_ROOM_EDIT, - } -} - -export function toggleTileAtLocation(positionX, positionY) { - return (dispatch, getState) => { - const { topology, construction } = getState() - - const roomId = construction.currentRoomInConstruction - const tileIds = topology.rooms[roomId].tiles - for (const tileId of tileIds) { - if (topology.tiles[tileId].positionX === positionX && topology.tiles[tileId].positionY === positionY) { - dispatch(deleteTile(tileId)) - return - } - } - - dispatch(addTile(roomId, positionX, positionY)) - } -} - -export function addTile(roomId, positionX, positionY) { - return { - type: ADD_TILE, - tile: { - id: uuid(), - roomId, - positionX, - positionY, - }, - } -} - -export function deleteTile(tileId) { - return { - type: DELETE_TILE, - tileId, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/index.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/index.js deleted file mode 100644 index d48af37a..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/index.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -export const OPEN_TOPOLOGY = 'OPEN_TOPOLOGY' -export const STORE_TOPOLOGY = 'STORE_TOPOLOGY' - -export function openTopology(projectId, id) { - return { - type: OPEN_TOPOLOGY, - projectId, - id, - } -} - -export function storeTopology(topology, entities) { - return { - type: STORE_TOPOLOGY, - topology, - entities, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js deleted file mode 100644 index 93320884..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/machine.js +++ /dev/null @@ -1,28 +0,0 @@ -export const DELETE_MACHINE = 'DELETE_MACHINE' -export const ADD_UNIT = 'ADD_UNIT' -export const DELETE_UNIT = 'DELETE_UNIT' - -export function deleteMachine(machineId) { - return { - type: DELETE_MACHINE, - machineId, - } -} - -export function addUnit(machineId, unitType, unitId) { - return { - type: ADD_UNIT, - machineId, - unitType, - unitId, - } -} - -export function deleteUnit(machineId, unitType, unitId) { - return { - type: DELETE_UNIT, - machineId, - unitType, - unitId, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js deleted file mode 100644 index 1f65952a..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/rack.js +++ /dev/null @@ -1,36 +0,0 @@ -import { v4 as uuid } from 'uuid' - -export const EDIT_RACK_NAME = 'EDIT_RACK_NAME' -export const DELETE_RACK = 'DELETE_RACK' -export const ADD_MACHINE = 'ADD_MACHINE' - -export function editRackName(rackId, name) { - return { - type: EDIT_RACK_NAME, - name, - rackId, - } -} - -export function deleteRack(tileId, rackId) { - return { - type: DELETE_RACK, - rackId, - tileId, - } -} - -export function addMachine(rackId, position) { - return { - type: ADD_MACHINE, - machine: { - id: uuid(), - rackId, - position, - cpus: [], - gpus: [], - memories: [], - storages: [], - }, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js b/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js deleted file mode 100644 index 14cc126c..00000000 --- a/opendc-web/opendc-web-ui/src/redux/actions/topology/room.js +++ /dev/null @@ -1,74 +0,0 @@ -import { v4 as uuid } from 'uuid' -import { - DEFAULT_RACK_SLOT_CAPACITY, - DEFAULT_RACK_POWER_CAPACITY, -} from '../../../components/topologies/map/MapConstants' -import { findTileWithPosition } from '../../../util/tile-calculations' - -export const ADD_ROOM = 'ADD_ROOM' -export const EDIT_ROOM_NAME = 'EDIT_ROOM_NAME' -export const DELETE_ROOM = 'DELETE_ROOM' -export const START_RACK_CONSTRUCTION = 'START_RACK_CONSTRUCTION' -export const STOP_RACK_CONSTRUCTION = 'STOP_RACK_CONSTRUCTION' -export const ADD_RACK_TO_TILE = 'ADD_RACK_TO_TILE' - -export function addRoom(topologyId, room) { - return { - type: ADD_ROOM, - room: { - id: uuid(), - topologyId, - ...room, - }, - } -} - -export function editRoomName(roomId, name) { - return { - type: EDIT_ROOM_NAME, - name, - roomId, - } -} - -export function startRackConstruction() { - return { - type: START_RACK_CONSTRUCTION, - } -} - -export function stopRackConstruction() { - return { - type: STOP_RACK_CONSTRUCTION, - } -} - -export function addRackToTile(positionX, positionY) { - return (dispatch, getState) => { - const { topology, interactionLevel } = getState() - const currentRoom = topology.rooms[interactionLevel.roomId] - const tiles = currentRoom.tiles.map((tileId) => topology.tiles[tileId]) - const tile = findTileWithPosition(tiles, positionX, positionY) - - if (tile !== null) { - dispatch({ - type: ADD_RACK_TO_TILE, - tileId: tile.id, - rack: { - id: uuid(), - name: 'Rack', - capacity: DEFAULT_RACK_SLOT_CAPACITY, - powerCapacityW: DEFAULT_RACK_POWER_CAPACITY, - machines: [], - }, - }) - } - } -} - -export function deleteRoom(roomId) { - return { - type: DELETE_ROOM, - roomId, - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/index.js b/opendc-web/opendc-web-ui/src/redux/index.js deleted file mode 100644 index 53cd9144..00000000 --- a/opendc-web/opendc-web-ui/src/redux/index.js +++ /dev/null @@ -1,59 +0,0 @@ -import { useMemo } from 'react' -import { applyMiddleware, compose, createStore } from 'redux' -import { createLogger } from 'redux-logger' -import createSagaMiddleware from 'redux-saga' -import thunk from 'redux-thunk' -import rootReducer from './reducers' -import rootSaga from './sagas' -import { createReduxEnhancer } from '@sentry/react' -import { sentryDsn } from '../config' - -let store - -function initStore(initialState, ctx) { - const sagaMiddleware = createSagaMiddleware({ context: ctx }) - - const middlewares = [thunk, sagaMiddleware] - - if (process.env.NODE_ENV !== 'production') { - middlewares.push(createLogger()) - } - - let middleware = applyMiddleware(...middlewares) - - if (sentryDsn) { - middleware = compose(middleware, createReduxEnhancer()) - } - - const configuredStore = createStore(rootReducer, initialState, middleware) - sagaMiddleware.run(rootSaga) - store = configuredStore - - return configuredStore -} - -export const initializeStore = (preloadedState, ctx) => { - let _store = store ?? initStore(preloadedState, ctx) - - // After navigating to a page with an initial Redux state, merge that state - // with the current state in the store, and create a new store - if (preloadedState && store) { - _store = initStore({ - ...store.getState(), - ...preloadedState, - }) - // Reset the current store - store = undefined - } - - // For SSG and SSR always create a new store - if (typeof window === 'undefined') return _store - // Create the store once in the client - if (!store) store = _store - - return _store -} - -export function useStore(initialState, ctx) { - return useMemo(() => initializeStore(initialState, ctx), [initialState, ctx]) -} diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js b/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js deleted file mode 100644 index d0aac5ae..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/construction-mode.js +++ /dev/null @@ -1,43 +0,0 @@ -import { combineReducers } from 'redux' -import { GO_DOWN_ONE_INTERACTION_LEVEL } from '../actions/interaction-level' -import { - CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED, - FINISH_NEW_ROOM_CONSTRUCTION, - FINISH_ROOM_EDIT, - START_NEW_ROOM_CONSTRUCTION_SUCCEEDED, - START_ROOM_EDIT, -} from '../actions/topology/building' -import { DELETE_ROOM, START_RACK_CONSTRUCTION, STOP_RACK_CONSTRUCTION } from '../actions/topology/room' - -export function currentRoomInConstruction(state = '-1', action) { - switch (action.type) { - case START_NEW_ROOM_CONSTRUCTION_SUCCEEDED: - return action.roomId - case START_ROOM_EDIT: - return action.roomId - case CANCEL_NEW_ROOM_CONSTRUCTION_SUCCEEDED: - case FINISH_NEW_ROOM_CONSTRUCTION: - case FINISH_ROOM_EDIT: - case DELETE_ROOM: - return '-1' - default: - return state - } -} - -export function inRackConstructionMode(state = false, action) { - switch (action.type) { - case START_RACK_CONSTRUCTION: - return true - case STOP_RACK_CONSTRUCTION: - case GO_DOWN_ONE_INTERACTION_LEVEL: - return false - default: - return state - } -} - -export const construction = combineReducers({ - currentRoomInConstruction, - inRackConstructionMode, -}) diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/index.js b/opendc-web/opendc-web-ui/src/redux/reducers/index.js deleted file mode 100644 index 7ffb1211..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import { combineReducers } from 'redux' -import { construction } from './construction-mode' -import { interactionLevel } from './interaction-level' -import topology from './topology' - -const rootReducer = combineReducers({ - topology, - construction, - interactionLevel, -}) - -export default rootReducer diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js b/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js deleted file mode 100644 index b30c68b9..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/interaction-level.js +++ /dev/null @@ -1,68 +0,0 @@ -import { - GO_DOWN_ONE_INTERACTION_LEVEL, - GO_FROM_BUILDING_TO_ROOM, - GO_FROM_RACK_TO_MACHINE, - GO_FROM_ROOM_TO_RACK, -} from '../actions/interaction-level' -import { DELETE_MACHINE } from '../actions/topology/machine' -import { DELETE_RACK } from '../actions/topology/rack' -import { DELETE_ROOM } from '../actions/topology/room' - -export function interactionLevel(state = { mode: 'BUILDING' }, action) { - switch (action.type) { - case GO_FROM_BUILDING_TO_ROOM: - return { - mode: 'ROOM', - roomId: action.roomId, - } - case GO_FROM_ROOM_TO_RACK: - return { - mode: 'RACK', - roomId: state.roomId, - tileId: action.tileId, - } - case GO_FROM_RACK_TO_MACHINE: - return { - mode: 'MACHINE', - roomId: state.roomId, - tileId: state.tileId, - position: action.position, - } - case GO_DOWN_ONE_INTERACTION_LEVEL: - if (state.mode === 'ROOM') { - return { - mode: 'BUILDING', - } - } else if (state.mode === 'RACK') { - return { - mode: 'ROOM', - roomId: state.roomId, - } - } else if (state.mode === 'MACHINE') { - return { - mode: 'RACK', - roomId: state.roomId, - tileId: state.tileId, - } - } else { - return state - } - case DELETE_MACHINE: - return { - mode: 'RACK', - roomId: state.roomId, - tileId: state.tileId, - } - case DELETE_RACK: - return { - mode: 'ROOM', - roomId: state.roomId, - } - case DELETE_ROOM: - return { - mode: 'BUILDING', - } - default: - return state - } -} diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js deleted file mode 100644 index 2c849387..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/topology/index.js +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import { CPU_UNITS, GPU_UNITS, MEMORY_UNITS, STORAGE_UNITS } from '../../../util/unit-specifications' -import machine from './machine' -import rack from './rack' -import room from './room' -import tile from './tile' -import topology from './topology' - -function objects(state = {}, action) { - return { - cpus: CPU_UNITS, - gpus: GPU_UNITS, - memories: MEMORY_UNITS, - storages: STORAGE_UNITS, - machines: machine(state.machines, action, state), - racks: rack(state.racks, action, state), - tiles: tile(state.tiles, action), - rooms: room(state.rooms, action, state), - root: topology(state.root, action, state), - } -} - -export default objects diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js deleted file mode 100644 index 1789257b..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/topology/machine.js +++ /dev/null @@ -1,47 +0,0 @@ -import produce from 'immer' -import { STORE_TOPOLOGY } from '../../actions/topology' -import { DELETE_MACHINE, ADD_UNIT, DELETE_UNIT } from '../../actions/topology/machine' -import { ADD_MACHINE, DELETE_RACK } from '../../actions/topology/rack' - -function machine(state = {}, action, { racks }) { - switch (action.type) { - case STORE_TOPOLOGY: - return action.entities.machines || {} - case ADD_MACHINE: - return produce(state, (draft) => { - const { machine } = action - draft[machine.id] = machine - }) - case DELETE_MACHINE: - return produce(state, (draft) => { - const { machineId } = action - delete draft[machineId] - }) - case ADD_UNIT: - return produce(state, (draft) => { - const { machineId, unitType, unitId } = action - draft[machineId][unitType].push(unitId) - }) - case DELETE_UNIT: - return produce(state, (draft) => { - const { machineId, unitType, unitId } = action - const units = draft[machineId][unitType] - const index = units.indexOf(unitId) - units.splice(index, 1) - }) - case DELETE_RACK: - return produce(state, (draft) => { - const { rackId } = action - const rack = racks[rackId] - - for (const id of rack.machines) { - const machine = draft[id] - machine.rackId = undefined - } - }) - default: - return state - } -} - -export default machine diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js deleted file mode 100644 index ca79348a..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/topology/rack.js +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import produce from 'immer' -import { STORE_TOPOLOGY } from '../../actions/topology' -import { DELETE_MACHINE } from '../../actions/topology/machine' -import { DELETE_RACK, EDIT_RACK_NAME, ADD_MACHINE } from '../../actions/topology/rack' -import { ADD_RACK_TO_TILE } from '../../actions/topology/room' - -function rack(state = {}, action, { machines }) { - switch (action.type) { - case STORE_TOPOLOGY: - return action.entities.racks || {} - case ADD_RACK_TO_TILE: - return produce(state, (draft) => { - const { rack } = action - draft[rack.id] = rack - }) - case EDIT_RACK_NAME: - return produce(state, (draft) => { - const { rackId, name } = action - draft[rackId].name = name - }) - case DELETE_RACK: - return produce(state, (draft) => { - const { rackId } = action - delete draft[rackId] - }) - case ADD_MACHINE: - return produce(state, (draft) => { - const { machine } = action - draft[machine.rackId].machines.push(machine.id) - }) - case DELETE_MACHINE: - return produce(state, (draft) => { - const { machineId } = action - const machine = machines[machineId] - const rack = draft[machine.rackId] - const index = rack.machines.indexOf(machineId) - rack.machines.splice(index, 1) - }) - default: - return state - } -} - -export default rack diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js deleted file mode 100644 index c05c8bfa..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/topology/room.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import produce from 'immer' -import { STORE_TOPOLOGY } from '../../actions/topology' -import { ADD_TILE, DELETE_TILE } from '../../actions/topology/building' -import { DELETE_ROOM, EDIT_ROOM_NAME, ADD_ROOM } from '../../actions/topology/room' - -function room(state = {}, action, { tiles }) { - switch (action.type) { - case STORE_TOPOLOGY: - return action.entities.rooms || {} - case ADD_ROOM: - return produce(state, (draft) => { - const { room } = action - draft[room.id] = room - }) - case DELETE_ROOM: - return produce(state, (draft) => { - const { roomId } = action - delete draft[roomId] - }) - case EDIT_ROOM_NAME: - return produce(state, (draft) => { - const { roomId, name } = action - draft[roomId].name = name - }) - case ADD_TILE: - return produce(state, (draft) => { - const { tile } = action - draft[tile.roomId].tiles.push(tile.id) - }) - case DELETE_TILE: - return produce(state, (draft) => { - const { tileId } = action - const tile = tiles[tileId] - const room = draft[tile.roomId] - const index = room.tiles.indexOf(tileId) - room.tiles.splice(index, 1) - }) - default: - return state - } -} - -export default room diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js deleted file mode 100644 index 24c0e20c..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/topology/tile.js +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import produce from 'immer' -import { STORE_TOPOLOGY } from '../../actions/topology' -import { ADD_TILE, DELETE_TILE } from '../../actions/topology/building' -import { DELETE_RACK } from '../../actions/topology/rack' -import { ADD_RACK_TO_TILE } from '../../actions/topology/room' - -function tile(state = {}, action) { - switch (action.type) { - case STORE_TOPOLOGY: - return action.entities.tiles || {} - case ADD_TILE: - return produce(state, (draft) => { - const { tile } = action - draft[tile.id] = tile - }) - case DELETE_TILE: - return produce(state, (draft) => { - const { tileId } = action - delete draft[tileId] - }) - case ADD_RACK_TO_TILE: - return produce(state, (draft) => { - const { rack, tileId } = action - draft[tileId].rack = rack.id - }) - case DELETE_RACK: - return produce(state, (draft) => { - const { tileId } = action - draft[tileId].rack = undefined - }) - default: - return state - } -} - -export default tile diff --git a/opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js b/opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js deleted file mode 100644 index dff0a69e..00000000 --- a/opendc-web/opendc-web-ui/src/redux/reducers/topology/topology.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2021 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -import produce from 'immer' -import { STORE_TOPOLOGY } from '../../actions/topology' -import { ADD_ROOM, DELETE_ROOM } from '../../actions/topology/room' - -function topology(state = undefined, action) { - switch (action.type) { - case STORE_TOPOLOGY: - return action.topology - case ADD_ROOM: - return produce(state, (draft) => { - const { room } = action - draft.rooms.push(room.id) - }) - case DELETE_ROOM: - return produce(state, (draft) => { - const { roomId } = action - const index = draft.rooms.indexOf(roomId) - draft.rooms.splice(index, 1) - }) - default: - return state - } -} - -export default topology diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/index.js b/opendc-web/opendc-web-ui/src/redux/sagas/index.js deleted file mode 100644 index 0fabdb6d..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/index.js +++ /dev/null @@ -1,7 +0,0 @@ -import { fork } from 'redux-saga/effects' -import { watchServer, updateServer } from './topology' - -export default function* rootSaga() { - yield fork(watchServer) - yield fork(updateServer) -} diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js deleted file mode 100644 index 15147bcf..00000000 --- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js +++ /dev/null @@ -1,76 +0,0 @@ -import { QueryObserver, MutationObserver } from 'react-query' -import { normalize, denormalize } from 'normalizr' -import { select, put, take, race, getContext, call } from 'redux-saga/effects' -import { eventChannel } from 'redux-saga' -import { Topology } from '../../util/topology-schema' -import { storeTopology, OPEN_TOPOLOGY } from '../actions/topology' - -/** - * Update the topology on the server. - */ -export function* updateServer() { - const queryClient = yield getContext('queryClient') - const mutationObserver = new MutationObserver(queryClient, { mutationKey: 'updateTopology' }) - - while (true) { - yield take( - (action) => - action.type.startsWith('EDIT') || action.type.startsWith('ADD') || action.type.startsWith('DELETE') - ) - const topology = yield select((state) => state.topology) - - if (!topology.root) { - continue - } - - const denormalizedTopology = denormalize(topology.root, Topology, topology) - yield call([mutationObserver, mutationObserver.mutate], denormalizedTopology) - } -} - -/** - * Watch the topology on the server for changes. - */ -export function* watchServer() { - let { projectId, id } = yield take(OPEN_TOPOLOGY) - while (true) { - const channel = yield queryObserver(projectId, id) - - while (true) { - const [action, response] = yield race([take(OPEN_TOPOLOGY), take(channel)]) - - if (action) { - projectId = action.projectId - id = action.id - break - } - - const { isFetched, data } = response - // Only update the topology on the client-side when a new topology was fetched - if (isFetched) { - const { result: topologyId, entities } = normalize(data, Topology) - yield put(storeTopology(entities.topologies[topologyId], entities)) - } - } - } -} - -/** - * Observe changes for the topology with the specified identifier. - */ -function* queryObserver(projectId, id) { - const queryClient = yield getContext('queryClient') - const observer = new QueryObserver(queryClient, { queryKey: ['topologies', projectId, id] }) - - return eventChannel((emitter) => { - const unsubscribe = observer.subscribe((result) => { - emitter(result) - }) - - // Update result to make sure we did not miss any query updates - // between creating the observer and subscribing to it. - observer.updateResult() - - return unsubscribe - }) -} |
