nope/resources/admin-shell/host/HostStatus.tsx
Martin Karkowski dbcba34c3b Arbeitsstand
2021-04-14 11:58:41 +02:00

343 lines
9.4 KiB
TypeScript

/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2021-02-09 10:41:42
* @modify date 2021-02-09 10:41:42
* @desc [description]
*/
import React from "react";
import { Alert, Badge, Card, ListGroup, Table } from "react-bootstrap";
import { nopeDispatcherManager } from "../../../lib/dispatcher/nopeDispatcherManager";
import { ENopeDispatcherStatus } from "../../../lib/types/nope/nopeDispatcher.interface";
import { INopeObserver } from "../../../lib/types/nope/nopeObservable.interface";
import { MemoryStatusOfHostComponent } from "./MemoryStatus";
type ValidColors = "danger" | "warning" | "info" | "success";
type RenderingHostInfo = {
info?: {
cpu: string;
cores: number;
os: string;
ram: number;
name: string;
disptachers: {
pid: string;
id: string;
variant: ValidColors;
badgeText: string;
}[];
instances: {
identifier: string;
status: ENopeDispatcherStatus;
dispatcher: string;
variant: ValidColors;
badgeText: string;
}[];
lastUpdate: string;
variant: ValidColors;
badgeText: string;
showBadge: boolean;
processes: number;
};
hostAvaiable: boolean;
showDetails: boolean;
};
/**
* A Component, used to Render the Staus of a Host.
*
*/
export class HostStatusComponent extends React.Component<
{
host: string;
ids: { [index: string]: string };
dispatcher: nopeDispatcherManager;
renderDetails?: boolean;
},
RenderingHostInfo
> {
protected _init = true;
protected _getId(id: string): string {
return this.props.ids[id];
}
/**
* List containing Observables
*
* @private
* @type {INopeObserver[]}
*/
private _observer: INopeObserver[] = [];
/**
* Function will be called if the Item will be rendered in the browser.
*/
componentDidMount(): void {
const _this = this;
this._observer.push(
this.props.dispatcher.externalDispatchers.subscribe(() => {
_this.setState(_this._getRenderingObject());
})
);
}
/**
* Function, that will be called before the network fails.
*/
public componentWillUnmount(): void {
// Call the unmount
for (const _observer of this._observer) {
_observer.unsubscribe();
}
}
componentDidUpdate(prevProps: { host: string }): void {
if (prevProps.host !== this.props.host) {
this.setState(this._getRenderingObject());
}
}
protected _getRenderingObject(): RenderingHostInfo {
const info = this.props.dispatcher.getHostInfos()[this.props.host];
if (info === undefined) {
return {
hostAvaiable: false,
showDetails: this._init
? this.props.renderDetails
: this.state.showDetails
};
}
const dict: { [index: number]: ValidColors } = {
0: "success",
1: "info",
2: "warning",
3: "danger"
};
const _this = this;
const ret: RenderingHostInfo = {
info: {
lastUpdate: new Date(info.timestamp).toISOString(),
variant: dict[info.status],
showBadge: info.status !== ENopeDispatcherStatus.HEALTHY,
badgeText: ENopeDispatcherStatus[info.status],
cores: info.cores,
cpu: info.cpu,
disptachers: info.disptachers.map((item) =>
Object.assign(
{
variant: dict[item.status],
badgeText: ENopeDispatcherStatus[item.status]
},
item,
{
id: _this._getId(item.id),
pid: item.id == item.pid ? "browser" : item.pid.toString()
}
)
),
instances: info.instances.map((item) =>
Object.assign(
{
variant: dict[item.status],
badgeText: ENopeDispatcherStatus[item.status]
},
item,
{
dispatcher: _this._getId(item.dispatcher)
}
)
),
name: info.name,
os: info.os,
ram: info.ram,
processes: 0
},
hostAvaiable: true,
showDetails: this._init
? this.props.renderDetails
: this.state.showDetails
};
this._init = false;
const pids = new Set();
for (const dispatcher of info.disptachers) {
pids.add(dispatcher.pid);
}
ret.info.processes = pids.size;
return ret;
}
/**
* Create the Status to Render.
* @param props
*/
constructor(props) {
super(props);
this.state = this._getRenderingObject();
}
render(): JSX.Element {
if (this.state.hostAvaiable) {
const cardContent = (
<Card.Body>
<Card.Title>
{" "}
{this.state.info.showBadge ? (
<>
{this.props.host}{" "}
<Badge variant={this.state.info.variant}>
CONTAINS {this.state.info.badgeText} DISPATCHER!
</Badge>{" "}
</>
) : (
<>{this.props.host}</>
)}{" "}
</Card.Title>
<Table striped bordered hover>
<tbody>
{this.state.info.ram > 0 ? (
<tr>
<td>RAM</td>
<td>
{" "}
{/* Rendert the Memory */}
<MemoryStatusOfHostComponent
value={this.state.info.ram}
></MemoryStatusOfHostComponent>
</td>
</tr>
) : (
<></>
)}
<tr>
<td>CPU</td>
<td>{this.state.info.cpu}</td>
</tr>
<tr>
<td>Cores</td>
<td>{this.state.info.cores}</td>
</tr>
<tr>
<td>Platform</td>
<td>{this.state.info.os}</td>
</tr>
<tr>
<td>NoPE-Processes</td>
<td>{this.state.info.processes}</td>
</tr>
<tr>
<td>Dispatchers</td>
{this.state.showDetails ? (
<Table striped bordered hover>
<thead>
<tr>
<th>ID</th>
<th>PID</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{this.state.info.disptachers.map((item, key_01) => {
return (
<tr key={key_01}>
<td>{item.id}</td>
<td>{item.pid}</td>
<td>
<Badge variant={item.variant}>
{item.badgeText}
</Badge>
</td>
</tr>
);
})}
</tbody>
</Table>
) : (
<td>{this.state.info.disptachers.length}</td>
)}
</tr>
<tr>
<td>Instances</td>
{this.state.info.instances.length > 0 ? (
<td>
{this.state.showDetails ? (
<Table striped bordered hover>
<thead>
<tr>
<th>Name</th>
<th>Dispatcher</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{this.state.info.instances.map((item, key_01) => {
return (
<tr key={key_01}>
<td>{item.identifier}</td>
<td>{item.dispatcher}</td>
<td>
<Badge variant={item.variant}>
{item.badgeText}
</Badge>
</td>
</tr>
);
})}
</tbody>
</Table>
) : (
<ListGroup>
{this.state.info.instances.map((item, key_01) => (
// Render the Item in a List.
<ListGroup.Item key={key_01}>
{item.identifier}
</ListGroup.Item>
))}
</ListGroup>
)}
</td>
) : (
<td>
<code>None</code>
</td>
)}
</tr>
</tbody>
</Table>
</Card.Body>
);
const cardFooter = (
<Card.Footer>
<small className="text-muted">
Last updated <b>{this.state.info.lastUpdate}</b>
</small>
</Card.Footer>
);
return (
<Card border={this.state.info.variant}>
{cardContent}
{cardFooter}
</Card>
);
} else {
return (
<Card>
<Alert variant={"danger"}>
Host <code>{this.props.host}</code> not available <b>:'(</b>
</Alert>
</Card>
);
}
}
}