259 lines
6.1 KiB
TypeScript
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;
|