diff options
Diffstat (limited to 'opendc-web/opendc-web-ui/src/data')
| -rw-r--r-- | opendc-web/opendc-web-ui/src/data/experiments.js | 16 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/src/data/project.js | 149 | ||||
| -rw-r--r-- | opendc-web/opendc-web-ui/src/data/topology.js | 55 |
3 files changed, 166 insertions, 54 deletions
diff --git a/opendc-web/opendc-web-ui/src/data/experiments.js b/opendc-web/opendc-web-ui/src/data/experiments.js index aef512e5..a76ea53f 100644 --- a/opendc-web/opendc-web-ui/src/data/experiments.js +++ b/opendc-web/opendc-web-ui/src/data/experiments.js @@ -20,18 +20,28 @@ * SOFTWARE. */ -import { useSelector } from 'react-redux' +import { useQuery } from 'react-query' +import { fetchTraces } from '../api/traces' +import { fetchSchedulers } from '../api/schedulers' + +/** + * Configure the query defaults for the experiment endpoints. + */ +export function configureExperimentClient(queryClient, auth) { + queryClient.setQueryDefaults('traces', { queryFn: () => fetchTraces(auth) }) + queryClient.setQueryDefaults('schedulers', { queryFn: () => fetchSchedulers(auth) }) +} /** * Return the available traces to experiment with. */ export function useTraces() { - return useSelector((state) => Object.values(state.objects.trace)) + return useQuery('traces') } /** * Return the available schedulers to experiment with. */ export function useSchedulers() { - return useSelector((state) => Object.values(state.objects.scheduler)) + return useQuery('schedulers') } diff --git a/opendc-web/opendc-web-ui/src/data/project.js b/opendc-web/opendc-web-ui/src/data/project.js index de2bc0d3..9bdcfb93 100644 --- a/opendc-web/opendc-web-ui/src/data/project.js +++ b/opendc-web/opendc-web-ui/src/data/project.js @@ -20,66 +20,143 @@ * SOFTWARE. */ -import { useSelector } from 'react-redux' +import { useQueries, useQuery } from 'react-query' +import { addProject, deleteProject, fetchProject, fetchProjects } from '../api/projects' +import { useRouter } from 'next/router' +import { addPortfolio, deletePortfolio, fetchPortfolio, fetchPortfoliosOfProject } from '../api/portfolios' +import { addScenario, deleteScenario, fetchScenario, fetchScenariosOfPortfolio } from '../api/scenarios' + +/** + * Configure the query defaults for the project endpoints. + */ +export function configureProjectClient(queryClient, auth) { + queryClient.setQueryDefaults('projects', { + queryFn: ({ queryKey }) => (queryKey.length === 1 ? fetchProjects(auth) : fetchProject(auth, queryKey[1])), + }) + + queryClient.setMutationDefaults('addProject', { + mutationFn: (data) => addProject(auth, data), + onSuccess: async (result) => { + queryClient.setQueryData('projects', (old = []) => [...old, result]) + }, + }) + queryClient.setMutationDefaults('deleteProject', { + mutationFn: (id) => deleteProject(auth, id), + onSuccess: async (result) => { + queryClient.setQueryData('projects', (old = []) => old.filter((project) => project._id !== result._id)) + queryClient.removeQueries(['projects', result._id]) + }, + }) + + queryClient.setQueryDefaults('portfolios', { + queryFn: ({ queryKey }) => fetchPortfolio(auth, queryKey[1]), + }) + queryClient.setQueryDefaults('project-portfolios', { + queryFn: ({ queryKey }) => fetchPortfoliosOfProject(auth, queryKey[1]), + }) + queryClient.setMutationDefaults('addPortfolio', { + mutationFn: (data) => addPortfolio(auth, data), + onSuccess: async (result) => { + queryClient.setQueryData(['projects', result.projectId], (old) => ({ + ...old, + portfolioIds: [...old.portfolioIds, result._id], + })) + queryClient.setQueryData(['portfolios', result._id], result) + }, + }) + queryClient.setMutationDefaults('deletePortfolio', { + mutationFn: (id) => deletePortfolio(auth, id), + onSuccess: async (result) => { + queryClient.setQueryData(['projects', result.projectId], (old) => ({ + ...old, + portfolioIds: old.portfolioIds.filter((id) => id !== result._id), + })) + queryClient.removeQueries(['portfolios', result._id]) + }, + }) + + queryClient.setQueryDefaults('scenarios', { + queryFn: ({ queryKey }) => fetchScenario(auth, queryKey[1]), + }) + queryClient.setQueryDefaults('portfolio-scenarios', { + queryFn: ({ queryKey }) => fetchScenariosOfPortfolio(auth, queryKey[1]), + }) + queryClient.setMutationDefaults('addScenario', { + mutationFn: (data) => addScenario(auth, data), + onSuccess: async (result) => { + // Register updated scenario in cache + queryClient.setQueryData(['scenarios', result._id], result) + + // Add scenario id to portfolio + queryClient.setQueryData(['portfolios', result.portfolioId], (old) => ({ + ...old, + scenarioIds: [...old.scenarioIds, result._id], + })) + }, + }) + queryClient.setMutationDefaults('deleteScenario', { + mutationFn: (id) => deleteScenario(auth, id), + onSuccess: async (result) => { + queryClient.setQueryData(['portfolios', result.portfolioId], (old) => ({ + ...old, + scenarioIds: old.scenarioIds.filter((id) => id !== result._id), + })) + queryClient.removeQueries(['scenarios', result._id]) + }, + }) +} /** * Return the available projects. */ export function useProjects() { - return useSelector((state) => state.projects) + return useQuery('projects') } /** - * Return the current active project. + * Return the project with the specified identifier. */ -export function useActiveProject() { - return useSelector((state) => - state.currentProjectId !== '-1' ? state.objects.project[state.currentProjectId] : undefined - ) +export function useProject(projectId) { + return useQuery(['projects', projectId], { enabled: !!projectId }) } /** - * Return the active portfolio. + * Return the portfolio with the specified identifier. */ -export function useActivePortfolio() { - return useSelector((state) => state.objects.portfolio[state.currentPortfolioId]) +export function usePortfolio(portfolioId) { + return useQuery(['portfolios', portfolioId], { enabled: !!portfolioId }) } /** - * Return the active scenario. + * Return the portfolios of the specified project. */ -export function useActiveScenario() { - return useSelector((state) => state.objects.scenario[state.currentScenarioId]) +export function useProjectPortfolios(projectId) { + return useQuery(['project-portfolios', projectId], { enabled: !!projectId }) } /** - * Return the portfolios for the specified project id. + * Return the scenarios with the specified identifiers. */ -export function usePortfolios(projectId) { - return useSelector((state) => { - let portfolios = state.objects.project[projectId] - ? state.objects.project[projectId].portfolioIds.map((t) => state.objects.portfolio[t]) - : [] - if (portfolios.filter((t) => !t).length > 0) { - portfolios = [] - } - - return portfolios - }) +export function useScenarios(scenarioIds) { + return useQueries( + scenarioIds.map((scenarioId) => ({ + queryKey: ['scenarios', scenarioId], + })) + ) } /** - * Return the scenarios for the specified portfolio id. + * Return the scenarios of the specified portfolio. */ -export function useScenarios(portfolioId) { - return useSelector((state) => { - let scenarios = state.objects.portfolio[portfolioId] - ? state.objects.portfolio[portfolioId].scenarioIds.map((t) => state.objects.scenario[t]) - : [] - if (scenarios.filter((t) => !t).length > 0) { - scenarios = [] - } +export function usePortfolioScenarios(portfolioId) { + return useQuery(['portfolio-scenarios', portfolioId], { enabled: !!portfolioId }) +} - return scenarios - }) +/** + * Return the current active project identifier. + */ +export function useActiveProjectId() { + const router = useRouter() + const { project } = router.query + return project } diff --git a/opendc-web/opendc-web-ui/src/data/topology.js b/opendc-web/opendc-web-ui/src/data/topology.js index d3ffb3e1..8db75877 100644 --- a/opendc-web/opendc-web-ui/src/data/topology.js +++ b/opendc-web/opendc-web-ui/src/data/topology.js @@ -21,6 +21,43 @@ */ import { useSelector } from 'react-redux' +import { useQueries, useQuery } from 'react-query' +import { addTopology, deleteTopology, fetchTopologiesOfProject, fetchTopology, updateTopology } from '../api/topologies' + +/** + * Configure the query defaults for the topology endpoints. + */ +export function configureTopologyClient(queryClient, auth) { + queryClient.setQueryDefaults('topologies', { queryFn: ({ queryKey }) => fetchTopology(auth, queryKey[1]) }) + queryClient.setQueryDefaults('project-topologies', { + queryFn: ({ queryKey }) => fetchTopologiesOfProject(auth, queryKey[1]), + }) + + queryClient.setMutationDefaults('addTopology', { + mutationFn: (data) => addTopology(auth, data), + onSuccess: async (result) => { + queryClient.setQueryData(['projects', result.projectId], (old) => ({ + ...old, + topologyIds: [...old.topologyIds, result._id], + })) + queryClient.setQueryData(['topologies', result._id], result) + }, + }) + queryClient.setMutationDefaults('updateTopology', { + mutationFn: (data) => updateTopology(auth, data), + onSuccess: async (result) => queryClient.setQueryData(['topologies', result._id], result), + }) + queryClient.setMutationDefaults('deleteTopology', { + mutationFn: (id) => deleteTopology(auth, id), + onSuccess: async (result) => { + queryClient.setQueryData(['projects', result.projectId], (old) => ({ + ...old, + topologyIds: old.topologyIds.filter((id) => id !== result._id), + })) + queryClient.removeQueries(['topologies', result._id]) + }, + }) +} /** * Return the current active topology. @@ -30,20 +67,8 @@ export function useActiveTopology() { } /** - * Return the topologies for the active project. + * Return the topologies of the specified project. */ -export function useProjectTopologies() { - return useSelector(({ currentProjectId, objects }) => { - if (currentProjectId === '-1' || !objects.project[currentProjectId]) { - return [] - } - - const topologies = objects.project[currentProjectId].topologyIds.map((t) => objects.topology[t]) - - if (topologies.filter((t) => !t).length > 0) { - return [] - } - - return topologies - }) +export function useProjectTopologies(projectId) { + return useQuery(['project-topologies', projectId], { enabled: !!projectId }) } |
