summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontend/public/index.html16
-rw-r--r--frontend/src/components/app/results/PortfolioResultsComponent.js28
-rw-r--r--frontend/src/components/app/sidebars/project/PortfolioListComponent.js4
-rw-r--r--frontend/src/components/app/sidebars/project/ProjectSidebarComponent.js6
-rw-r--r--frontend/src/components/app/sidebars/project/ScenarioListComponent.js4
-rw-r--r--frontend/src/components/app/sidebars/project/TopologyListComponent.js4
-rw-r--r--frontend/src/sagas/portfolios.js31
-rw-r--r--frontend/src/sagas/scenarios.js3
8 files changed, 66 insertions, 30 deletions
diff --git a/frontend/public/index.html b/frontend/public/index.html
index 0254eff4..b19fdbda 100644
--- a/frontend/public/index.html
+++ b/frontend/public/index.html
@@ -37,8 +37,8 @@
<meta name="google-site-verification" content="YIR4LkQTv6WmOdWv8MkeiUKni-0Yu3WHylLp4VvUMig"/>
<!-- CDN dependencies -->
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css"
- integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
+ integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
<script src="https://use.fontawesome.com/ece66a2e7c.js"></script>
@@ -61,14 +61,14 @@
</noscript>
<div id="root"></div>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"
- integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
+<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
+ integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
crossorigin="anonymous"></script>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js"
- integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4"
+<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"
+ integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo"
crossorigin="anonymous"></script>
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js"
- integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1"
+<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"
+ integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI"
crossorigin="anonymous"></script>
</body>
</html>
diff --git a/frontend/src/components/app/results/PortfolioResultsComponent.js b/frontend/src/components/app/results/PortfolioResultsComponent.js
index e9b33777..286dd48c 100644
--- a/frontend/src/components/app/results/PortfolioResultsComponent.js
+++ b/frontend/src/components/app/results/PortfolioResultsComponent.js
@@ -54,18 +54,24 @@ const PortfolioResultsComponent = ({ portfolio, scenarios }) => {
<div className="col-6 mb-2" key={metric}>
<h4>{METRIC_NAMES[metric]}</h4>
<ResponsiveContainer aspect={16 / 9} width="100%">
- <ComposedChart data={dataPerMetric[metric]} margin={{ bottom: 15 }} layout="vertical" animationDUration={0}>
- <CartesianGrid strokeDasharray="3 3"/>
- <XAxis tickFormatter={(tick) => approx(tick)}
- label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }}
- type="number"/>
- <YAxis dataKey="name" type="category"/>
- <Bar dataKey="value" fill="#3399FF"/>
- <Scatter dataKey="value" opacity={0}>
- <ErrorBar dataKey="errorX" width={10} strokeWidth={3} stroke="#FF6600"
- direction="x"/>
+ <ComposedChart data={dataPerMetric[metric]} margin={{ bottom: 15 }} layout="vertical">
+ <CartesianGrid strokeDasharray="3 3" />
+ <XAxis
+ tickFormatter={(tick) => approx(tick)}
+ label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }}
+ type="number"
+ />
+ <YAxis dataKey="name" type="category" />
+ <Bar dataKey="value" fill="#3399FF" isAnimationActive={false} />
+ <Scatter dataKey="value" opacity={0} isAnimationActive={false}>
+ <ErrorBar
+ dataKey="errorX"
+ width={10}
+ strokeWidth={3}
+ stroke="#FF6600"
+ direction="x"
+ />
</Scatter>
-
</ComposedChart>
</ResponsiveContainer>
</div>
diff --git a/frontend/src/components/app/sidebars/project/PortfolioListComponent.js b/frontend/src/components/app/sidebars/project/PortfolioListComponent.js
index 837666af..b000b9e2 100644
--- a/frontend/src/components/app/sidebars/project/PortfolioListComponent.js
+++ b/frontend/src/components/app/sidebars/project/PortfolioListComponent.js
@@ -37,13 +37,13 @@ class PortfolioListComponent extends React.Component {
<div className="row mb-1">
<div
className={
- 'col-8 align-self-center ' +
+ 'col-7 align-self-center ' +
(portfolio._id === this.props.currentPortfolioId ? 'font-weight-bold' : '')
}
>
{portfolio.name}
</div>
- <div className="col-4 text-right">
+ <div className="col-5 text-right">
<Link
className="btn btn-outline-primary mr-1 fa fa-play"
to={`/projects/${this.props.currentProjectId}/portfolios/${portfolio._id}`}
diff --git a/frontend/src/components/app/sidebars/project/ProjectSidebarComponent.js b/frontend/src/components/app/sidebars/project/ProjectSidebarComponent.js
index aadc451e..4789315e 100644
--- a/frontend/src/components/app/sidebars/project/ProjectSidebarComponent.js
+++ b/frontend/src/components/app/sidebars/project/ProjectSidebarComponent.js
@@ -5,8 +5,10 @@ import PortfolioListContainer from '../../../../containers/app/sidebars/project/
const ProjectSidebarComponent = ({ collapsible }) => (
<Sidebar isRight={false} collapsible={collapsible}>
- <TopologyListContainer />
- <PortfolioListContainer />
+ <div className="h-100 overflow-auto container-fluid">
+ <TopologyListContainer />
+ <PortfolioListContainer />
+ </div>
</Sidebar>
)
diff --git a/frontend/src/components/app/sidebars/project/ScenarioListComponent.js b/frontend/src/components/app/sidebars/project/ScenarioListComponent.js
index 8b50eff0..e775a663 100644
--- a/frontend/src/components/app/sidebars/project/ScenarioListComponent.js
+++ b/frontend/src/components/app/sidebars/project/ScenarioListComponent.js
@@ -26,13 +26,13 @@ class ScenarioListComponent extends React.Component {
<div key={scenario._id} className="row mb-1">
<div
className={
- 'col-8 pl-5 align-self-center ' +
+ 'col-7 pl-5 align-self-center ' +
(scenario._id === this.props.currentScenarioId ? 'font-weight-bold' : '')
}
>
{scenario.name}
</div>
- <div className="col-4 text-right">
+ <div className="col-5 text-right">
<Link
className="btn btn-outline-primary mr-1 fa fa-play disabled"
to={`/projects/${this.props.currentProjectId}/portfolios/${scenario.portfolioId}/scenarios/${scenario._id}`}
diff --git a/frontend/src/components/app/sidebars/project/TopologyListComponent.js b/frontend/src/components/app/sidebars/project/TopologyListComponent.js
index 498ee26d..2f42f7e4 100644
--- a/frontend/src/components/app/sidebars/project/TopologyListComponent.js
+++ b/frontend/src/components/app/sidebars/project/TopologyListComponent.js
@@ -34,13 +34,13 @@ class TopologyListComponent extends React.Component {
<div key={topology._id} className="row mb-1">
<div
className={
- 'col-8 align-self-center ' +
+ 'col-7 align-self-center ' +
(topology._id === this.props.currentTopologyId ? 'font-weight-bold' : '')
}
>
{topology.name}
</div>
- <div className="col-4 text-right">
+ <div className="col-5 text-right">
<span
className="btn btn-outline-primary mr-1 fa fa-play"
onClick={() => this.onChoose(topology._id)}
diff --git a/frontend/src/sagas/portfolios.js b/frontend/src/sagas/portfolios.js
index 3c004282..ed9bfd29 100644
--- a/frontend/src/sagas/portfolios.js
+++ b/frontend/src/sagas/portfolios.js
@@ -1,4 +1,4 @@
-import { call, put, select } from 'redux-saga/effects'
+import { call, put, select, delay } 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'
@@ -15,7 +15,34 @@ export function* onOpenPortfolioSucceeded(action) {
yield fetchAndStoreAllSchedulers()
yield fetchAndStoreAllTraces()
- // TODO Fetch portfolio-specific metrics
+ yield watchForPortfolioResults()
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* watchForPortfolioResults() {
+ try {
+ const currentPortfolioId = yield select((state) => state.currentPortfolioId)
+ let unfinishedScenarios = yield getCurrentUnfinishedScenarios()
+
+ while (unfinishedScenarios.length > 0) {
+ yield delay(3000)
+ yield fetchPortfolioWithScenarios(currentPortfolioId)
+ unfinishedScenarios = yield getCurrentUnfinishedScenarios()
+ }
+ } catch (error) {
+ console.error(error)
+ }
+}
+
+export function* getCurrentUnfinishedScenarios() {
+ try {
+ const currentPortfolioId = yield select((state) => state.currentPortfolioId)
+ const scenarioIds = yield select((state) => state.objects.portfolio[currentPortfolioId].scenarioIds)
+ const scenarioObjects = yield select((state) => state.objects.scenario)
+ const scenarios = scenarioIds.map((s) => scenarioObjects[s])
+ return scenarios.filter((s) => !s || s.simulation.state === 'QUEUED' || s.simulation.state === 'RUNNING')
} catch (error) {
console.error(error)
}
diff --git a/frontend/src/sagas/scenarios.js b/frontend/src/sagas/scenarios.js
index 3ecc3fc4..720c0c97 100644
--- a/frontend/src/sagas/scenarios.js
+++ b/frontend/src/sagas/scenarios.js
@@ -4,7 +4,7 @@ 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'
+import { fetchPortfolioWithScenarios, watchForPortfolioResults } from './portfolios'
export function* onOpenScenarioSucceeded(action) {
try {
@@ -32,6 +32,7 @@ export function* onAddScenario(action) {
scenarioIds: scenarioIds.concat([scenario._id]),
})
)
+ yield watchForPortfolioResults()
} catch (error) {
console.error(error)
}