summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-ui/src/components')
-rw-r--r--opendc-web/opendc-web-ui/src/components/AppHeaderUser.js32
-rw-r--r--opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js1
-rw-r--r--opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js3
-rw-r--r--opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js7
-rw-r--r--opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js3
-rw-r--r--opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitType.js25
6 files changed, 58 insertions, 13 deletions
diff --git a/opendc-web/opendc-web-ui/src/components/AppHeaderUser.js b/opendc-web/opendc-web-ui/src/components/AppHeaderUser.js
index e271accb..3a73d9ba 100644
--- a/opendc-web/opendc-web-ui/src/components/AppHeaderUser.js
+++ b/opendc-web/opendc-web-ui/src/components/AppHeaderUser.js
@@ -28,26 +28,44 @@ import {
DropdownItem,
DropdownGroup,
Avatar,
+ Progress,
+ ProgressSize,
+ DropdownSeparator,
} from '@patternfly/react-core'
import { useReducer } from 'react'
import { useAuth } from '../auth'
+import useUser from '../data/user'
export default function AppHeaderUser() {
const { logout, user, isAuthenticated, isLoading } = useAuth()
const username = isAuthenticated || isLoading ? user?.name : 'Anonymous'
const avatar = isAuthenticated || isLoading ? user?.picture : '/img/avatar.svg'
+ const { data } = useUser()
+ const simulationBudget = data?.accounting?.simulationTimeBudget ?? 3600
+ const simulationTime = data?.accounting?.simulationTime | 0
+
const [isDropdownOpen, toggleDropdown] = useReducer((t) => !t, false)
const userDropdownItems = [
- <DropdownGroup key="group 2">
- <DropdownItem
- key="group 2 logout"
- isDisabled={!isAuthenticated}
- onClick={() => logout({ returnTo: window.location.origin })}
- >
- Logout
+ <DropdownGroup key="budget" label="Monthly Simulation Budget">
+ <DropdownItem isDisabled>
+ <Progress
+ min={0}
+ max={simulationBudget}
+ value={simulationTime}
+ title={`${Math.ceil(simulationTime / 60)} of ${Math.ceil(simulationBudget / 60)} minutes`}
+ size={ProgressSize.sm}
+ />
</DropdownItem>
</DropdownGroup>,
+ <DropdownSeparator key="separator" />,
+ <DropdownItem
+ key="group 2 logout"
+ isDisabled={!isAuthenticated}
+ onClick={() => logout({ returnTo: window.location.origin })}
+ >
+ Logout
+ </DropdownItem>,
]
const avatarComponent = avatar ? (
diff --git a/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js b/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js
index 8dc52f7a..64218a0a 100644
--- a/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js
+++ b/opendc-web/opendc-web-ui/src/components/portfolios/ScenarioTable.js
@@ -64,7 +64,6 @@ function ScenarioTable({ portfolio, status }) {
) : (
'Unknown Topology'
)}
- ,
</Td>
<Td dataLabel="Workload">{`${scenario.workload.trace.name} (${
scenario.workload.samplingFraction * 100
diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js
index 6b136120..a0054ef6 100644
--- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js
+++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddContainer.js
@@ -25,6 +25,7 @@ import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import UnitAddComponent from './UnitAddComponent'
import { addUnit } from '../../../../redux/actions/topology/machine'
+import UnitType from './UnitType'
function UnitAddContainer({ machineId, unitType }) {
const units = useSelector((state) => Object.values(state.topology[unitType]))
@@ -37,7 +38,7 @@ function UnitAddContainer({ machineId, unitType }) {
UnitAddContainer.propTypes = {
machineId: PropTypes.string.isRequired,
- unitType: PropTypes.string.isRequired,
+ unitType: UnitType.isRequired,
}
export default UnitAddContainer
diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js
index daa3e7a7..75ab0ad7 100644
--- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js
+++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListComponent.js
@@ -20,9 +20,10 @@ import {
} from '@patternfly/react-core'
import { CubesIcon, InfoIcon, TrashIcon } from '@patternfly/react-icons'
import { ProcessingUnit, StorageUnit } from '../../../../shapes'
+import UnitType from './UnitType'
function UnitInfo({ unit, unitType }) {
- if (unitType === 'cpu' || unitType === 'gpu') {
+ if (unitType === 'cpus' || unitType === 'gpus') {
return (
<DescriptionList>
<DescriptionListGroup>
@@ -60,7 +61,7 @@ function UnitInfo({ unit, unitType }) {
}
UnitInfo.propTypes = {
- unitType: PropTypes.string.isRequired,
+ unitType: UnitType.isRequired,
unit: PropTypes.oneOfType([ProcessingUnit, StorageUnit]).isRequired,
}
@@ -104,7 +105,7 @@ function UnitListComponent({ unitType, units, onDelete }) {
}
UnitListComponent.propTypes = {
- unitType: PropTypes.string.isRequired,
+ unitType: UnitType.isRequired,
units: PropTypes.arrayOf(PropTypes.oneOfType([ProcessingUnit, StorageUnit])).isRequired,
onDelete: PropTypes.func,
}
diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js
index 25e750c4..bcd4bdcc 100644
--- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js
+++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitListContainer.js
@@ -25,6 +25,7 @@ import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
import UnitListComponent from './UnitListComponent'
import { deleteUnit } from '../../../../redux/actions/topology/machine'
+import UnitType from './UnitType'
function UnitListContainer({ machineId, unitType }) {
const dispatch = useDispatch()
@@ -40,7 +41,7 @@ function UnitListContainer({ machineId, unitType }) {
UnitListContainer.propTypes = {
machineId: PropTypes.string.isRequired,
- unitType: PropTypes.string.isRequired,
+ unitType: UnitType.isRequired,
}
export default UnitListContainer
diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitType.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitType.js
new file mode 100644
index 00000000..b6d7bf8b
--- /dev/null
+++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitType.js
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022 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'
+
+export default PropTypes.oneOf(['cpus', 'gpus', 'memories', 'storages'])