/*
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;