| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- import React, { Component } from "react";
- import * as ReactDom from "react-dom/client";
- import { DAL } from "../DAL/systemInfo";
- import {SystemInfo, CpuInfo, NetworkInfo, DriveInfo} from "../../src/models/systemInfo";
- import menu from "./menu";
- interface SystemInfoComponentState {
- loading: boolean;
- hidden: boolean;
- }
- interface SystemInfoProps {
- hostname: string;
- setHidden: any;//((val:boolean)=>void|null);
- }
- export class SystemInfoComponent extends Component<SystemInfoProps, SystemInfoComponentState> {
- private data: SystemInfo|undefined = undefined;
- public constructor(props: SystemInfoProps) {
- super(props);
- this.state = {
- loading: true,
- hidden: this.isFiltered()
- };
- DAL.SystemInfo.getInfo(this.props.hostname).then(data => {
- this.data = data; // FIXME error handling
- this.setState({...this.state, loading: false});
- });
- menu.addFilterEventListener(() => {
- this.refreshFilter();
- });
- }
- private isFiltered(): boolean {
- const filterShown = menu.getFilteredHostnames();
- return (filterShown.indexOf(this.props.hostname) < 0);
- }
- private refreshFilter() {
- const hidden = this.isFiltered();
- if (hidden === this.state.hidden)
- return;
- this.setState({...this.state, hidden: hidden});
- }
- private layout(content: React.JSX.Element) {
- return <section key={this.props.hostname} className={(this.state.hidden ? "hidden" : "")}><div><h1>{this.props.hostname}</h1>{content}</div></section>;
- }
- private statItem(key: string, value: string|React.JSX.Element, listKey?: number): React.JSX.Element {
- if (!value)
- return <></>;
- key = key.charAt(0).toUpperCase()+String(key).slice(1);
- if (listKey === undefined)
- return <li>{key}: {value}</li>;
- return <li key={listKey}>{key}: {value}</li>;
- }
- private statItemNumber(key: string, value: number): React.JSX.Element {
- if (!value || isNaN(value))
- return <></>;
- return this.statItem(key, `${value}`);
- }
- private statItemMhz(key: string, value: number): React.JSX.Element {
- if (!value || isNaN(value))
- return <></>;
- return this.statItem(key, `${value}`);
- }
- private stringifyByte(value: number): string {
- if (!value || isNaN(value))
- return "";
- let units = ["Byte", "kB", "MB", "GB", "TB", "PB"];
- let unitIndex = 0;
- while (value > 1024 && unitIndex < units.length) {
- value /= 1024;
- unitIndex++;
- }
- value = Math.round(value*100)/100;
- return `${value}${units[unitIndex]}`;
- }
- private statItemBytes(key: string, value: number): React.JSX.Element {
- if (!value || isNaN(value))
- return <></>;
- return this.statItem(key, this.stringifyByte(value));
- }
- private statItemReadOnly(key: string, value: boolean|undefined): React.JSX.Element {
- if (value === undefined)
- return <></>;
- return this.statItem(key, value ? "Read-Write" : "Read Only");
- }
- private statItemBoolean(key: string, value: boolean|undefined): React.JSX.Element {
- if (value === undefined)
- return <></>;
- return this.statItem(key, value ? "true" : "false");
- }
- private statItemArray(key: string, values: string[]): React.JSX.Element {
- return this.statItem(key, <ul>{values.map((x, idx) => <li key={idx}>{x}</li>)}</ul>);
- }
- private statItemFragArray(key: string, values: React.JSX.Element[]): React.JSX.Element {
- return this.statItem(key, <ul>{values}</ul>);
- }
- private uptime(data: SystemInfo): string {
- let totalTime = data.uptime;
- let timeInSec = Math.floor(totalTime % 60);
- totalTime /= 60;
- let timeInMin = Math.floor(totalTime % 60);
- totalTime /= 60;
- let timeInHours = Math.floor(totalTime % 24);
- totalTime /= 24;
- let timeInDays = Math.floor(totalTime);
- let result = "";
- if (timeInDays)
- result += `${timeInDays}d, `;
- if (result.length || timeInHours)
- result += (`${timeInHours}:`).padStart(3, "0");
- result += (`${timeInMin}`).padStart(2, "0")+':'+(`${timeInSec}`).padStart(2, "0");
- return result;
- }
- private cpuInfos(cpu: CpuInfo, cpuIndex: number): React.JSX.Element {
- return this.statItem("model", cpu.model, cpuIndex);
- }
- private networkInfo(network: NetworkInfo, netIndex: number): React.JSX.Element {
- return <li key={netIndex}><ul>
- {this.statItem("Interface", network.iface)}
- {this.statItem("Address", network.address)}
- {this.statItem("Netmask", network.netmask)}
- {this.statItem("Family", network.family)}
- {this.statItem("Mac Address", network.mac)}
- </ul></li>;
- }
- private driveInfo(drive: DriveInfo, driveIdx: number): React.JSX.Element {
- return <li key={driveIdx}><ul>
- {this.statItem("name", drive.name)}
- {this.statItem("type", drive.type)}
- {this.statItem("Mount point", drive.mount)}
- {this.statItem("label", drive.label)}
- {this.statItemBytes("Size", drive.size)}
- {this.statItemBytes("Used Size", drive.usedSize)}
- {this.statItemBytes("Remaining Size", drive.size - drive.usedSize)}
- {this.statItemNumber("Used (%)", Math.round(10000 * drive.usedSize / drive.size) / 100)}
- {this.statItem("Physical", drive.physical)}
- {this.statItem("UUID", drive.uuid)}
- {this.statItem("model", drive.model)}
- {this.statItem("serial", drive.serial)}
- {this.statItemBoolean("removable", drive.removable)}
- {this.statItem("protocol", drive.protocol)}
- {this.statItem("device", drive.device)}
- {this.statItemReadOnly("Access", drive.rw)}
- </ul></li>;
- }
- public render(): React.JSX.Element {
- if (this.state.loading)
- return this.layout(<>Loading..</>);
- else if (this.data === undefined)
- return this.layout(<>Error</>);
- const data = this.data!;
- return this.layout(<>
- <ul>
- {this.statItem("Platform", data.platform)}
- {this.statItem("Distribution", data.distribution)}
- {this.statItem("Architecture", data.arch)}
- {this.statItem("OS Version", data.osVersion)}
- {this.statItem("uptime", this.uptime(data))}
- {this.statItem("Architecture", data.arch)}
- {this.statItem("Node Version", data.nodeVersion)}
- </ul>
- <ul>
- {this.statItem("Manufacturer", data.manufacturer)}
- {this.statItem("Model", data.model)}
- {this.statItemMhz("CPU Max Speed", data.cpuMaxSpeed)}
- {this.statItemFragArray("Cpus", data.cpus.map((x, idx) => this.cpuInfos(x, idx)))}
- {this.statItemBytes("Memory", data.memory)}
- {this.statItem("Memory Layout", <ul>{data.memoryLayout.map((x, idx) => <li key={idx}>{this.stringifyByte(x)}</li>)}</ul>)}
- </ul>
- <ul>
- {this.statItemArray("DNS Servers", data.dnsServers)}
- {this.statItemFragArray("Network Interfaces", data.network.map((x, idx) => this.networkInfo(x, idx)))}
- </ul>
- <ul>
- {this.statItemFragArray("Drives", data.drives.map((x, idx) => this.driveInfo(x, idx)))}
- </ul>
- </>);
- }
- public static async renderMultiple(container: HTMLElement): Promise<React.JSX.Element[]> {
- let domNodes = (await DAL.SystemInfo.listHosts()).map(hostname => <SystemInfoComponent key={hostname} setHidden={null} hostname={hostname}/>);
- ReactDom.createRoot(container).render(<>{domNodes}</>);
- return domNodes;
- }
- }
|