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; 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. * Returns a valid representation of the model.
@ -33,9 +40,14 @@ final class Group extends Item
{ {
$return = parent::decode($data); $return = parent::decode($data);
$return['type'] = GROUP_ITEM; $return['type'] = GROUP_ITEM;
$return['imageSrc'] = static::extractImageSrc($data);
$return['groupId'] = static::extractGroupId($data); $return['groupId'] = static::extractGroupId($data);
if (!isset($return['encodedHtml']) === true) {
$return['imageSrc'] = static::extractImageSrc($data);
$return['statusImageSrc'] = static::extractStatusImageSrc($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; 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. * Fetch a vc item data structure from the database using a filter.
* *
@ -146,8 +176,93 @@ final class Group extends Item
include_once $config['homedir'].'/include/functions_visual_map.php'; include_once $config['homedir'].'/include/functions_visual_map.php';
include_once $config['homedir'].'/include/functions_ui.php'; include_once $config['homedir'].'/include/functions_ui.php';
// Get the status img src.
$groupId = static::extractGroupId($data); $groupId = static::extractGroupId($data);
$showStatistics = static::extractShowStatistics($data);
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); $status = \groups_get_status($groupId);
$imagePath = \visual_map_get_image_status_element($data, $status); $imagePath = \visual_map_get_image_status_element($data, $status);
$data['statusImageSrc'] = \ui_get_full_url( $data['statusImageSrc'] = \ui_get_full_url(
@ -165,6 +280,9 @@ final class Group extends Item
$data['height'] = $sizeImage[1]; $data['height'] = $sizeImage[1];
} }
static::$useHtmlOutput = false;
}
return $data; return $data;
} }

View File

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