summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/redux/sagas
diff options
context:
space:
mode:
authorFabian Mastenbroek <mail.fabianm@gmail.com>2021-07-07 16:27:49 +0200
committerFabian Mastenbroek <mail.fabianm@gmail.com>2021-07-07 16:28:25 +0200
commite5e5d2c65e583493870bc0b62fb185c5e757c13f (patch)
treedc9bc25517ce36e155932212f598bf2375519d34 /opendc-web/opendc-web-ui/src/redux/sagas
parentaa788a3ad18badfac8beaabdaffc88b9e52f9306 (diff)
ui: Migrate project APIs to React Query
This change updates the OpenDC frontend to use React Query for fetching and mutating project data. Previously, this state was tracked and synchronized via Redux. Migrating to React Query greatly simplifies the state synchronization logic necessary in the frontend.
Diffstat (limited to 'opendc-web/opendc-web-ui/src/redux/sagas')
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/index.js6
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/objects.js7
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js29
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/projects.js43
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js7
-rw-r--r--opendc-web/opendc-web-ui/src/redux/sagas/topology.js30
6 files changed, 32 insertions, 90 deletions
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/index.js b/opendc-web/opendc-web-ui/src/redux/sagas/index.js
index a8f44843..939be691 100644
--- a/opendc-web/opendc-web-ui/src/redux/sagas/index.js
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/index.js
@@ -11,7 +11,7 @@ import { ADD_UNIT, DELETE_MACHINE, DELETE_UNIT } from '../actions/topology/machi
import { ADD_MACHINE, DELETE_RACK, EDIT_RACK_NAME } from '../actions/topology/rack'
import { ADD_RACK_TO_TILE, DELETE_ROOM, EDIT_ROOM_NAME } from '../actions/topology/room'
import { onAddPortfolio, onDeletePortfolio, onOpenPortfolioSucceeded, onUpdatePortfolio } from './portfolios'
-import { onFetchProjects, onOpenProjectSucceeded, onProjectAdd, onProjectDelete } from './projects'
+import { onOpenProjectSucceeded } from './projects'
import {
onAddMachine,
onAddRackToTile,
@@ -36,10 +36,6 @@ import { onAddPrefab } from './prefabs'
import { ADD_PREFAB } from '../actions/prefabs'
export default function* rootSaga() {
- yield takeEvery(FETCH_PROJECTS, onFetchProjects)
- yield takeEvery(ADD_PROJECT, onProjectAdd)
- yield takeEvery(DELETE_PROJECT, onProjectDelete)
-
yield takeEvery(OPEN_PROJECT_SUCCEEDED, onOpenProjectSucceeded)
yield takeEvery(OPEN_PORTFOLIO_SUCCEEDED, onOpenPortfolioSucceeded)
yield takeEvery(OPEN_SCENARIO_SUCCEEDED, onOpenScenarioSucceeded)
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/objects.js b/opendc-web/opendc-web-ui/src/redux/sagas/objects.js
index e5fd092d..5523dd57 100644
--- a/opendc-web/opendc-web-ui/src/redux/sagas/objects.js
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/objects.js
@@ -1,13 +1,11 @@
import { call, put, select, getContext } from 'redux-saga/effects'
import { addToStore } from '../actions/objects'
import { getAllSchedulers } from '../../api/schedulers'
-import { getProject } from '../../api/projects'
import { getAllTraces } from '../../api/traces'
import { getTopology, updateTopology } from '../../api/topologies'
import { uuid } from 'uuidv4'
export const OBJECT_SELECTORS = {
- project: (state) => state.objects.project,
user: (state) => state.objects.user,
authorization: (state) => state.objects.authorization,
portfolio: (state) => state.objects.portfolio,
@@ -41,11 +39,6 @@ function* fetchAndStoreObjects(objectType, apiCall) {
return objects
}
-export const fetchAndStoreProject = function* (id) {
- const auth = yield getContext('auth')
- return yield fetchAndStoreObject('project', id, call(getProject, auth, id))
-}
-
export const fetchAndStoreTopology = function* (id) {
const topologyStore = yield select(OBJECT_SELECTORS['topology'])
const roomStore = yield select(OBJECT_SELECTORS['room'])
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js b/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js
index 48d1ad3e..c32fcdc0 100644
--- a/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/portfolios.js
@@ -1,7 +1,7 @@
import { call, put, select, delay, getContext } from 'redux-saga/effects'
-import { addPropToStoreObject, addToStore } from '../actions/objects'
+import { addToStore } from '../actions/objects'
import { addPortfolio, deletePortfolio, getPortfolio, updatePortfolio } from '../../api/portfolios'
-import { getProject } from '../../api/projects'
+import { fetchProject } from '../../api/projects'
import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects'
import { fetchAndStoreAllTopologiesOfProject } from './topology'
import { getScenario } from '../../api/scenarios'
@@ -9,9 +9,11 @@ import { getScenario } from '../../api/scenarios'
export function* onOpenPortfolioSucceeded(action) {
try {
const auth = yield getContext('auth')
- const project = yield call(getProject, auth, action.projectId)
- yield put(addToStore('project', project))
- yield fetchAndStoreAllTopologiesOfProject(project._id)
+ const queryClient = yield getContext('queryClient')
+ const project = yield call(() =>
+ queryClient.fetchQuery(`projects/${action.projectId}`, () => fetchProject(auth, action.projectId))
+ )
+ yield fetchAndStoreAllTopologiesOfProject(action.projectId)
yield fetchPortfoliosOfProject(project)
yield fetchAndStoreAllSchedulers()
yield fetchAndStoreAllTraces()
@@ -94,13 +96,6 @@ export function* onAddPortfolio(action) {
})
)
yield put(addToStore('portfolio', portfolio))
-
- const portfolioIds = yield select((state) => state.objects.project[projectId].portfolioIds)
- yield put(
- addPropToStoreObject('project', projectId, {
- portfolioIds: portfolioIds.concat([portfolio._id]),
- })
- )
} catch (error) {
console.error(error)
}
@@ -119,17 +114,7 @@ export function* onUpdatePortfolio(action) {
export function* onDeletePortfolio(action) {
try {
const auth = yield getContext('auth')
- const portfolio = yield select((state) => state.objects.portfolio[action.id])
-
yield call(deletePortfolio, auth, action.id)
-
- const portfolioIds = yield select((state) => state.objects.project[portfolio.projectId].portfolioIds)
-
- yield put(
- addPropToStoreObject('project', portfolio.projectId, {
- portfolioIds: portfolioIds.filter((id) => id !== action.id),
- })
- )
} catch (error) {
console.error(error)
}
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/projects.js b/opendc-web/opendc-web-ui/src/redux/sagas/projects.js
index 0689090a..96a4323c 100644
--- a/opendc-web/opendc-web-ui/src/redux/sagas/projects.js
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/projects.js
@@ -1,16 +1,16 @@
-import { call, put, getContext } from 'redux-saga/effects'
-import { addToStore } from '../actions/objects'
-import { addProjectSucceeded, deleteProjectSucceeded, fetchProjectsSucceeded } from '../actions/projects'
-import { addProject, deleteProject, getProject, getProjects } from '../../api/projects'
+import { call, getContext } from 'redux-saga/effects'
import { fetchAndStoreAllTopologiesOfProject } from './topology'
import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects'
import { fetchPortfoliosOfProject } from './portfolios'
+import { fetchProject } from '../../api/projects'
export function* onOpenProjectSucceeded(action) {
try {
const auth = yield getContext('auth')
- const project = yield call(getProject, auth, action.id)
- yield put(addToStore('project', project))
+ const queryClient = yield getContext('queryClient')
+ const project = yield call(() =>
+ queryClient.fetchQuery(`projects/${action.id}`, () => fetchProject(auth, action.id))
+ )
yield fetchAndStoreAllTopologiesOfProject(action.id, true)
yield fetchPortfoliosOfProject(project)
@@ -20,34 +20,3 @@ export function* onOpenProjectSucceeded(action) {
console.error(error)
}
}
-
-export function* onProjectAdd(action) {
- try {
- const auth = yield getContext('auth')
- const project = yield call(addProject, auth, { name: action.name })
- yield put(addToStore('project', project))
- yield put(addProjectSucceeded(project))
- } catch (error) {
- console.error(error)
- }
-}
-
-export function* onProjectDelete(action) {
- try {
- const auth = yield getContext('auth')
- yield call(deleteProject, auth, action.id)
- yield put(deleteProjectSucceeded(action.id))
- } catch (error) {
- console.error(error)
- }
-}
-
-export function* onFetchProjects(action) {
- try {
- const auth = yield getContext('auth')
- const projects = yield call(getProjects, auth)
- yield put(fetchProjectsSucceeded(projects))
- } catch (error) {
- console.error(error)
- }
-}
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js b/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js
index b2979636..3fe12981 100644
--- a/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/scenarios.js
@@ -1,6 +1,6 @@
import { call, put, select, getContext } from 'redux-saga/effects'
import { addPropToStoreObject, addToStore } from '../actions/objects'
-import { getProject } from '../../api/projects'
+import { fetchProject } from '../../api/projects'
import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects'
import { fetchAndStoreAllTopologiesOfProject } from './topology'
import { addScenario, deleteScenario, updateScenario } from '../../api/scenarios'
@@ -9,7 +9,10 @@ import { fetchPortfolioWithScenarios, watchForPortfolioResults } from './portfol
export function* onOpenScenarioSucceeded(action) {
try {
const auth = yield getContext('auth')
- const project = yield call(getProject, auth, action.projectId)
+ const queryClient = yield getContext('queryClient')
+ const project = yield call(() =>
+ queryClient.fetchQuery(`projects/${action.projectId}`, () => fetchProject(auth, action.projectId))
+ )
yield put(addToStore('project', project))
yield fetchAndStoreAllTopologiesOfProject(project._id)
yield fetchAndStoreAllSchedulers()
diff --git a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js
index 4f7bc8db..3f41e1d4 100644
--- a/opendc-web/opendc-web-ui/src/redux/sagas/topology.js
+++ b/opendc-web/opendc-web-ui/src/redux/sagas/topology.js
@@ -19,10 +19,15 @@ import {
import { fetchAndStoreTopology, getTopologyAsObject, updateTopologyOnServer } from './objects'
import { uuid } from 'uuidv4'
import { addTopology, deleteTopology } from '../../api/topologies'
+import { fetchProject } from '../../api/projects'
export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = false) {
try {
- const project = yield select((state) => state.objects.project[projectId])
+ const auth = yield getContext('auth')
+ const queryClient = yield getContext('queryClient')
+ const project = yield call(() =>
+ queryClient.fetchQuery(`projects/${projectId}`, () => fetchProject(auth, projectId))
+ )
for (let i in project.topologyIds) {
yield fetchAndStoreTopology(project.topologyIds[i])
@@ -51,13 +56,6 @@ export function* onAddTopology(action) {
const auth = yield getContext('auth')
const topology = yield call(addTopology, auth, { ...topologyToBeCreated, projectId })
yield fetchAndStoreTopology(topology._id)
-
- const topologyIds = yield select((state) => state.objects.project[projectId].topologyIds)
- yield put(
- addPropToStoreObject('project', projectId, {
- topologyIds: topologyIds.concat([topology._id]),
- })
- )
yield put(setCurrentTopology(topology._id))
} catch (error) {
console.error(error)
@@ -66,21 +64,19 @@ export function* onAddTopology(action) {
export function* onDeleteTopology(action) {
try {
- const topology = yield select((state) => state.objects.topologies[action.id])
- const topologyIds = yield select((state) => state.objects.project[topology.projectId].topologyIds)
+ const auth = yield getContext('auth')
+ const queryClient = yield getContext('queryClient')
+ const project = yield call(() =>
+ queryClient.fetchQuery(`projects/${action.projectId}`, () => fetchProject(auth, action.projectId))
+ )
+ const topologyIds = project?.topologyIds ?? []
+
const currentTopologyId = yield select((state) => state.currentTopologyId)
if (currentTopologyId === action.id) {
yield put(setCurrentTopology(topologyIds.filter((t) => t !== action.id)[0]))
}
- const auth = yield getContext('auth')
yield call(deleteTopology, auth, action.id)
-
- yield put(
- addPropToStoreObject('project', topology.projectId, {
- topologyIds: topologyIds.filter((id) => id !== action.id),
- })
- )
} catch (error) {
console.error(error)
}