/* Copyright (C) 2022 Cloudbase Solutions SRL This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */ import React from "react"; import { observer } from "mobx-react"; import styled from "styled-components"; import moment from "moment"; import CopyValue from "@src/components/ui/CopyValue"; import StatusImage from "@src/components/ui/StatusComponents/StatusImage"; import Button from "@src/components/ui/Button"; import { ThemePalette, ThemeProps } from "@src/components/Theme"; import { MetalHubDisk, MetalHubNic, MetalHubServer, } from "@src/@types/MetalHub"; import { ArrowStyled, GlobalStyle, HeaderIcon, HeaderName, Row, RowBody, RowBodyColumn, RowBodyColumnValue, RowHeader, RowHeaderColumn, } from "@src/components/modules/TransferModule/TransferDetailsTable"; import { Collapse } from "react-collapse"; import LoadingButton from "@src/components/ui/LoadingButton"; import StatusPill from "@src/components/ui/StatusComponents/StatusPill"; const Wrapper = styled.div` ${ThemeProps.exactWidth(ThemeProps.contentWidth)} margin: 0 auto; padding-left: 126px; `; const Info = styled.div` display: flex; flex-wrap: wrap; margin-top: 32px; margin-left: -32px; `; const Field = styled.div` ${ThemeProps.exactWidth("calc(50% - 32px)")} margin-bottom: 32px; margin-left: 32px; `; const Value = styled.div``; const Label = styled.div` font-size: 10px; font-weight: ${ThemeProps.fontWeights.medium}; color: ${ThemePalette.grayscale[3]}; text-transform: uppercase; margin-bottom: 3px; `; const LoadingWrapper = styled.div` display: flex; justify-content: center; width: 100%; margin: 32px 0 64px 0; `; const Buttons = styled.div` margin-top: 64px; display: flex; justify-content: space-between; `; const ButtonsColumn = styled.div` display: flex; flex-direction: column; button { margin-bottom: 16px; &:last-child { margin-bottom: 0; } } `; const Table = styled.div``; const TableBody = styled.div``; const TableHeader = styled.div` background: ${ThemePalette.grayscale[1]}; border-radius: ${ThemeProps.borderRadius}; margin-bottom: 32px; &:last-child { margin-bottom: 0; } `; const TableHeaderInfo = styled.div` padding: 16px; border-bottom: 1px solid ${ThemePalette.grayscale[5]}; font-size: 16px; `; const TableBodyContent = styled.div` font-size: 14px; `; const HeaderSubtitle = styled.span` color: ${ThemePalette.grayscale[5]}; margin-left: 4px; `; type Props = { server: MetalHubServer | null; loading: boolean; creatingReplica: boolean; creatingMigration: boolean; onCreateReplicaClick: () => void; onCreateMigrationClick: () => void; onDeleteClick: () => void; }; type State = { openedRows: string[]; }; @observer class MetalHubServerDetailsContent extends React.Component { state: State = { openedRows: [], }; handleRowClick(id: string) { if (this.state.openedRows.find(i => i === id)) { this.setState(prevState => ({ openedRows: prevState.openedRows.filter(i => id !== i), })); } else { this.setState(prevState => ({ openedRows: [...prevState.openedRows, id], })); } } renderLoading() { return ( ); } renderButtons() { if (this.props.loading) { return null; } const creating = this.props.creatingReplica || this.props.creatingMigration; return ( {this.props.creatingReplica ? ( Loading Wizard ... ) : ( )} {this.props.creatingMigration ? ( Loading Wizard ... ) : ( )} ); } renderInfo() { if (this.props.loading || !this.props.server) { return null; } const server = this.props.server; return ( {this.renderValue(server.hostname || "-")} {this.renderValue(String(server.id))} {server.active ? ( ) : ( )} {this.renderValue(String(server.api_endpoint))} {moment(server.created_at).format("YYYY-MM-DD HH:mm:ss")} {moment(server.updated_at).format("YYYY-MM-DD HH:mm:ss")} {this.renderValue(server.firmware_type || "-")} {server.physical_cores || "-"} physical, {server.logical_cores || "-"}{" "} logical {server.memory ? this.renderValue( `${(server.memory / 1024 / 1024 / 1024).toFixed(2)} GB` ) : "-"} {server.os_info.os_name ? this.renderValue( `${server.os_info.os_name} ${server.os_info.os_version}` ) : "-"} ); } renderValue(value: string) { return value !== "-" ? ( ) : ( {value} ); } renderNics(nics: MetalHubNic[]) { return nics.map(nic => { const isOpened = Boolean( this.state.openedRows.find(i => i === nic.nic_name) ); return ( { this.handleRowClick(nic.nic_name); }} > {nic.nic_name} {[ `MAC Address: ${nic.mac_address}`, `IP Addresses: ${nic.ip_addresses.join(", ")}`, `Interface Type: ${nic.interface_type}`, ].map(l => ( {l} ))} ); }); } renderPartitions( partitions: MetalHubDisk["partitions"] = [], sectorSize = 0 ) { return partitions.map(partition => { if (!partition.partition_uuid) { return null; } const isOpened = Boolean( this.state.openedRows.find(i => i === partition.partition_uuid) ); const size = partition.sectors * sectorSize; const sizeString = sectorSize ? size < 1024 * 1024 * 1024 ? `${(size / 1024 / 1024).toFixed(2)} MB` : `${(size / 1024 / 1024 / 1024).toFixed(2)} GB` : "Size unavailable"; return ( { this.handleRowClick(partition.partition_uuid!); }} > {partition.name} {sizeString} {[ `ID: ${partition.partition_uuid}`, `Path: ${partition.path}`, `Sectors: ${partition.sectors}`, `Start Sector: ${partition.start_sector}`, `End Sector: ${partition.end_sector}`, ].map(l => ( {l} ))} ); }); } renderNicsTable() { if (this.props.loading || !this.props.server?.nics) { return null; } return ( {this.renderNics(this.props.server.nics)}
); } renderPartitionsTable() { if (this.props.loading || !this.props.server?.disks) { return null; } return ( {this.props.server.disks.map(disk => ( {disk.name}{" "} {disk.size ? ( {(disk.size / 1024 / 1024 / 1024).toFixed(2)} GB ) : null} {this.renderPartitions( disk.partitions, disk.physical_sector_size )} ))}
); } render() { return ( {this.renderInfo()} {this.renderPartitionsTable()} {this.renderNicsTable()} {this.props.loading ? this.renderLoading() : null} {this.renderButtons()} ); } } export default MetalHubServerDetailsContent;