Merge branch 'visual-console-refactor' of https://brutus.artica.lan:8081/artica/pandorafms into visual-console-refactor

Former-commit-id: c47efaabdd51775e11d1672ef2f4100b97baa332
This commit is contained in:
Alejandro Gallardo Escobar 2019-04-22 13:15:30 +02:00
commit ebaa3506de
8 changed files with 169 additions and 32 deletions

View File

@ -19,6 +19,13 @@ final class Group extends Item
*/
protected static $useLinkedVisualConsole = true;
/**
* Used to enable validation, extraction and encodeing of the HTML output.
*
* @var boolean
*/
protected static $useHtmlOutput = true;
/**
* Returns a valid representation of the model.
@ -33,9 +40,14 @@ final class Group extends Item
{
$return = parent::decode($data);
$return['type'] = GROUP_ITEM;
$return['imageSrc'] = static::extractImageSrc($data);
$return['groupId'] = static::extractGroupId($data);
$return['statusImageSrc'] = static::extractStatusImageSrc($data);
if (!isset($return['encodedHtml']) === true) {
$return['imageSrc'] = static::extractImageSrc($data);
$return['statusImageSrc'] = static::extractStatusImageSrc($data);
}
global $config;
$return['link'] = $config['homeurl'].'index.php?sec=estado&sec2=operation/agentes/estado_agente&group_id='.$return['groupId'];
return $return;
}
@ -120,6 +132,24 @@ final class Group extends Item
}
/**
* Extract a show Statistics value.
*
* @param array $data Unknown input data structure.
*
* @return integer Valid identifier of a group.
*
* @throws \InvalidArgumentException When a valid group Id can't be found.
*/
private static function extractShowStatistics(array $data): int
{
return static::parseIntOr(
static::issetInArray($data, ['showStatistics', 'show_statistics']),
0
);
}
/**
* Fetch a vc item data structure from the database using a filter.
*
@ -146,23 +176,111 @@ final class Group extends Item
include_once $config['homedir'].'/include/functions_visual_map.php';
include_once $config['homedir'].'/include/functions_ui.php';
// Get the status img src.
$groupId = static::extractGroupId($data);
$status = \groups_get_status($groupId);
$imagePath = \visual_map_get_image_status_element($data, $status);
$data['statusImageSrc'] = \ui_get_full_url(
$imagePath,
false,
false,
false
);
$showStatistics = static::extractShowStatistics($data);
// If the width or the height are equal to 0 we will extract them
// from the real image size.
if ((int) $data['width'] === 0 || (int) $data['height'] === 0) {
$sizeImage = getimagesize($imagePath);
$data['width'] = $sizeImage[0];
$data['height'] = $sizeImage[1];
if ($showStatistics) {
$agents_critical = \agents_get_agents(
[
'disabled' => 0,
'id_grupo' => $groupId,
'status' => AGENT_STATUS_CRITICAL,
],
['COUNT(*) as total'],
'AR',
false
);
$agents_warning = \agents_get_agents(
[
'disabled' => 0,
'id_grupo' => $groupId,
'status' => AGENT_STATUS_WARNING,
],
['COUNT(*) as total'],
'AR',
false
);
$agents_unknown = \agents_get_agents(
[
'disabled' => 0,
'id_grupo' => $groupId,
'status' => AGENT_STATUS_UNKNOWN,
],
['COUNT(*) as total'],
'AR',
false
);
$agents_ok = \agents_get_agents(
[
'disabled' => 0,
'id_grupo' => $groupId,
'status' => AGENT_STATUS_OK,
],
['COUNT(*) as total'],
'AR',
false
);
$total_agents = ($agents_critical[0]['total'] + $agents_warning[0]['total'] + $agents_unknown[0]['total'] + $agents_ok[0]['total']);
$stat_agent_ok = ($agents_ok[0]['total'] / $total_agents * 100);
$stat_agent_wa = ($agents_warning[0]['total'] / $total_agents * 100);
$stat_agent_cr = ($agents_critical[0]['total'] / $total_agents * 100);
$stat_agent_un = ($agents_unknown[0]['total'] / $total_agents * 100);
if ($width == 0 || $height == 0) {
$dyn_width = 520;
$dyn_height = 80;
} else {
$dyn_width = $width;
$dyn_height = $height;
}
// Print statistics table.
$html = '<table cellpadding="0" cellspacing="0" border="0" class="databox" style="width:'.$dyn_width.'px;height:'.$dyn_height.'px;text-align:center;';
if ($data['label_position'] === 'left') {
$html .= 'float:right;';
} else if ($data['label_position'] === 'right') {
$html .= 'float:left;';
}
$html .= '">';
$html .= '<tr style="height:10%;">';
$html .= '<th style="text-align:center;background-color:#9d9ea0;color:black;font-weight:bold;">'.\groups_get_name($layoutData['id_group'], true).'</th>';
$html .= '</tr>';
$html .= '<tr style="background-color:whitesmoke;height:90%;">';
$html .= '<td>';
$html .= '<div style="margin-left:2%;color: #FFF;font-size: 12px;display:inline;background-color:#FC4444;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">'.remove_right_zeros(number_format($stat_agent_cr, 2)).'%</div>';
$html .= '<div style="background-color:white;color: black ;font-size: 12px;display:inline;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">Critical</div>';
$html .= '<div style="margin-left:2%;color: #FFF;font-size: 12px;display:inline;background-color:#f8db3f;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">'.remove_right_zeros(number_format($stat_agent_wa, 2)).'%</div>';
$html .= '<div style="background-color:white;color: black ;font-size: 12px;display:inline;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">Warning</div>';
$html .= '<div style="margin-left:2%;color: #FFF;font-size: 12px;display:inline;background-color:#84b83c;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">'.remove_right_zeros(number_format($stat_agent_ok, 2)).'%</div>';
$html .= '<div style="background-color:white;color: black ;font-size: 12px;display:inline;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">Normal</div>';
$html .= '<div style="margin-left:2%;color: #FFF;font-size: 12px;display:inline;background-color:#9d9ea0;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">'.remove_right_zeros(number_format($stat_agent_un, 2)).'%</div>';
$html .= '<div style="background-color:white;color: black ;font-size: 12px;display:inline;position:relative;height:80%;width:9.4%;height:80%;border-radius:2px;text-align:center;padding:5px;">Unknown</div>';
$html .= '</td>';
$html .= '</tr>';
$html .= '</table>';
$data['html'] = $html;
} else {
// Get the status img src.
$status = \groups_get_status($groupId);
$imagePath = \visual_map_get_image_status_element($data, $status);
$data['statusImageSrc'] = \ui_get_full_url(
$imagePath,
false,
false,
false
);
// If the width or the height are equal to 0 we will extract them
// from the real image size.
if ((int) $data['width'] === 0 || (int) $data['height'] === 0) {
$sizeImage = getimagesize($imagePath);
$data['width'] = $sizeImage[0];
$data['height'] = $sizeImage[1];
}
static::$useHtmlOutput = false;
}
return $data;

View File

@ -82,4 +82,4 @@
animation: rotate-second 60s infinite linear;
}
/*# sourceMappingURL=vc.main.959e6e64.css.map*/
/*# sourceMappingURL=vc.main.65e9c886.css.map*/

