From a9da76621c1be7a11bf292e868a8f7c22f2ea203 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 26 Mar 2023 21:20:42 +0100 Subject: bug(web): Inform user when deleted topology is still used This change fixes #135 which showed that trying to delete a topology used by a scenario would result in nothing happening in the UI and a 500 error being returned by the server. We check whether a scenario still references the topology and show an error to the user if that happens. Fixes #135 --- .../src/components/projects/TopologyTable.js | 104 +++++++++++++-------- 1 file changed, 64 insertions(+), 40 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components') diff --git a/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js b/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js index 62deace0..1c2c4f04 100644 --- a/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js +++ b/opendc-web/opendc-web-ui/src/components/projects/TopologyTable.js @@ -20,18 +20,22 @@ * SOFTWARE. */ -import { Bullseye } from '@patternfly/react-core' +import { Bullseye, AlertGroup, Alert, AlertVariant, AlertActionCloseButton } from '@patternfly/react-core' import PropTypes from 'prop-types' import Link from 'next/link' import { Tr, Th, Thead, Td, ActionsColumn, Tbody, TableComposable } from '@patternfly/react-table' -import React from 'react' +import React, { useState } from 'react' import TableEmptyState from '../util/TableEmptyState' import { parseAndFormatDateTime } from '../../util/date-time' import { useTopologies, useDeleteTopology } from '../../data/topology' function TopologyTable({ projectId }) { + const [error, setError] = useState('') + const { status, data: topologies = [] } = useTopologies(projectId) - const { mutate: deleteTopology } = useDeleteTopology() + const { mutate: deleteTopology } = useDeleteTopology({ + onError: (error) => setError(error), + }) const actions = ({ number }) => [ { @@ -42,45 +46,65 @@ function TopologyTable({ projectId }) { ] return ( - - - - Name - Rooms - Last Edited - - - - {topologies.map((topology) => ( - - - {topology.name} - - - {topology.rooms.length === 1 ? '1 room' : `${topology.rooms.length} rooms`} - - {parseAndFormatDateTime(topology.updatedAt)} - - - - - ))} - {topologies.length === 0 && ( + <> + + {error && ( + setError(null)} + /> + } + /> + )} + + + - - - - - + Name + Rooms + Last Edited - )} - - + + + {topologies.map((topology) => ( + + + + {topology.name} + + + + {topology.rooms.length === 1 ? '1 room' : `${topology.rooms.length} rooms`} + + {parseAndFormatDateTime(topology.updatedAt)} + + + + + ))} + {topologies.length === 0 && ( + + + + + + + + )} + + + ) } -- cgit v1.2.3 From efe1cebb4c1d8f07c0f1afb8bf08732d9fe20125 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 26 Mar 2023 21:49:26 +0100 Subject: bug(web): Do not offset hover layer after dragging This change fixes #136 which reported that the grid and cursor will fall out of sync when dragging or moving the grid when placing rooms or objects. Fixes #136 --- .../opendc-web-ui/src/components/topologies/map/MapStage.js | 12 ++++-------- .../components/topologies/map/layers/HoverLayerComponent.js | 10 +++++----- .../src/components/topologies/map/layers/ObjectHoverLayer.js | 4 +--- .../src/components/topologies/map/layers/RoomHoverLayer.js | 4 +--- 4 files changed, 11 insertions(+), 19 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components') diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js index 1b9fff72..e2b626ec 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/MapStage.js @@ -1,9 +1,8 @@ -import React, { useRef, useState, useContext } from 'react' +import React, { useRef, useState } from 'react' import PropTypes from 'prop-types' import { useHotkeys } from 'react-hotkeys-hook' import { Stage } from 'react-konva' import { MAP_MAX_SCALE, MAP_MIN_SCALE, MAP_MOVE_PIXELS_PER_EVENT, MAP_SCALE_PER_EVENT } from './MapConstants' -import { ReactReduxContext } from 'react-redux' import useResizeObserver from 'use-resize-observer' import { mapContainer } from './MapStage.module.css' import MapLayer from './layers/MapLayer' @@ -13,7 +12,6 @@ import ScaleIndicator from './controls/ScaleIndicator' import Toolbar from './controls/Toolbar' function MapStage({ hotkeysRef }) { - const reduxContext = useContext(ReactReduxContext) const stageRef = useRef(null) const { width = 500, height = 500 } = useResizeObserver({ ref: stageRef.current?.attrs?.container }) const [[x, y], setPos] = useState([0, 0]) @@ -68,11 +66,9 @@ function MapStage({ hotkeysRef }) { x={x} y={y} > - - - - - + + + diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js index 2b1060c0..d7e0c56a 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/HoverLayerComponent.js @@ -15,11 +15,11 @@ function HoverLayerComponent({ isEnabled, isValid, onClick, children }) { const stage = layer.getStage() - // Transform used to convert mouse coordinates to world coordinates - const transform = stage.getAbsoluteTransform().copy() - transform.invert() - stage.on('mousemove.hover', () => { + // Transform used to convert mouse coordinates to world coordinates + const transform = stage.getAbsoluteTransform().copy() + transform.invert() + const { x, y } = transform.point(stage.getPointerPosition()) setPos([x, y]) }) @@ -38,7 +38,7 @@ function HoverLayerComponent({ isEnabled, isValid, onClick, children }) { const y = gridY * TILE_SIZE_IN_PIXELS return ( - + (valid ? onClick(gridX, gridY) : undefined)} /> {children ? React.cloneElement(children, { x, y, scale: 1 }) : undefined} diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js index 1f00de36..5e741a3b 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/ObjectHoverLayer.js @@ -27,7 +27,7 @@ import { findTileWithPosition } from '../../../../util/tile-calculations' import HoverLayerComponent from './HoverLayerComponent' import TilePlusIcon from '../elements/TilePlusIcon' -function ObjectHoverLayer() { +export default function ObjectHoverLayer() { const isEnabled = useSelector((state) => state.construction.inRackConstructionMode) const isValid = useSelector((state) => (x, y) => { if (state.interactionLevel.mode !== 'ROOM') { @@ -49,5 +49,3 @@ function ObjectHoverLayer() { ) } - -export default ObjectHoverLayer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js index 727f4e25..b9cfcaf4 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/map/layers/RoomHoverLayer.js @@ -30,7 +30,7 @@ import { } from '../../../../util/tile-calculations' import HoverLayerComponent from './HoverLayerComponent' -function RoomHoverLayer() { +export default function RoomHoverLayer() { const dispatch = useDispatch() const onClick = (x, y) => dispatch(toggleTileAtLocation(x, y)) const isEnabled = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') @@ -57,5 +57,3 @@ function RoomHoverLayer() { return } - -export default RoomHoverLayer -- cgit v1.2.3 From 760cb3632d9c7352ae866667657785297502ce08 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 26 Mar 2023 22:05:43 +0100 Subject: bug(web): Fix access to machines on lower shelves This change addresses #137 which reports that machines on shelves lower than the top shelve cannot be accessed and doing so will cause the UI to disappear and an error message to be generated. The issue was caused by using the incorrect logic for selecting the machine at a certain rack position. Fixes #137 --- .../topologies/sidebar/machine/MachineSidebar.js | 8 +- .../sidebar/rack/MachineListComponent.js | 91 ++++++++++++---------- 2 files changed, 56 insertions(+), 43 deletions(-) (limited to 'opendc-web/opendc-web-ui/src/components') diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js index 6f89e10b..8a4c33dc 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/MachineSidebar.js @@ -15,7 +15,13 @@ import { useSelector } from 'react-redux' function MachineSidebar({ tileId, position }) { const machine = useSelector(({ topology }) => { const rack = topology.racks[topology.tiles[tileId].rack] - return topology.machines[rack.machines[position - 1]] + + for (const machineId of rack.machines) { + const machine = topology.machines[machineId] + if (machine.position === position) { + return machine + } + } }) const machineId = machine.id return ( diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js index de7a2140..02c97730 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js @@ -17,49 +17,56 @@ import { Machine } from '../../../../shapes' function MachineListComponent({ machines = [], onSelect, onAdd }) { return ( - {machines.map((machine, index) => - machine ? ( - onSelect(index + 1)}> - - - {machines.length - index}U - , - - onSelect(index + 1)} machine={machine} /> - , - ]} - /> - - - - - - ) : ( - - - - {machines.length - index}U - , - - Empty Slot - , - ]} - /> - - - - - + {machines + .map((machine, index) => + machine ? ( + onSelect(index + 1)}> + + + {index + 1}U + , + + onSelect(index + 1)} machine={machine} /> + , + ]} + /> + + + + + + ) : ( + + + + {index + 1}U + , + + Empty Slot + , + ]} + /> + + + + + + ) ) - )} + .reverse()} ) } -- cgit v1.2.3 From 42caec326fe5b6f4a0a2fe73e4cf2ba26ecba23d Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Sun, 26 Mar 2023 22:09:05 +0100 Subject: bug(web): Do not allow selection of empty unit This change fixes #138 which reports that when adding a unit to a machine, if the user does not select a unit and presses add, the UI will crash. We now disable the add button until the user has selected a unit. --- .../src/components/topologies/sidebar/machine/UnitAddComponent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'opendc-web/opendc-web-ui/src/components') diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js index 4507b409..18cba23a 100644 --- a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/machine/UnitAddComponent.js @@ -27,7 +27,7 @@ function UnitAddComponent({ units, onAdd }) { ))} - -- cgit v1.2.3