nope/resources/admin-shell/dispatchers.tsx
2020-12-04 19:10:33 +01:00

259 lines
6.1 KiB
TypeScript

/**
* @author Martin Karkowski
* @email m.karkowski@zema.de
* @create date 2020-12-03 11:57:29
* @modify date 2020-12-03 11:57:29
* @desc [description]
*/
import React from "react";
import { Card, Col, ProgressBar, Row, Table } from "react-bootstrap";
import {
IDispatcherInfo,
INopeDispatcher
} from "../../lib/types/nope/nopeDispatcher.interface";
import { INopeObserver } from "../../lib/types/nope/nopeObservable.interface";
/**
* Component used to render the Status of the Memory of a Host.
*/
class MemoryStatusComponent extends React.Component<
{
value: number;
},
{}
> {
render() {
// Determine the Now Value.
const now = Math.round(1000 - this.props.value * 1000) / 10;
const colorRange = {
"0": "success",
"30": "success",
"75": "warning",
"90": "danger",
"101": "danger"
};
// Determine the Color, Therefore filter the "keys" based on the now Value.
const color =
colorRange[
Object.getOwnPropertyNames(colorRange).filter(
(value) => now < parseFloat(value)
)[0]
];
// Render
return (
<>
<ProgressBar now={now} label={`${now} %`} variant={color} />
</>
);
}
}
class HostStatusComponent extends React.Component<
{
status: {
cores: number;
cpu: string;
os: string;
ram: number;
name: string;
pids: { pid: number; dispatchers: string[] }[];
};
},
{}
> {
render() {
return (
<Card>
<Card.Body>
<Card.Title>{this.props.status.name}</Card.Title>
<Table bordered>
<tbody>
<tr>
<td>RAM</td>
<td>
{" "}
{/* Rendert the Memory */}
<MemoryStatusComponent
value={this.props.status.ram}
></MemoryStatusComponent>
</td>
</tr>
<tr>
<td>CPU</td>
<td>{this.props.status.cpu}</td>
</tr>
<tr>
<td>Cores</td>
<td>{this.props.status.cores}</td>
</tr>
<tr>
<td>Nope-Processes</td>
<td>{this.props.status.pids.length}</td>
</tr>
</tbody>
</Table>
</Card.Body>
<Card.Footer>
<small className="text-muted">Last updated 3 mins ago</small>
</Card.Footer>
</Card>
);
}
}
class AvailableDispatchers extends React.Component<
{ dispatcher: INopeDispatcher },
{ dispatchers: IDispatcherInfo[][]; connected: boolean }
> {
private _observer: INopeObserver[] = [];
private __sort() {
const sorted: {
[index: string]: {
cpu: string;
cores: number;
os: string;
ram: number;
name: string;
pids: { [index: string]: string[] };
};
} = {};
const ret: {
cpu: string;
cores: number;
os: string;
ram: number;
name: string;
pids: { pid: number; dispatchers: string[] };
}[] = [];
for (const dispatcher of this.props.dispatcher.externalDispatchers.getContent()) {
if (sorted[dispatcher.host.name] === undefined) {
sorted[dispatcher.host.name] = {
cores: dispatcher.host.cores,
cpu: dispatcher.host.cpu,
name: dispatcher.host.name,
os: dispatcher.host.os,
pids: {},
ram: dispatcher.host.ram
};
}
if (sorted[dispatcher.host.name].pids[dispatcher.pid] === undefined) {
console.log(dispatcher.pid);
sorted[dispatcher.host.name].pids[dispatcher.pid] = [];
}
sorted[dispatcher.host.name].pids[dispatcher.pid].push(dispatcher.id);
}
for (const hostname in sorted) {
const _toAdd: any = sorted[hostname];
_toAdd.pids = Object.getOwnPropertyNames(sorted[hostname].pids).map(
(pid) => {
return {
pid,
dispatchers: sorted[hostname].pids[pid]
};
}
);
ret.push(_toAdd);
}
return ret;
}
private __refresh__() {
const connected = this.props.dispatcher.communicator.connected.getContent();
const dispatchers = [];
const maxItems = 3;
const sorted = [
...this.__sort(),
...this.__sort(),
...this.__sort(),
...this.__sort()
];
// Function to Split the Dispatcher Array into an array containing max 3 elements.
for (let i = 0; i < sorted.length; i = i + maxItems) {
dispatchers.push(sorted.slice(i, i + maxItems));
}
this.setState({
dispatchers: connected ? dispatchers : [],
connected
});
}
/**
* Function will be called if the Item has been rendered sucessfully.
*/
componentDidMount() {
if (this.props.dispatcher) {
// Subscribe to the Instances.
const _this = this;
this._observer.push(
this.props.dispatcher.externalDispatchers.subscribe(() => {
_this.__refresh__();
})
);
this._observer.push(
this.props.dispatcher.communicator.connected.subscribe(() => {
_this.__refresh__();
})
);
// Render the Elements
this.__refresh__();
}
}
/**
* Function, that will be called before the network fails.
*/
componentWillUnmount() {
// Call the unmount
for (const _observer of this._observer) {
_observer.unsubscribe();
}
}
constructor(props) {
super(props);
this.state = {
dispatchers: [],
connected: false
};
}
public render() {
return (
<>
{this.state.dispatchers.map((row, idx_01) => {
return (
<Row
key={idx_01}
style={{ paddingTop: "0.5rem", paddingBottom: "0.5rem" }}
>
{row.map((item, idx_02) => {
return (
<Col key={`${idx_01}_${idx_02}`} sm={4}>
<HostStatusComponent status={item}></HostStatusComponent>
</Col>
);
})}
</Row>
);
})}
</>
);
}
}
export default AvailableDispatchers;