From 607e8c72d85bf79dcd9bf28df96b239e2764bc30 Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Wed, 8 Jul 2020 20:14:36 +0200 Subject: Add routes for portfolios and scenarios --- frontend/src/sagas/experiments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontend/src/sagas') diff --git a/frontend/src/sagas/experiments.js b/frontend/src/sagas/experiments.js index f2b23017..79b4f74c 100644 --- a/frontend/src/sagas/experiments.js +++ b/frontend/src/sagas/experiments.js @@ -1,6 +1,6 @@ import { call, put, select } from 'redux-saga/effects' import { addPropToStoreObject, addToStore } from '../actions/objects' -import { deleteExperiment, getExperiment } from '../api/routes/experiments' +import { deleteExperiment, getExperiment } from '../api/routes/portfolios' import { addExperiment, getProject } from '../api/routes/projects' import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' import { fetchAndStoreAllTopologiesOfProject, fetchTopologyOfExperiment } from './topology' -- cgit v1.2.3 From 8aa174e70c01631ae4e00a6d208966fcd77cf972 Mon Sep 17 00:00:00 2001 From: Georgios Andreadis Date: Fri, 10 Jul 2020 10:21:46 +0200 Subject: Add implementation of portfolio and scenario UI structure --- frontend/src/sagas/experiments.js | 91 -------------------------------- frontend/src/sagas/index.js | 34 +++++++----- frontend/src/sagas/objects.js | 2 + frontend/src/sagas/portfolios.js | 108 ++++++++++++++++++++++++++++++++++++++ frontend/src/sagas/projects.js | 7 ++- frontend/src/sagas/scenarios.js | 72 +++++++++++++++++++++++++ frontend/src/sagas/topology.js | 15 ++---- 7 files changed, 212 insertions(+), 117 deletions(-) delete mode 100644 frontend/src/sagas/experiments.js create mode 100644 frontend/src/sagas/portfolios.js create mode 100644 frontend/src/sagas/scenarios.js (limited to 'frontend/src/sagas') diff --git a/frontend/src/sagas/experiments.js b/frontend/src/sagas/experiments.js deleted file mode 100644 index 79b4f74c..00000000 --- a/frontend/src/sagas/experiments.js +++ /dev/null @@ -1,91 +0,0 @@ -import { call, put, select } from 'redux-saga/effects' -import { addPropToStoreObject, addToStore } from '../actions/objects' -import { deleteExperiment, getExperiment } from '../api/routes/portfolios' -import { addExperiment, getProject } from '../api/routes/projects' -import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' -import { fetchAndStoreAllTopologiesOfProject, fetchTopologyOfExperiment } from './topology' - -export function* onOpenExperimentSucceeded(action) { - try { - const project = yield call(getProject, action.projectId) - yield put(addToStore('project', project)) - - const experiment = yield call(getExperiment, action.experimentId) - yield put(addToStore('experiment', experiment)) - - yield fetchExperimentSpecifications() - - yield fetchTopologyOfExperiment(experiment) - } catch (error) { - console.error(error) - } -} - -export function* onFetchExperimentsOfProject() { - try { - const currentProjectId = yield select((state) => state.currentProjectId) - const currentProject = yield select((state) => state.object.project[currentProjectId]) - - yield fetchExperimentSpecifications() - - for (let i in currentProject.experimentIds) { - const experiment = yield call(getExperiment, currentProject.experimentIds[i]) - yield put(addToStore('experiment', experiment)) - } - } catch (error) { - console.error(error) - } -} - -function* fetchExperimentSpecifications() { - try { - const currentProjectId = yield select((state) => state.currentProjectId) - yield fetchAndStoreAllTopologiesOfProject(currentProjectId) - yield fetchAndStoreAllTraces() - yield fetchAndStoreAllSchedulers() - } catch (error) { - console.error(error) - } -} - -export function* onAddExperiment(action) { - try { - const currentProjectId = yield select((state) => state.currentProjectId) - - const experiment = yield call( - addExperiment, - currentProjectId, - Object.assign({}, action.experiment, { - id: '-1', - projectId: currentProjectId, - }), - ) - yield put(addToStore('experiment', experiment)) - - const experimentIds = yield select((state) => state.objects.project[currentProjectId].experimentIds) - yield put( - addPropToStoreObject('project', currentProjectId, { - experimentIds: experimentIds.concat([experiment._id]), - }), - ) - } catch (error) { - console.error(error) - } -} - -export function* onDeleteExperiment(action) { - try { - yield call(deleteExperiment, action.id) - - const currentProjectId = yield select((state) => state.currentProjectId) - const experimentIds = yield select((state) => state.objects.project[currentProjectId].experimentIds) - - yield put( - addPropToStoreObject('project', currentProjectId, { - experimentIds: experimentIds.filter((id) => id !== action.id), - }), - ) - } catch (error) { - console.error(error) - } -} diff --git a/frontend/src/sagas/index.js b/frontend/src/sagas/index.js index 26d19d58..daae8d8c 100644 --- a/frontend/src/sagas/index.js +++ b/frontend/src/sagas/index.js @@ -1,11 +1,10 @@ import { takeEvery } from 'redux-saga/effects' import { LOG_IN } from '../actions/auth' import { - ADD_EXPERIMENT, - DELETE_EXPERIMENT, - FETCH_EXPERIMENTS_OF_PROJECT, - OPEN_EXPERIMENT_SUCCEEDED, -} from '../actions/experiments' + ADD_PORTFOLIO, + DELETE_PORTFOLIO, + OPEN_PORTFOLIO_SUCCEEDED, UPDATE_PORTFOLIO, +} from '../actions/portfolios' import { ADD_PROJECT, DELETE_PROJECT, OPEN_PROJECT_SUCCEEDED } from '../actions/projects' import { ADD_TILE, @@ -18,11 +17,11 @@ import { ADD_MACHINE, DELETE_RACK, EDIT_RACK_NAME } from '../actions/topology/ra import { ADD_RACK_TO_TILE, DELETE_ROOM, EDIT_ROOM_NAME } from '../actions/topology/room' import { DELETE_CURRENT_USER, FETCH_AUTHORIZATIONS_OF_CURRENT_USER } from '../actions/users' import { - onAddExperiment, - onDeleteExperiment, - onFetchExperimentsOfProject, - onOpenExperimentSucceeded, -} from './experiments' + onAddPortfolio, + onDeletePortfolio, + onOpenPortfolioSucceeded, + onUpdatePortfolio, +} from './portfolios' import { onDeleteCurrentUser } from './profile' import { onOpenProjectSucceeded, onProjectAdd, onProjectDelete } from './projects' import { @@ -44,6 +43,8 @@ import { } from './topology' 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' export default function* rootSaga() { yield takeEvery(LOG_IN, onFetchLoggedInUser) @@ -55,7 +56,8 @@ export default function* rootSaga() { yield takeEvery(DELETE_CURRENT_USER, onDeleteCurrentUser) yield takeEvery(OPEN_PROJECT_SUCCEEDED, onOpenProjectSucceeded) - yield takeEvery(OPEN_EXPERIMENT_SUCCEEDED, onOpenExperimentSucceeded) + yield takeEvery(OPEN_PORTFOLIO_SUCCEEDED, onOpenPortfolioSucceeded) + yield takeEvery(OPEN_SCENARIO_SUCCEEDED, onOpenScenarioSucceeded) yield takeEvery(ADD_TOPOLOGY, onAddTopology) yield takeEvery(DELETE_TOPOLOGY, onDeleteTopology) @@ -73,7 +75,11 @@ export default function* rootSaga() { yield takeEvery(ADD_UNIT, onAddUnit) yield takeEvery(DELETE_UNIT, onDeleteUnit) - yield takeEvery(FETCH_EXPERIMENTS_OF_PROJECT, onFetchExperimentsOfProject) - yield takeEvery(ADD_EXPERIMENT, onAddExperiment) - yield takeEvery(DELETE_EXPERIMENT, onDeleteExperiment) + yield takeEvery(ADD_PORTFOLIO, onAddPortfolio) + yield takeEvery(UPDATE_PORTFOLIO, onUpdatePortfolio) + yield takeEvery(DELETE_PORTFOLIO, onDeletePortfolio) + + yield takeEvery(ADD_SCENARIO, onAddScenario) + yield takeEvery(UPDATE_SCENARIO, onUpdateScenario) + yield takeEvery(DELETE_SCENARIO, onDeleteScenario) } diff --git a/frontend/src/sagas/objects.js b/frontend/src/sagas/objects.js index 8a12bd13..17b28d02 100644 --- a/frontend/src/sagas/objects.js +++ b/frontend/src/sagas/objects.js @@ -11,6 +11,8 @@ export const OBJECT_SELECTORS = { project: (state) => state.objects.project, user: (state) => state.objects.user, authorization: (state) => state.objects.authorization, + portfolio: (state) => state.objects.portfolio, + scenario: (state) => state.objects.scenario, cpu: (state) => state.objects.cpu, gpu: (state) => state.objects.gpu, memory: (state) => state.objects.memory, diff --git a/frontend/src/sagas/portfolios.js b/frontend/src/sagas/portfolios.js new file mode 100644 index 00000000..cda1be9b --- /dev/null +++ b/frontend/src/sagas/portfolios.js @@ -0,0 +1,108 @@ +import { call, put, select } from 'redux-saga/effects' +import { addPropToStoreObject, addToStore } from '../actions/objects' +import { addPortfolio, deletePortfolio, getPortfolio, updatePortfolio } from '../api/routes/portfolios' +import { getProject } from '../api/routes/projects' +import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' +import { fetchAndStoreAllTopologiesOfProject } from './topology' +import { getScenario } from '../api/routes/scenarios' + +export function* onOpenPortfolioSucceeded(action) { + try { + const project = yield call(getProject, action.projectId) + yield put(addToStore('project', project)) + yield fetchAndStoreAllTopologiesOfProject(project._id) + yield fetchPortfoliosOfProject() + yield fetchAndStoreAllSchedulers() + yield fetchAndStoreAllTraces() + + // TODO Fetch portfolio-specific metrics + } catch (error) { + console.error(error) + } +} + +export function* fetchPortfoliosOfProject() { + try { + const currentProjectId = yield select((state) => state.currentProjectId) + const currentProject = yield select((state) => state.objects.project[currentProjectId]) + + yield fetchAndStoreAllSchedulers() + yield fetchAndStoreAllTraces() + + for (let i in currentProject.portfolioIds) { + yield fetchPortfolioWithScenarios(currentProject.portfolioIds[i]) + } + } catch (error) { + console.error(error) + } +} + +export function* fetchPortfolioWithScenarios(portfolioId) { + try { + const portfolio = yield call(getPortfolio, portfolioId) + yield put(addToStore('portfolio', portfolio)) + + for (let i in portfolio.scenarioIds) { + const scenario = yield call(getScenario, portfolio.scenarioIds[i]) + yield put(addToStore('scenario', scenario)) + } + return portfolio + } catch (error) { + console.error(error) + } +} + +export function* onAddPortfolio(action) { + try { + const currentProjectId = yield select((state) => state.currentProjectId) + + const portfolio = yield call( + addPortfolio, + currentProjectId, + Object.assign({}, action.portfolio, { + projectId: currentProjectId, + scenarioIds: [], + }), + ) + yield put(addToStore('portfolio', portfolio)) + + const portfolioIds = yield select((state) => state.objects.project[currentProjectId].portfolioIds) + yield put( + addPropToStoreObject('project', currentProjectId, { + portfolioIds: portfolioIds.concat([portfolio._id]), + }), + ) + } catch (error) { + console.error(error) + } +} + +export function* onUpdatePortfolio(action) { + try { + const portfolio = yield call( + updatePortfolio, + action.portfolio._id, + action.portfolio, + ) + yield put(addToStore('portfolio', portfolio)) + } catch (error) { + console.error(error) + } +} + +export function* onDeletePortfolio(action) { + try { + yield call(deletePortfolio, action.id) + + const currentProjectId = yield select((state) => state.currentProjectId) + const portfolioIds = yield select((state) => state.objects.project[currentProjectId].portfolioIds) + + yield put( + addPropToStoreObject('project', currentProjectId, { + portfolioIds: portfolioIds.filter((id) => id !== action.id), + }), + ) + } catch (error) { + console.error(error) + } +} diff --git a/frontend/src/sagas/projects.js b/frontend/src/sagas/projects.js index d1f5e7f7..fdeea132 100644 --- a/frontend/src/sagas/projects.js +++ b/frontend/src/sagas/projects.js @@ -3,13 +3,18 @@ import { addToStore } from '../actions/objects' import { addProjectSucceeded, deleteProjectSucceeded } from '../actions/projects' import { addProject, deleteProject, getProject } from '../api/routes/projects' import { fetchAndStoreAllTopologiesOfProject } from './topology' +import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' +import { fetchPortfoliosOfProject } from './portfolios' export function* onOpenProjectSucceeded(action) { try { const project = yield call(getProject, action.id) yield put(addToStore('project', project)) - yield fetchAndStoreAllTopologiesOfProject(action.id) + yield fetchAndStoreAllTopologiesOfProject(action.id, true) + yield fetchPortfoliosOfProject() + yield fetchAndStoreAllSchedulers() + yield fetchAndStoreAllTraces() } catch (error) { console.error(error) } diff --git a/frontend/src/sagas/scenarios.js b/frontend/src/sagas/scenarios.js new file mode 100644 index 00000000..48b1e9be --- /dev/null +++ b/frontend/src/sagas/scenarios.js @@ -0,0 +1,72 @@ +import { call, put, select } from 'redux-saga/effects' +import { addPropToStoreObject, addToStore } from '../actions/objects' +import { getProject } from '../api/routes/projects' +import { fetchAndStoreAllSchedulers, fetchAndStoreAllTraces } from './objects' +import { fetchAndStoreAllTopologiesOfProject } from './topology' +import { addScenario, deleteScenario, updateScenario } from '../api/routes/scenarios' +import { fetchPortfolioWithScenarios } from './portfolios' + +export function* onOpenScenarioSucceeded(action) { + try { + const project = yield call(getProject, action.projectId) + yield put(addToStore('project', project)) + yield fetchAndStoreAllTopologiesOfProject(project._id) + yield fetchAndStoreAllSchedulers() + yield fetchAndStoreAllTraces() + yield fetchPortfolioWithScenarios(action.portfolioId) + + // TODO Fetch scenario-specific metrics + } catch (error) { + console.error(error) + } +} + +export function* onAddScenario(action) { + try { + const scenario = yield call( + addScenario, + action.scenario.portfolioId, + action.scenario, + ) + yield put(addToStore('scenario', scenario)) + + const scenarioIds = yield select((state) => state.objects.portfolio[action.scenario.portfolioId].scenarioIds) + yield put( + addPropToStoreObject('portfolio', action.scenario.portfolioId, { + scenarioIds: scenarioIds.concat([scenario._id]), + }), + ) + } catch (error) { + console.error(error) + } +} + +export function* onUpdateScenario(action) { + try { + const scenario = yield call( + updateScenario, + action.scenario._id, + action.scenario, + ) + yield put(addToStore('scenario', scenario)) + } catch (error) { + console.error(error) + } +} + +export function* onDeleteScenario(action) { + try { + yield call(deleteScenario, action.id) + + const currentPortfolioId = yield select((state) => state.currentPortfolioId) + const scenarioIds = yield select((state) => state.objects.project[currentPortfolioId].scenarioIds) + + yield put( + addPropToStoreObject('scenario', currentPortfolioId, { + scenarioIds: scenarioIds.filter((id) => id !== action.id), + }), + ) + } catch (error) { + console.error(error) + } +} diff --git a/frontend/src/sagas/topology.js b/frontend/src/sagas/topology.js index 008c7b63..e915f9ff 100644 --- a/frontend/src/sagas/topology.js +++ b/frontend/src/sagas/topology.js @@ -20,16 +20,7 @@ import { fetchAndStoreTopology, updateTopologyOnServer } from './objects' import { uuid } from 'uuidv4' import { addTopology, deleteTopology } from '../api/routes/topologies' -export function* fetchTopologyOfExperiment(experiment) { - try { - yield fetchAndStoreTopology(experiment.topologyId) - yield put(setCurrentTopology(experiment.topologyId)) - } catch (error) { - console.error(error) - } -} - -export function* fetchAndStoreAllTopologiesOfProject(projectId) { +export function* fetchAndStoreAllTopologiesOfProject(projectId, setTopology = false) { try { const project = yield select((state) => state.objects.project[projectId]) @@ -37,7 +28,9 @@ export function* fetchAndStoreAllTopologiesOfProject(projectId) { yield fetchAndStoreTopology(project.topologyIds[i]) } - yield put(setCurrentTopology(project.topologyIds[0])) + if (setTopology) { + yield put(setCurrentTopology(project.topologyIds[0])) + } } catch (error) { console.error(error) } -- cgit v1.2.3