From 28d6d13844db28745bc2813e87a367131f862070 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 20:59:11 +0200 Subject: refactor(ui): Move page components in separate files --- .../src/components/portfolios/PortfolioOverview.js | 121 ++++++++++++++++ .../components/portfolios/PortfolioResultInfo.js | 40 ++++++ .../src/components/portfolios/PortfolioResults.js | 156 +++++++++++++++++++++ .../portfolios/results/PortfolioResultInfo.js | 40 ------ .../portfolios/results/PortfolioResults.js | 134 ------------------ 5 files changed, 317 insertions(+), 174 deletions(-) create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js create mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js delete mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js delete mode 100644 opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js (limited to 'opendc-web/opendc-web-ui/src/components/portfolios') diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js new file mode 100644 index 00000000..580b0a29 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioOverview.js @@ -0,0 +1,121 @@ +/* + * 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 PropTypes from 'prop-types' +import { + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + Chip, + ChipGroup, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Grid, + GridItem, + Skeleton, +} from '@patternfly/react-core' +import React from 'react' +import { usePortfolio } from '../../data/project' +import { METRIC_NAMES } from '../../util/available-metrics' +import NewScenario from './NewScenario' +import ScenarioTable from './ScenarioTable' + +function PortfolioOverview({ portfolioId }) { + const { data: portfolio } = usePortfolio(portfolioId) + + return ( + + + + Details + + + + Name + + {portfolio?.name ?? } + + + + Scenarios + + {portfolio?.scenarioIds.length ?? } + + + + Metrics + + {portfolio?.targets?.enabledMetrics ? ( + portfolio.targets.enabledMetrics.length > 0 ? ( + + {portfolio.targets.enabledMetrics.map((metric) => ( + + {METRIC_NAMES[metric]} + + ))} + + ) : ( + 'No metrics enabled' + ) + ) : ( + + )} + + + + Repeats per Scenario + + {portfolio?.targets?.repeatsPerScenario ?? ( + + )} + + + + + + + + + + + + + Scenarios + + + + + + + + ) +} + +PortfolioOverview.propTypes = { + portfolioId: PropTypes.string, +} + +export default PortfolioOverview diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js new file mode 100644 index 00000000..dbfa928f --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResultInfo.js @@ -0,0 +1,40 @@ +/* + * 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 PropTypes from 'prop-types' +import { Tooltip } from '@patternfly/react-core' +import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' +import { METRIC_DESCRIPTIONS } from '../../util/available-metrics' + +function PortfolioResultInfo({ metric }) { + return ( + {METRIC_DESCRIPTIONS[metric]}}> + + + ) +} + +PortfolioResultInfo.propTypes = { + metric: PropTypes.string.isRequired, +} + +export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js new file mode 100644 index 00000000..00023d9e --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/portfolios/PortfolioResults.js @@ -0,0 +1,156 @@ +/* + * 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 React from 'react' +import PropTypes from 'prop-types' +import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' +import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_UNITS } from '../../util/available-metrics' +import { mean, std } from 'mathjs' +import approx from 'approximate-number' +import { + Bullseye, + Card, + CardActions, + CardBody, + CardHeader, + CardTitle, + EmptyState, + EmptyStateBody, + EmptyStateIcon, + Grid, + GridItem, + Spinner, + Title, +} from '@patternfly/react-core' +import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' +import { usePortfolioScenarios } from '../../data/project' +import PortfolioResultInfo from './PortfolioResultInfo' +import NewScenario from './NewScenario' + +const PortfolioResults = ({ portfolioId }) => { + const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) + + if (status === 'loading') { + return ( + + + + + Loading Results + + + + ) + } else if (status === 'error') { + return ( + + + + + Unable to connect + + + There was an error retrieving data. Check your connection and try again. + + + + ) + } else if (scenarios.length === 0) { + return ( + + + + + No results + + + No results are currently available for this portfolio. Run a scenario to obtain simulation + results. + + + + + ) + } + + const dataPerMetric = {} + + AVAILABLE_METRICS.forEach((metric) => { + dataPerMetric[metric] = scenarios + .filter((scenario) => scenario.results) + .map((scenario) => ({ + name: scenario.name, + value: mean(scenario.results[metric]), + errorX: std(scenario.results[metric]), + })) + }) + + return ( + + {AVAILABLE_METRICS.map((metric) => ( + + + + + + + {METRIC_NAMES[metric]} + + + + + + approx(tick)} + label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} + type="number" + /> + + + + + + + + + + + ))} + + ) +} + +PortfolioResults.propTypes = { + portfolioId: PropTypes.string, +} + +export default PortfolioResults diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.js deleted file mode 100644 index 09348e60..00000000 --- a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResultInfo.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. - */ - -import PropTypes from 'prop-types' -import { Tooltip } from '@patternfly/react-core' -import { OutlinedQuestionCircleIcon } from '@patternfly/react-icons' -import { METRIC_DESCRIPTIONS } from '../../../util/available-metrics' - -function PortfolioResultInfo({ metric }) { - return ( - {METRIC_DESCRIPTIONS[metric]}}> - - - ) -} - -PortfolioResultInfo.propTypes = { - metric: PropTypes.string.isRequired, -} - -export default PortfolioResultInfo diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js b/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js deleted file mode 100644 index f1883e68..00000000 --- a/opendc-web/opendc-web-ui/src/components/portfolios/results/PortfolioResults.js +++ /dev/null @@ -1,134 +0,0 @@ -import React from 'react' -import PropTypes from 'prop-types' -import { Bar, CartesianGrid, ComposedChart, ErrorBar, ResponsiveContainer, Scatter, XAxis, YAxis } from 'recharts' -import { AVAILABLE_METRICS, METRIC_NAMES, METRIC_UNITS } from '../../../util/available-metrics' -import { mean, std } from 'mathjs' -import approx from 'approximate-number' -import { - Bullseye, - Card, - CardActions, - CardBody, - CardHeader, - CardTitle, - EmptyState, - EmptyStateBody, - EmptyStateIcon, - Grid, - GridItem, - Spinner, - Title, -} from '@patternfly/react-core' -import { ErrorCircleOIcon, CubesIcon } from '@patternfly/react-icons' -import { usePortfolioScenarios } from '../../../data/project' -import PortfolioResultInfo from './PortfolioResultInfo' -import NewScenario from '../NewScenario' - -const PortfolioResults = ({ portfolioId }) => { - const { status, data: scenarios = [] } = usePortfolioScenarios(portfolioId) - - if (status === 'loading') { - return ( - - - - - Loading Results - - - - ) - } else if (status === 'error') { - return ( - - - - - Unable to connect - - - There was an error retrieving data. Check your connection and try again. - - - - ) - } else if (scenarios.length === 0) { - return ( - - - - - No results - - - No results are currently available for this portfolio. Run a scenario to obtain simulation - results. - - - - - ) - } - - const dataPerMetric = {} - - AVAILABLE_METRICS.forEach((metric) => { - dataPerMetric[metric] = scenarios - .filter((scenario) => scenario.results) - .map((scenario) => ({ - name: scenario.name, - value: mean(scenario.results[metric]), - errorX: std(scenario.results[metric]), - })) - }) - - return ( - - {AVAILABLE_METRICS.map((metric) => ( - - - - - - - {METRIC_NAMES[metric]} - - - - - - approx(tick)} - label={{ value: METRIC_UNITS[metric], position: 'bottom', offset: 0 }} - type="number" - /> - - - - - - - - - - - ))} - - ) -} - -PortfolioResults.propTypes = { - portfolioId: PropTypes.string, -} - -export default PortfolioResults -- cgit v1.2.3