From 235057cd170f1583db14bf93ea7d2de39e492356 Mon Sep 17 00:00:00 2001 From: vincent van beek Date: Fri, 27 Mar 2026 14:22:41 +0100 Subject: add prefabs for racks (#392) * add prefabs for racks --- .../topologies/sidebar/rack/AddPrefab.js | 78 ++++++++++++++++++++-- .../sidebar/room/RackConstructionComponent.js | 47 ++++++++++--- .../sidebar/room/RackConstructionContainer.js | 9 ++- 3 files changed, 116 insertions(+), 18 deletions(-) (limited to 'opendc-web/opendc-web-server/src/main/webui/components') diff --git a/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/rack/AddPrefab.js b/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/rack/AddPrefab.js index 6a0c3ff3..d3266537 100644 --- a/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/rack/AddPrefab.js +++ b/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/rack/AddPrefab.js @@ -22,15 +22,81 @@ import PropTypes from 'prop-types' import React from 'react' -import { Button } from '@patternfly/react-core' +import { Button, AlertGroup, Alert, AlertVariant, AlertActionCloseButton } from '@patternfly/react-core' import { SaveIcon } from '@patternfly/react-icons' +import { useSelector } from 'react-redux' +import { useRouter } from 'next/router' +import { denormalize } from 'normalizr' +import { Rack } from '../../../../util/topology-schema' +import { useNewRackPrefab } from '../../../../data/rack-prefabs' + +function AddPrefab({ tileId }) { + const [alert, setAlert] = React.useState(null) + const router = useRouter() + const { project: projectId } = router.query + const { mutate: addRackPrefab } = useNewRackPrefab() + + const rackId = useSelector((state) => state.topology.tiles[tileId]?.rack) + const rack = useSelector((state) => { + const topologyState = state.topology + if (!rackId || !topologyState.racks[rackId]) { + return null + } + return denormalize(rackId, Rack, topologyState) + }) + + const onClick = () => { + if (rack && projectId) { + addRackPrefab( + { + projectId, + name: rack.name, + rack: { + ...rack, + id: 0, + machines: rack.machines.map((m) => ({ ...m, id: 0 })), + }, + }, + { + onSuccess: () => { + setAlert({ variant: AlertVariant.success, title: 'Rack saved as prefab' }) + }, + onError: (error) => { + setAlert({ variant: AlertVariant.danger, title: `Failed to save rack: ${error}` }) + }, + } + ) + } + } -function AddPrefab() { - const onClick = () => {} // TODO return ( - + <> + + {alert && ( + setAlert(null)} + /> + } + /> + )} + + + ) } diff --git a/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionComponent.js b/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionComponent.js index a384d5d5..f9eab381 100644 --- a/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionComponent.js +++ b/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionComponent.js @@ -1,9 +1,11 @@ import PropTypes from 'prop-types' import React from 'react' -import { Button } from '@patternfly/react-core' +import { Button, FormSelect, FormSelectOption } from '@patternfly/react-core' import { PlusIcon, TimesIcon } from '@patternfly/react-icons' -const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, isEditingRoom }) => { +const RackConstructionComponent = ({ onStart, onStop, inRackConstructionMode, isEditingRoom, prefabs = [] }) => { + const [selectedPrefabId, setSelectedPrefabId] = React.useState('') + if (inRackConstructionMode) { return ( + <> + + + {prefabs.map((prefab) => ( + + ))} + + + ) } @@ -30,6 +54,7 @@ RackConstructionComponent.propTypes = { onStop: PropTypes.func, inRackConstructionMode: PropTypes.bool, isEditingRoom: PropTypes.bool, + prefabs: PropTypes.array, } export default RackConstructionComponent diff --git a/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionContainer.js b/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionContainer.js index e04287a5..70f1b8e6 100644 --- a/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionContainer.js +++ b/opendc-web/opendc-web-server/src/main/webui/components/topologies/sidebar/room/RackConstructionContainer.js @@ -22,21 +22,28 @@ import React from 'react' import { useDispatch, useSelector } from 'react-redux' +import { useRouter } from 'next/router' import { startRackConstruction, stopRackConstruction } from '../../../../redux/actions/topology/room' +import { useRackPrefabs } from '../../../../data/rack-prefabs' import RackConstructionComponent from './RackConstructionComponent' function RackConstructionContainer(props) { + const router = useRouter() + const { project: projectId } = router.query + const { data: prefabs = [] } = useRackPrefabs(projectId) + const isRackConstructionMode = useSelector((state) => state.construction.inRackConstructionMode) const isEditingRoom = useSelector((state) => state.construction.currentRoomInConstruction !== '-1') const dispatch = useDispatch() - const onStart = () => dispatch(startRackConstruction()) + const onStart = (rackPrefab) => dispatch(startRackConstruction(rackPrefab)) const onStop = () => dispatch(stopRackConstruction()) return ( -- cgit v1.2.3