View File

@ -1 +1 @@
{"version":3,"sources":["webpack:///main.css","webpack:///styles.css"],"names":[],"mappings":"AAAA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,4BAA4B;EAC5B,wBAAwB;AAC1B;;AAEA;EACE,kBAAkB;EAClB,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,2BAAuB;EAAvB,8BAAuB;MAAvB,2BAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;AACrB;;ACbA;EACE,wBAAwB;EACxB,kCAA2B;AAC7B;;AAEA,kBAAkB;;AAElB;EACE,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;EACtB,wBAAuB;MAAvB,qBAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,0BAAqB;MAArB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;AACrB;;AAEA;EACE,6DAA6D;EAC7D,eAAe;;EAEf,0BAA0B;EAC1B,mCAAmC;EACnC,kCAAkC;EAClC,kCAAkC;EAClC,wCAAwC;AAC1C;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,eAAe;AACjB;;AAEA,iBAAiB;;AAEjB;EACE,qDAA6C;UAA7C,6CAA6C;AAC/C;;AAEA;EACE,sDAA8C;UAA9C,8CAA8C;AAChD;;AAEA;EACE,oDAA4C;UAA5C,4CAA4C;AAC9C","file":"vc.main.959e6e64.css","sourcesContent":["#visual-console-container {\n margin: 0px auto;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.visual-console-item {\n position: absolute;\n display: flex;\n flex-direction: initial;\n justify-items: center;\n align-items: center;\n}\n","@font-face {\n font-family: Alarm Clock;\n src: url(./alarm-clock.ttf);\n}\n\n/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: flex;\n flex-direction: column;\n justify-content: center;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n font-family: \"Alarm Clock\", \"Courier New\", Courier, monospace;\n font-size: 50px;\n\n /* To improve legibility */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n"],"sourceRoot":""}
{"version":3,"sources":["webpack:///main.css","webpack:///styles.css"],"names":[],"mappings":"AAAA;EACE,gBAAgB;EAChB,kBAAkB;EAClB,4BAA4B;EAC5B,wBAAwB;AAC1B;;AAEA;EACE,kBAAkB;EAClB,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,2BAAuB;EAAvB,8BAAuB;MAAvB,2BAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;AACrB;;ACbA;EACE,wBAAwB;EACxB,kCAA2B;AAC7B;;AAEA,kBAAkB;;AAElB;EACE,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;EACtB,wBAAuB;MAAvB,qBAAuB;UAAvB,uBAAuB;EACvB,qBAAqB;EACrB,0BAAqB;MAArB,qBAAqB;EACrB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;AACrB;;AAEA;EACE,6DAA6D;EAC7D,eAAe;;EAEf,0BAA0B;EAC1B,mCAAmC;EACnC,kCAAkC;EAClC,kCAAkC;EAClC,wCAAwC;AAC1C;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,eAAe;AACjB;;AAEA,iBAAiB;;AAEjB;EACE,qDAA6C;UAA7C,6CAA6C;AAC/C;;AAEA;EACE,sDAA8C;UAA9C,8CAA8C;AAChD;;AAEA;EACE,oDAA4C;UAA5C,4CAA4C;AAC9C","file":"vc.main.65e9c886.css","sourcesContent":["#visual-console-container {\n margin: 0px auto;\n position: relative;\n background-repeat: no-repeat;\n background-size: contain;\n}\n\n.visual-console-item {\n position: absolute;\n display: flex;\n flex-direction: initial;\n justify-items: center;\n align-items: center;\n}\n","@font-face {\n font-family: Alarm Clock;\n src: url(./alarm-clock.ttf);\n}\n\n/* Digital clock */\n\n.visual-console-item .digital-clock {\n display: flex;\n flex-direction: column;\n justify-content: center;\n justify-items: center;\n align-content: center;\n align-items: center;\n}\n\n.visual-console-item .digital-clock > span {\n font-family: \"Alarm Clock\", \"Courier New\", Courier, monospace;\n font-size: 50px;\n\n /* To improve legibility */\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n text-rendering: optimizeLegibility;\n text-shadow: rgba(0, 0, 0, 0.01) 0 0 1px;\n}\n\n.visual-console-item .digital-clock > span.date {\n font-size: 25px;\n}\n\n.visual-console-item .digital-clock > span.timezone {\n font-size: 25px;\n}\n\n/* Analog clock */\n\n.visual-console-item .analogic-clock .hour-hand {\n animation: rotate-hour 43200s infinite linear;\n}\n\n.visual-console-item .analogic-clock .minute-hand {\n animation: rotate-minute 3600s infinite linear;\n}\n\n.visual-console-item .analogic-clock .second-hand {\n animation: rotate-second 60s infinite linear;\n}\n"],"sourceRoot":""}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,18 @@
import { LinkedVisualConsoleProps, UnknownObject } from "../types";
import { linkedVCPropsDecoder, parseIntOr, notEmptyStringOr } from "../lib";
import {
linkedVCPropsDecoder,
parseIntOr,
notEmptyStringOr,
stringIsEmpty,
decodeBase64
} from "../lib";
import Item, { ItemProps, itemBasePropsDecoder, ItemType } from "../Item";
export type GroupProps = {
type: ItemType.GROUP_ITEM;
imageSrc: string; // URL?
imageSrc: string | null; // URL?
groupId: number;
html: string | null;
statusImageSrc: string | null;
} & ItemProps &
LinkedVisualConsoleProps;
@ -20,7 +27,10 @@ export type GroupProps = {
* is missing from the raw object or have an invalid type.
*/
export function groupPropsDecoder(data: UnknownObject): GroupProps | never {
if (typeof data.imageSrc !== "string" || data.imageSrc.length === 0) {
if (
(typeof data.imageSrc !== "string" || data.imageSrc.length === 0) &&
data.encodedHtml === null
) {
throw new TypeError("invalid image src.");
}
if (parseIntOr(data.groupId, null) === null) {
@ -30,8 +40,11 @@ export function groupPropsDecoder(data: UnknownObject): GroupProps | never {
return {
...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
type: ItemType.GROUP_ITEM,
imageSrc: data.imageSrc,
imageSrc: notEmptyStringOr(data.imageSrc, null),
groupId: parseInt(data.groupId),
html: !stringIsEmpty(data.encodedHtml)
? decodeBase64(data.encodedHtml)
: null,
statusImageSrc: notEmptyStringOr(data.statusImageSrc, null),
...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.
};
@ -39,12 +52,18 @@ export function groupPropsDecoder(data: UnknownObject): GroupProps | never {
export default class Group extends Item<GroupProps> {
protected createDomElement(): HTMLElement {
const img: HTMLImageElement = document.createElement("img");
img.className = "group";
if (this.props.statusImageSrc != null) {
img.src = this.props.statusImageSrc;
}
if (this.props.html !== null) {
const div = document.createElement("div");
div.innerHTML = this.props.html;
return div;
} else {
const img: HTMLImageElement = document.createElement("img");
img.className = "group";
if (this.props.statusImageSrc != null) {
img.src = this.props.statusImageSrc;
}
return img;
return img;
}
}
}