From 5e5ab63b280eb446db4090733cd3ad2e97d02018 Mon Sep 17 00:00:00 2001 From: Fabian Mastenbroek Date: Mon, 19 Jul 2021 15:47:23 +0200 Subject: refactor(ui): Restructure components per page This change updates the source structure of the OpenDC frontend to follow the page structure. --- .../topologies/sidebar/rack/AddPrefab.js | 44 +++++++++++++ .../topologies/sidebar/rack/DeleteRackContainer.js | 59 +++++++++++++++++ .../topologies/sidebar/rack/MachineComponent.js | 46 ++++++++++++++ .../sidebar/rack/MachineListComponent.js | 73 ++++++++++++++++++++++ .../sidebar/rack/MachineListContainer.js | 56 +++++++++++++++++ .../topologies/sidebar/rack/RackNameContainer.js | 22 +++++++ .../topologies/sidebar/rack/RackSidebar.js | 58 +++++++++++++++++ .../sidebar/rack/RackSidebar.module.scss | 12 ++++ 8 files changed, 370 insertions(+) create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js create mode 100644 opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss (limited to 'opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack') diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js new file mode 100644 index 00000000..e944c2e8 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/AddPrefab.js @@ -0,0 +1,44 @@ +/* + * 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 React from 'react' +import { useDispatch } from 'react-redux' +import { Button } from '@patternfly/react-core' +import { SaveIcon } from '@patternfly/react-icons' +import { addPrefab } from '../../../../api/prefabs' + +function AddPrefab({ tileId }) { + const dispatch = useDispatch() + const onClick = () => dispatch(addPrefab('name', tileId)) + return ( + + ) +} + +AddPrefab.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default AddPrefab diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js new file mode 100644 index 00000000..80c6349a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/DeleteRackContainer.js @@ -0,0 +1,59 @@ +/* + * 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 React, { useState } from 'react' +import { useDispatch } from 'react-redux' +import TrashIcon from '@patternfly/react-icons/dist/js/icons/trash-icon' +import { Button } from '@patternfly/react-core' +import ConfirmationModal from '../../../util/modals/ConfirmationModal' +import { deleteRack } from '../../../../redux/actions/topology/rack' + +function DeleteRackContainer({ tileId }) { + const dispatch = useDispatch() + const [isVisible, setVisible] = useState(false) + const callback = (isConfirmed) => { + if (isConfirmed) { + dispatch(deleteRack(tileId)) + } + setVisible(false) + } + return ( + <> + + + + ) +} + +DeleteRackContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default DeleteRackContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js new file mode 100644 index 00000000..921622d6 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineComponent.js @@ -0,0 +1,46 @@ +import PropTypes from 'prop-types' +import React from 'react' +import Image from 'next/image' +import { Flex, Label } from '@patternfly/react-core' +import { Machine } from '../../../../shapes' + +const UnitIcon = ({ id, type }) => ( + {'Machine +) + +UnitIcon.propTypes = { + id: PropTypes.string, + type: PropTypes.string, +} + +function MachineComponent({ machine, onClick }) { + const hasNoUnits = + machine.cpus.length + machine.gpus.length + machine.memories.length + machine.storages.length === 0 + + return ( + onClick()}> + {machine.cpus.length > 0 ? : undefined} + {machine.gpus.length > 0 ? : undefined} + {machine.memories.length > 0 ? : undefined} + {machine.storages.length > 0 ? : undefined} + {hasNoUnits ? ( + + ) : undefined} + + ) +} + +MachineComponent.propTypes = { + machine: Machine.isRequired, + onClick: PropTypes.func, +} + +export default MachineComponent 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 new file mode 100644 index 00000000..de7a2140 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListComponent.js @@ -0,0 +1,73 @@ +import PropTypes from 'prop-types' +import React from 'react' +import MachineComponent from './MachineComponent' +import { + Badge, + Button, + DataList, + DataListAction, + DataListCell, + DataListItem, + DataListItemCells, + DataListItemRow, +} from '@patternfly/react-core' +import { AngleRightIcon, PlusIcon } from '@patternfly/react-icons' +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 + , + ]} + /> + + + + + + ) + )} + + ) +} + +MachineListComponent.propTypes = { + machines: PropTypes.arrayOf(Machine), + onSelect: PropTypes.func.isRequired, + onAdd: PropTypes.func.isRequired, +} + +export default MachineListComponent diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js new file mode 100644 index 00000000..6fbff949 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/MachineListContainer.js @@ -0,0 +1,56 @@ +/* + * 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 React, { useMemo } from 'react' +import { useDispatch, useSelector } from 'react-redux' +import MachineListComponent from './MachineListComponent' +import { goFromRackToMachine } from '../../../../redux/actions/interaction-level' +import { addMachine } from '../../../../redux/actions/topology/rack' + +function MachineListContainer({ tileId, ...props }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const machines = useSelector((state) => rack.machines.map((id) => state.objects.machine[id])) + const machinesNull = useMemo(() => { + const res = Array(rack.capacity).fill(null) + for (const machine of machines) { + res[machine.position - 1] = machine + } + return res + }, [rack, machines]) + const dispatch = useDispatch() + + return ( + dispatch(addMachine(rack._id, index))} + onSelect={(index) => dispatch(goFromRackToMachine(index))} + /> + ) +} + +MachineListContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default MachineListContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js new file mode 100644 index 00000000..09d73af7 --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackNameContainer.js @@ -0,0 +1,22 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { useDispatch, useSelector } from 'react-redux' +import NameComponent from '../NameComponent' +import { editRackName } from '../../../../redux/actions/topology/rack' + +const RackNameContainer = ({ tileId }) => { + const { name: rackName, _id } = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + const dispatch = useDispatch() + const callback = (name) => { + if (name) { + dispatch(editRackName(_id, name)) + } + } + return +} + +RackNameContainer.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackNameContainer diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js new file mode 100644 index 00000000..3c9f152a --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.js @@ -0,0 +1,58 @@ +import PropTypes from 'prop-types' +import React from 'react' +import { machineListContainer, sidebarContainer } from './RackSidebar.module.scss' +import RackNameContainer from './RackNameContainer' +import AddPrefab from './AddPrefab' +import DeleteRackContainer from './DeleteRackContainer' +import MachineListContainer from './MachineListContainer' +import { + Skeleton, + TextContent, + TextList, + TextListItem, + TextListItemVariants, + TextListVariants, + Title, +} from '@patternfly/react-core' +import { useSelector } from 'react-redux' + +function RackSidebar({ tileId }) { + const rack = useSelector((state) => state.objects.rack[state.objects.tile[tileId].rack]) + + return ( +
+ + Details + + + Name + + + + + Capacity + + {rack?.capacity ?? } + + + Actions + + + + Slots + +
+ +
+
+ ) +} + +RackSidebar.propTypes = { + tileId: PropTypes.string.isRequired, +} + +export default RackSidebar diff --git a/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss new file mode 100644 index 00000000..6f258aec --- /dev/null +++ b/opendc-web/opendc-web-ui/src/components/topologies/sidebar/rack/RackSidebar.module.scss @@ -0,0 +1,12 @@ +.sidebarContainer { + display: flex; + height: 100%; + max-height: 100%; + flex-direction: column; +} + +.machineListContainer { + flex: 1; + overflow-y: scroll; + margin-top: 10px; +} -- cgit v1.2.3