diff --git a/pandora_agents/unix/DEBIAN/control b/pandora_agents/unix/DEBIAN/control index 4ead22711f..6771606f50 100644 --- a/pandora_agents/unix/DEBIAN/control +++ b/pandora_agents/unix/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-agent-unix -Version: 7.0NG.735-190614 +Version: 7.0NG.735-190625 Architecture: all Priority: optional Section: admin diff --git a/pandora_agents/unix/DEBIAN/make_deb_package.sh b/pandora_agents/unix/DEBIAN/make_deb_package.sh index 0a62096fb5..fe7628e999 100644 --- a/pandora_agents/unix/DEBIAN/make_deb_package.sh +++ b/pandora_agents/unix/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190614" +pandora_version="7.0NG.735-190625" echo "Test if you has the tools for to make the packages." whereis dpkg-deb | cut -d":" -f2 | grep dpkg-deb > /dev/null diff --git a/pandora_agents/unix/pandora_agent b/pandora_agents/unix/pandora_agent index 23dc9f3f4c..6bbb463b49 100755 --- a/pandora_agents/unix/pandora_agent +++ b/pandora_agents/unix/pandora_agent @@ -42,7 +42,7 @@ my $Sem = undef; my $ThreadSem = undef; use constant AGENT_VERSION => '7.0NG.735'; -use constant AGENT_BUILD => '190614'; +use constant AGENT_BUILD => '190625'; # Agent log default file size maximum and instances use constant DEFAULT_MAX_LOG_SIZE => 600000; diff --git a/pandora_agents/unix/pandora_agent.redhat.spec b/pandora_agents/unix/pandora_agent.redhat.spec index fcc42de22c..8f580504eb 100644 --- a/pandora_agents/unix/pandora_agent.redhat.spec +++ b/pandora_agents/unix/pandora_agent.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.735 -%define release 190614 +%define release 190625 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent.spec b/pandora_agents/unix/pandora_agent.spec index 14d90f0833..28023a28f3 100644 --- a/pandora_agents/unix/pandora_agent.spec +++ b/pandora_agents/unix/pandora_agent.spec @@ -3,7 +3,7 @@ # %define name pandorafms_agent_unix %define version 7.0NG.735 -%define release 190614 +%define release 190625 Summary: Pandora FMS Linux agent, PERL version Name: %{name} diff --git a/pandora_agents/unix/pandora_agent_installer b/pandora_agents/unix/pandora_agent_installer index cf65cbba4a..879ff79eac 100755 --- a/pandora_agents/unix/pandora_agent_installer +++ b/pandora_agents/unix/pandora_agent_installer @@ -10,7 +10,7 @@ # ********************************************************************** PI_VERSION="7.0NG.735" -PI_BUILD="190614" +PI_BUILD="190625" OS_NAME=`uname -s` FORCE=0 diff --git a/pandora_agents/win32/installer/pandora.mpi b/pandora_agents/win32/installer/pandora.mpi index eaa9573fe6..21e38fb13b 100644 --- a/pandora_agents/win32/installer/pandora.mpi +++ b/pandora_agents/win32/installer/pandora.mpi @@ -186,7 +186,7 @@ UpgradeApplicationID {} Version -{190614} +{190625} ViewReadme {Yes} diff --git a/pandora_agents/win32/pandora.cc b/pandora_agents/win32/pandora.cc index 8724546822..2194b622ac 100644 --- a/pandora_agents/win32/pandora.cc +++ b/pandora_agents/win32/pandora.cc @@ -30,7 +30,7 @@ using namespace Pandora; using namespace Pandora_Strutils; #define PATH_SIZE _MAX_PATH+1 -#define PANDORA_VERSION ("7.0NG.735(Build 190614)") +#define PANDORA_VERSION ("7.0NG.735(Build 190625)") string pandora_path; string pandora_dir; diff --git a/pandora_agents/win32/versioninfo.rc b/pandora_agents/win32/versioninfo.rc index 67a1d6e71d..f328ab299c 100644 --- a/pandora_agents/win32/versioninfo.rc +++ b/pandora_agents/win32/versioninfo.rc @@ -11,7 +11,7 @@ BEGIN VALUE "LegalCopyright", "Artica ST" VALUE "OriginalFilename", "PandoraAgent.exe" VALUE "ProductName", "Pandora FMS Windows Agent" - VALUE "ProductVersion", "(7.0NG.735(Build 190614))" + VALUE "ProductVersion", "(7.0NG.735(Build 190625))" VALUE "FileVersion", "1.0.0.0" END END diff --git a/pandora_console/DEBIAN/control b/pandora_console/DEBIAN/control index c653917fdc..8a166990ab 100644 --- a/pandora_console/DEBIAN/control +++ b/pandora_console/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-console -Version: 7.0NG.735-190614 +Version: 7.0NG.735-190625 Architecture: all Priority: optional Section: admin diff --git a/pandora_console/DEBIAN/make_deb_package.sh b/pandora_console/DEBIAN/make_deb_package.sh index 1f20583f54..2d45e0aa49 100644 --- a/pandora_console/DEBIAN/make_deb_package.sh +++ b/pandora_console/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190614" +pandora_version="7.0NG.735-190625" package_pear=0 package_pandora=1 diff --git a/pandora_console/extensions/agents_modules.php b/pandora_console/extensions/agents_modules.php index b5860068d8..97657f5189 100644 --- a/pandora_console/extensions/agents_modules.php +++ b/pandora_console/extensions/agents_modules.php @@ -1,23 +1,24 @@ '.__('Group').''; $filter_groups = html_print_select_groups(false, 'AR', true, 'group_id', $group_id, '', '', '', true, false, true, '', false, 'width: auto;'); $filter_recursion_label = ''.__('Recursion').''; $filter_recursion = html_print_checkbox('recursion', 1, 0, true); - // groups module + // Groups module. $filter_module_groups_label = ''.__('Module group').''; $filter_module_groups = html_print_select_from_sql( 'SELECT * FROM tmodule_group ORDER BY name', @@ -146,7 +147,7 @@ function mainAgentsModules() 'width: auto;' ); - // agent + // Agent. $agents = agents_get_group_agents($group_id); if ((empty($agents)) || $agents == -1) { $agents = []; @@ -155,7 +156,7 @@ function mainAgentsModules() $filter_agents_label = ''.__('Agents').''; $filter_agents = html_print_select($agents, 'id_agents2[]', $agents_id, '', '', 0, true, true, true, '', false, 'min-width: 180px; max-width: 200px;'); - // type show + // Type show. $selection = [ 0 => __('Show common modules'), 1 => __('Show all modules'), @@ -163,12 +164,12 @@ function mainAgentsModules() $filter_type_show_label = ''.__('Show common modules').''; $filter_type_show = html_print_select($selection, 'selection_agent_module', $selection_a_m, '', '', 0, true, false, true, '', false, 'min-width: 180px;'); - // modules + // Modules. $all_modules = select_modules_for_agent_group($group_id, $agents_id, $selection_a_m, false); $filter_modules_label = ''.__('Module').''; $filter_modules = html_print_select($all_modules, 'module[]', $modules_selected, '', '', 0, true, true, false, '', false, 'min-width: 180px; max-width: 200px;'); - // update + // Update. $filter_update = html_print_submit_button(__('Update item'), 'edit_item', false, 'class="sub upd"', true); $onheader = [ @@ -178,8 +179,11 @@ function mainAgentsModules() 'combo_groups' => $filter_groups, ]; - // Old style table, we need a lot of special formatting,don't use table function - // Prepare old-style table + /* + * Old style table, we need a lot of special formatting,don't use table function. + * Prepare old-style table. + */ + if ($config['pure'] == 0) { // Header. ui_print_page_header( @@ -200,38 +204,51 @@ function mainAgentsModules() $full_modules = urlencode(implode(';', $full_modules_selected)); $full_agents = urlencode(implode(';', $full_agents_id)); - $url = " index.php?sec=view&sec2=extensions/agents_modules&pure=0&offset=$offset + $url = 'index.php?sec=view&sec2=extensions/agents_modules&pure=0&offset=$offset &group_id=$group_id&modulegroup=$modulegroup&refresh=$refr&full_modules_selected=$full_modules - &full_agents_id=$full_agents&selection_agent_module=$selection_a_m"; + &full_agents_id=$full_agents&selection_agent_module=$selection_a_m'; } else { - $url = " index.php?sec=view&sec2=extensions/agents_modules&pure=0&offset=$offset&group_id=$group_id&modulegroup=$modulegroup&refresh=$refr"; + $url = 'index.php?sec=view&sec2=extensions/agents_modules&pure=0&offset=$offset&group_id=$group_id&modulegroup=$modulegroup&refresh=$refr'; } - // Floating menu - Start + // Floating menu - Start. echo '
'; echo ''; echo '
'; - // Floating menu - End + // Floating menu - End. ui_require_jquery_file('countdown'); } if ($config['pure'] != 1) { - echo '
'; - - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo "'; - echo ''; - echo '
'.$filter_groups_label.''.$filter_groups.'   '.$filter_recursion_label.$filter_recursion.''.$filter_module_groups_label.''.$filter_module_groups.'
'.$filter_agents_label.''.$filter_agents.''.$filter_type_show_label.''.$filter_type_show.''.$filter_modules_label.''.$filter_modules.'
".$filter_update.'
'; - echo '
'; + $show_filters = '
'; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= ''; + $show_filters .= "'; + $show_filters .= ''; + $show_filters .= '
'.$filter_groups_label.''.$filter_groups.'   '.$filter_recursion_label.$filter_recursion.''.$filter_module_groups_label.''.$filter_module_groups.'
'.$filter_agents_label.''.$filter_agents.''.$filter_type_show_label.''.$filter_type_show.''.$filter_modules_label.''.$filter_modules.'
".$filter_update.'
'; + $show_filters .= '
'; + ui_toggle($show_filters, __('Filters')); } if ($agents_id[0] != -1) { @@ -291,7 +308,7 @@ function mainAgentsModules() $count = 0; foreach ($agents as $agent) { - // TODO TAGS agents_get_modules + // TODO TAGS agents_get_modules. $module = agents_get_modules( $agent, false, @@ -339,7 +356,7 @@ function mainAgentsModules() } } } else { - // TODO TAGS agents_get_modules + // TODO TAGS agents_get_modules. $all_modules = agents_get_modules( $agents, false, @@ -414,11 +431,11 @@ function mainAgentsModules() if ($hor_offset > 0) { $new_hor_offset = ($hor_offset - $block); - echo ""."".html_print_image( - 'images/arrow_left.png', + echo "".html_print_image( + 'images/arrow_left_green.png', true, ['title' => __('Previous modules')] - ).''.''; + ).''; } $nmodules = 0; @@ -440,11 +457,11 @@ function mainAgentsModules() if (($hor_offset + $block) < $nmodules) { $new_hor_offset = ($hor_offset + $block); - echo ""."".html_print_image( - 'images/arrow.png', + echo "".html_print_image( + 'images/arrow_right_green.png', true, ['title' => __('More modules')] - ).''.''; + ).''; } echo ''; @@ -457,12 +474,12 @@ function mainAgentsModules() $filter_agents['id_grupo'] = $group_id; } - // Prepare pagination - $url = 'index.php?extension_in_menu=estado&sec=extensions&sec2=extensions/agents_modules&save_serialize=1&'.'hor_offset='.$hor_offset.'&selection_a_m='.$selection_a_m; + // Prepare pagination. + $url = 'index.php?extension_in_menu=estado&sec=extensions&sec2=extensions/agents_modules&save_serialize=1&hor_offset='.$hor_offset.'&selection_a_m='.$selection_a_m; ui_pagination($total_pagination, $url); foreach ($agents as $agent) { - // Get stats for this group + // Get stats for this group. $agent_status = agents_get_status($agent['id_agente']); $alias = db_get_row('tagente', 'id_agente', $agent['id_agente']); if (empty($alias['alias'])) { @@ -471,29 +488,29 @@ function mainAgentsModules() switch ($agent_status) { case 4: - // Alert fired status + // Alert fired status. $rowcolor = 'group_view_alrm'; break; case 1: - // Critical status + // Critical status. $rowcolor = 'group_view_crit'; break; case 2: - // Warning status + // Warning status. $rowcolor = 'group_view_warn'; break; case 0: - // Normal status + // Normal status. $rowcolor = 'group_view_ok'; break; case 3: case -1: default: - // Unknown status + // Unknown status. $rowcolor = 'group_view_unk'; break; } @@ -502,7 +519,7 @@ function mainAgentsModules() echo " ".$alias['alias'].''; - // TODO TAGS agents_get_modules + // TODO TAGS agents_get_modules. $agent_modules = agents_get_modules($agent['id_agente'], false, $filter_module_group, true, true); $nmodules = 0; @@ -572,18 +589,23 @@ function mainAgentsModules() echo ''; - echo "
"; + $show_legend = "
"; + $show_legend .= "
+
".__('Orange cell when the module has fired alerts').'
'; + $show_legend .= "
+
".__('Red cell when the module has a critical status').' +
'; + $show_legend .= "
+
".__('Yellow cell when the module has a warning status').'
'; + $show_legend .= "
+
".__('Green cell when the module has a normal status').'
'; + $show_legend .= "
+
".__('Grey cell when the module has an unknown status').'
'; + $show_legend .= "
+
".__("Cell turns blue when the module is in 'not initialize' status").'
'; + $show_legend .= '
'; + ui_toggle($show_legend, __('Legend')); - echo ''; - echo "'; - echo "'; - echo "'; - echo "'; - echo "'; - echo "'; - echo "'; - echo '
".__('Legend').'
".__('Orange cell when the module has fired alerts').'
".__('Red cell when the module has a critical status').'
".__('Yellow cell when the module has a warning status').'
".__('Green cell when the module has a normal status').'
".__('Grey cell when the module has an unknown status').'
".__("Cell turns blue when the module is in 'not initialize' status").'
'; - echo '
'; $pure_var = $config['pure']; if ($pure_var) { $pure_var = 1; @@ -627,16 +649,14 @@ $ignored_params['refresh'] = ''; $.each($('.th_class_module_r'), function (i, elem) { id = $(elem).attr('id').replace('th_module_r_', ''); $("#th_module_r_" + id).height(($("#div_module_r_" + id).width() + 10) + 'px'); - - //$("#div_module_r_" + id).css('margin-top', (max_width - $("#div_module_r_" + id).width()) + 'px'); $("#div_module_r_" + id).css('margin-top', (max_width - 20) + 'px'); $("#div_module_r_" + id).show(); }); - var refr =" . $refr . "; - var pure =" . $pure_var . "; - var href ='" . ui_get_url_refresh ($ignored_params) . "'; - + var refr = ''; + var pure = ''; + var href =' '; + if (pure) { var startCountDown = function (duration, cb) { $('div.vc-countdown').countdown('destroy'); @@ -646,7 +666,7 @@ $ignored_params['refresh'] = ''; $('div.vc-countdown').countdown({ until: t, format: 'MS', - layout: '(%M%nn%M:%S%nn%S Until refresh)', + layout: '(%M%nn%M:%S%nn%S ) ', alwaysExpire: true, onExpiry: function () { $('div.vc-countdown').countdown('destroy'); @@ -655,8 +675,11 @@ $ignored_params['refresh'] = ''; } }); } - - startCountDown(refr, false); + + if(refr>0){ + startCountDown(refr, false); + } + var controls = document.getElementById('vc-controls'); autoHideElement(controls, 1000); diff --git a/pandora_console/extensions/module_groups.php b/pandora_console/extensions/module_groups.php index 9e750be932..d9843f9860 100644 --- a/pandora_console/extensions/module_groups.php +++ b/pandora_console/extensions/module_groups.php @@ -1,17 +1,32 @@ 0, 1, 0)) AS alerts_module_count, - SUM(IF($condition_warning, 1, 0)) AS warning_module_count, - SUM(IF($condition_unknown, 1, 0)) AS unknown_module_count, - SUM(IF($condition_not_init, 1, 0)) AS notInit_module_count, - SUM(IF($condition_critical, 1, 0)) AS critical_module_count, - SUM(IF($condition_normal, 1, 0)) AS normal_module_count, - COUNT(tae.id_agente_modulo) AS total_count, - tmg.id_mg, - tmg.name as n, - tg.id_grupo - FROM ( - SELECT tam.id_agente_modulo, - tam.id_module_group, - ta.id_grupo AS g, - tae.estado, - SUM(IF(tatm.last_fired <> 0, 1, 0)) AS alert_fired - FROM tagente_modulo tam - LEFT JOIN talert_template_modules tatm - ON tatm.id_agent_module = tam.id_agente_modulo - AND tatm.times_fired = 1 - LEFT JOIN tagente_estado tae - ON tae.id_agente_modulo = tam.id_agente_modulo - INNER JOIN tagente ta - ON ta.id_agente = tam.id_agente - WHERE ta.disabled = 0 - AND tam.disabled = 0 - AND tam.delete_pending = 0 - AND ta.id_grupo IN ($ids_group) - GROUP BY tam.id_agente_modulo - UNION ALL - SELECT tam.id_agente_modulo, - tam.id_module_group, - tasg.id_group AS g, - tae.estado, - SUM(IF(tatm.last_fired <> 0, 1, 0)) AS alert_fired - FROM tagente_modulo tam - LEFT JOIN talert_template_modules tatm - ON tatm.id_agent_module = tam.id_agente_modulo - AND tatm.times_fired = 1 - LEFT JOIN tagente_estado tae - ON tae.id_agente_modulo = tam.id_agente_modulo - INNER JOIN tagente ta - ON ta.id_agente = tam.id_agente - INNER JOIN tagent_secondary_group tasg - ON ta.id_agente = tasg.id_agent - WHERE ta.disabled = 0 - AND tam.disabled = 0 - AND tam.delete_pending = 0 - AND tasg.id_group IN ($ids_group) - GROUP BY tam.id_agente_modulo, tasg.id_group - ) AS tae - RIGHT JOIN tgrupo tg - ON tg.id_grupo = tae.g - INNER JOIN ( - SELECT * FROM tmodule_group - UNION ALL - SELECT 0 AS 'id_mg', 'Nothing' AS 'name' - ) AS tmg - ON tae.id_module_group = tmg.id_mg - GROUP BY tae.g, tmg.id_mg"; + $sql = sprintf( + "SELECT SUM(IF(tae.alert_fired <> 0, 1, 0)) AS alerts_module_count, + SUM(IF(%s, 1, 0)) AS warning_module_count, + SUM(IF(%s, 1, 0)) AS unknown_module_count, + SUM(IF(%s, 1, 0)) AS notInit_module_count, + SUM(IF(%s, 1, 0)) AS critical_module_count, + SUM(IF(%s, 1, 0)) AS normal_module_count, + COUNT(tae.id_agente_modulo) AS total_count, + tmg.id_mg, + tmg.name as n, + tg.id_grupo + FROM ( + SELECT tam.id_agente_modulo, + tam.id_module_group, + ta.id_grupo AS g, + tae.estado, + SUM(IF(tatm.last_fired <> 0, 1, 0)) AS alert_fired + FROM tagente_modulo tam + LEFT JOIN talert_template_modules tatm + ON tatm.id_agent_module = tam.id_agente_modulo + AND tatm.times_fired = 1 + LEFT JOIN tagente_estado tae + ON tae.id_agente_modulo = tam.id_agente_modulo + INNER JOIN tagente ta + ON ta.id_agente = tam.id_agente + WHERE ta.disabled = 0 + AND tam.disabled = 0 + AND tam.delete_pending = 0 + AND ta.id_grupo IN (%s) + GROUP BY tam.id_agente_modulo + UNION ALL + SELECT tam.id_agente_modulo, + tam.id_module_group, + tasg.id_group AS g, + tae.estado, + SUM(IF(tatm.last_fired <> 0, 1, 0)) AS alert_fired + FROM tagente_modulo tam + LEFT JOIN talert_template_modules tatm + ON tatm.id_agent_module = tam.id_agente_modulo + AND tatm.times_fired = 1 + LEFT JOIN tagente_estado tae + ON tae.id_agente_modulo = tam.id_agente_modulo + INNER JOIN tagente ta + ON ta.id_agente = tam.id_agente + INNER JOIN tagent_secondary_group tasg + ON ta.id_agente = tasg.id_agent + WHERE ta.disabled = 0 + AND tam.disabled = 0 + AND tam.delete_pending = 0 + AND tasg.id_group IN (%s) + GROUP BY tam.id_agente_modulo, tasg.id_group + ) AS tae + RIGHT JOIN tgrupo tg + ON tg.id_grupo = tae.g + INNER JOIN ( + SELECT * FROM tmodule_group + UNION ALL + SELECT 0 AS 'id_mg', 'Nothing' AS 'name' + ) AS tmg + ON tae.id_module_group = tmg.id_mg + GROUP BY tae.g, tmg.id_mg", + $condition_warning, + $condition_unknown, + $condition_not_init, + $condition_critical, + $condition_normal, + $ids_group, + $ids_group + ); $array_data_prev = db_get_all_rows_sql($sql); @@ -220,9 +253,21 @@ function mainModuleGroups() echo ''; echo ''; + $cell_style = ' + min-width: 60px; + width: 100%; + margin: 0; + overflow:hidden; + text-align: center; + padding: 5px; + padding-bottom:10px; + font-size: 18px; + text-align: center; + '; + if (true) { $table = new StdClass(); - $table->style[0] = 'color: #ffffff; background-color: #373737; font-weight: bolder; padding-right: 10px; min-width: 230px;'; + $table->style[0] = 'color: #ffffff; background-color: #373737; font-weight: bolder; min-width: 230px;'; $table->width = '100%'; $head[0] = __('Groups'); @@ -248,28 +293,28 @@ function mainModuleGroups() $color = '#FFA631'; // Orange when the cell for this model group and agent has at least one alert fired. } else if ($array_data[$key][$k]['critical_module_count'] != 0) { - $color = '#FC4444'; + $color = '#e63c52'; // Red when the cell for this model group and agent has at least one module in critical state and the rest in any state. } else if ($array_data[$key][$k]['warning_module_count'] != 0) { - $color = '#FAD403'; + $color = '#f3b200'; // Yellow when the cell for this model group and agent has at least one in warning state and the rest in green state. } else if ($array_data[$key][$k]['unknown_module_count'] != 0) { $color = '#B2B2B2 '; // Grey when the cell for this model group and agent has at least one module in unknown state and the rest in any state. } else if ($array_data[$key][$k]['normal_module_count'] != 0) { - $color = '#80BA27'; + $color = '#82b92e'; // Green when the cell for this model group and agent has OK state all modules. } else if ($array_data[$key][$k]['notInit_module_count'] != 0) { $color = '#5BB6E5'; // Blue when the cell for this module group and all modules have not init value. } - $data[$i][$j] = "
"; + $data[$i][$j] = "
"; $data[$i][$j] .= ""; $data[$i][$j] .= $array_data[$key][$k]['total_count']; $data[$i][$j] .= '
'; } else { - $data[$i][$j] = "
"; + $data[$i][$j] = "
"; $data[$i][$j] .= 0; $data[$i][$j] .= '
'; } @@ -278,7 +323,7 @@ function mainModuleGroups() } } else { foreach ($value['gm'] as $k => $v) { - $data[$i][$j] = "
"; + $data[$i][$j] = "
"; $data[$i][$j] .= 0; $data[$i][$j] .= '
'; $j++; diff --git a/pandora_console/extensions/realtime_graphs/realtime_graphs.css b/pandora_console/extensions/realtime_graphs/realtime_graphs.css index ab6c94e238..2219c6152a 100644 --- a/pandora_console/extensions/realtime_graphs/realtime_graphs.css +++ b/pandora_console/extensions/realtime_graphs/realtime_graphs.css @@ -11,5 +11,5 @@ #graph_container { width: 800px; - margin: 20px auto !important; + margin: 20px auto; } diff --git a/pandora_console/extras/delete_files/delete_files.txt b/pandora_console/extras/delete_files/delete_files.txt deleted file mode 100644 index 82ce1527aa..0000000000 --- a/pandora_console/extras/delete_files/delete_files.txt +++ /dev/null @@ -1,3 +0,0 @@ -/general/login_identification_wizard.php -/general/login_required.php -/godmode/update_manager/update_manager.messages.php \ No newline at end of file diff --git a/pandora_console/general/footer.php b/pandora_console/general/footer.php index b35123b5d3..dcc894989b 100644 --- a/pandora_console/general/footer.php +++ b/pandora_console/general/footer.php @@ -20,6 +20,8 @@ if (isset($_SERVER['REQUEST_TIME'])) { $time = get_system_time(); } +ui_require_css_file('footer'); + $license_file = 'general/license/pandora_info_'.$config['language'].'.html'; if (! file_exists($config['homedir'].$license_file)) { $license_file = 'general/license/pandora_info_en.html'; @@ -41,9 +43,17 @@ if ($current_package == 0) { $build_package_version = $current_package; } -echo sprintf(__('%s %s - Build %s - MR %s', get_product_name(), $pandora_version, $build_package_version, $config['MR'])); +echo __( + '%s %s - Build %s - MR %s', + get_product_name(), + $pandora_version, + $build_package_version, + $config['MR'] +); +echo '
'; +echo ''.__('Page generated on %s', date('Y-m-d H:i:s')).''; + -echo ' '; if (isset($config['debug'])) { $cache_info = []; diff --git a/pandora_console/general/login_page.php b/pandora_console/general/login_page.php index 86dccfa53a..4fbdf93140 100755 --- a/pandora_console/general/login_page.php +++ b/pandora_console/general/login_page.php @@ -19,8 +19,8 @@ if (isset($config['homedir'])) { ui_require_css_file('login'); -require_once $homedir.'include/functions_ui.php'; -require_once $homedir.'include/functions.php'; +require_once __DIR__.'/../include/functions_ui.php'; +require_once __DIR__.'/../include/functions.php'; require_once __DIR__.'/../include/functions_html.php'; @@ -518,6 +518,7 @@ if ($login_screen == 'error_authconfig' || $login_screen == 'error_emptyconfig' ui_require_css_file('dialog'); ui_require_css_file('jquery-ui.min', 'include/styles/js/'); ui_require_jquery_file('jquery-ui.min'); +ui_require_jquery_file('jquery-ui_custom'); ?> - - - - - - - - -
- - - class = 'databox'; - $table->cellpadding = 4; - $table->cellspacing = 4; - $table->head = []; - $table->data = []; - $table->headstyle[0] = 'text-align:center;'; - $table->width = '100%'; - $table->head[0] = ''.__('%s Overview', get_product_name()).''; - $table->head_colspan[0] = 4; +echo '
'; - // Indicators. - $tdata = []; - $stats = reporting_get_stats_indicators($data, 120, 10, false); - $status = ''; - foreach ($stats as $stat) { - $status .= ''; - } +// +// Overview Table. +// +$table = new stdClass(); +$table->class = 'no-class'; +$table->cellpadding = 4; +$table->cellspacing = 4; +$table->head = []; +$table->data = []; +$table->headstyle[0] = 'text-align:center;'; +$table->width = '100%'; +$table->head_colspan[0] = 4; - $status .= '
'.$stat['title'].''.$stat['graph'].'
'; - $table->data[0][0] = $status; - $table->rowclass[] = ''; +// Indicators. +$tdata = []; +$stats = reporting_get_stats_indicators($data, 120, 10, false); +$status = ''; +foreach ($stats as $stat) { + $status .= ''; +} - $table->data[] = $tdata; +$status .= '
'.$stat['title'].''.$stat['graph'].'
'; +$table->data[0][0] = $status; +$table->rowclass[] = ''; - // Alerts. - $tdata = []; - $tdata[0] = reporting_get_stats_alerts($data); - $table->rowclass[] = ''; - $table->data[] = $tdata; +$table->data[] = $tdata; - // Modules by status. - $tdata = []; - $tdata[0] = reporting_get_stats_modules_status($data, 180, 100); - $table->rowclass[] = ''; - $table->data[] = $tdata; +// Alerts. +$tdata = []; +$tdata[0] = reporting_get_stats_alerts($data); +$table->rowclass[] = ''; +$table->data[] = $tdata; - // Total agents and modules. - $tdata = []; - $tdata[0] = reporting_get_stats_agents_monitors($data); - $table->rowclass[] = ''; - $table->data[] = $tdata; +// Modules by status. +$tdata = []; +$tdata[0] = reporting_get_stats_modules_status($data, 180, 100); +$table->rowclass[] = ''; +$table->data[] = $tdata; - // Users. - if (users_is_admin()) { - $tdata = []; - $tdata[0] = reporting_get_stats_users($data); - $table->rowclass[] = ''; - $table->data[] = $tdata; - } +// Total agents and modules. +$tdata = []; +$tdata[0] = reporting_get_stats_agents_monitors($data); +$table->rowclass[] = ''; +$table->data[] = $tdata; - html_print_table($table); - unset($table); - ?> - - -
- - - rowclass[] = ''; + $table->data[] = $tdata; +} + +ui_toggle( + html_print_table($table, true), + __('%s Overview', get_product_name()), + '', + 'overview', + false +); +unset($table); + +echo '
+ui_toggle( + $activity, + __('Latest activity'), + '', + 'activity', + false, + false, + '', + 'white-box-content padded' +); +// END OF LAST ACTIVIYY. +// Close right panel. +echo '
'; + +// Close welcome panel. +echo '
'; diff --git a/pandora_console/general/main_menu.php b/pandora_console/general/main_menu.php index 877f171090..ca6c0fd473 100644 --- a/pandora_console/general/main_menu.php +++ b/pandora_console/general/main_menu.php @@ -30,12 +30,6 @@ $(document).ready(function(){ } }); - -// Set the height of the menu. -$(window).on('load', function (){ - $("#menu_full").height($("#container").height()); -}); - data[1] = $data; $form = '
'; $form .= html_print_table($table, true); $form .= '
'; -ui_toggle($form, __('Filter'), '', false); +ui_toggle($form, __('Filter'), '', '', false); $filter = '1=1'; diff --git a/pandora_console/godmode/agentes/agent_manager.php b/pandora_console/godmode/agentes/agent_manager.php index dfdd7390c3..7c6a3ab03b 100644 --- a/pandora_console/godmode/agentes/agent_manager.php +++ b/pandora_console/godmode/agentes/agent_manager.php @@ -176,7 +176,7 @@ if ($disk_conf_delete) { @unlink($filename['conf']); } -echo '
'; +echo ''; // Custom ID. $custom_id_div = '
'; @@ -245,7 +245,7 @@ if (!$new_agent && $alias != '') { $table_agent_name .= '
'; // QR code div. - $table_qr_code = '
'; + $table_qr_code = '
'; $table_qr_code .= '

'.__('QR Code Agent view').':

'; $table_qr_code .= '
'; if ($id_agente) { @@ -401,7 +401,7 @@ $table_description .= html_print_textarea( // QR code. echo '
-
+
'.$table_agent_name.$table_alias.$table_ip.$table_primary_group.'
'.$table_interval.$table_os.$table_server.$table_description.'
'; @@ -413,8 +413,8 @@ echo '
'; if (enterprise_installed()) { $secondary_groups_selected = enterprise_hook('agents_get_secondary_groups', [$id_agente]); - $table_adv_secondary_groups = '

'.__('Secondary groups').':

'; - $table_adv_secondary_groups_left = html_print_select_groups( + $adv_secondary_groups_label = '

'.__('Secondary groups').':

'; + $adv_secondary_groups_left = html_print_select_groups( false, // Use the current user to select the groups. 'AR', @@ -441,7 +441,7 @@ if (enterprise_installed()) { // CSS classnames (default). false, // Not disabled (default). - 'width:50%; min-width:170px;', + 'min-width:170px;', // Inline styles (default). false, // Option style select (default). @@ -455,7 +455,7 @@ if (enterprise_installed()) { // Do not show the primary group in this selection. ); - $table_adv_secondary_groups_arrows = html_print_input_image( + $adv_secondary_groups_arrows = html_print_input_image( 'add_secondary', 'images/darrowright_green.png', 1, @@ -479,7 +479,7 @@ if (enterprise_installed()) { ] ); - $table_adv_secondary_groups_right .= html_print_select( + $adv_secondary_groups_right .= html_print_select( $secondary_groups_selected['for_select'], // Values. 'secondary_groups_selected', @@ -502,7 +502,7 @@ if (enterprise_installed()) { // Class. false, // Disabled. - 'width:50%; min-width:170px;' + 'min-width:170px;' // Style. ); @@ -579,7 +579,7 @@ if (enterprise_installed()) { } -$table_adv_parent = '

'.__('Parent').':

'; +$table_adv_parent = '
'; $params = []; $params['return'] = true; $params['show_helptip'] = true; @@ -648,13 +648,15 @@ $table_adv_module_mode .= html_print_radio_button_extended( $table_adv_module_mode .= '
'; // Status (Disabled / Enabled). -$table_adv_status = '

'.__('Disabled').': '.ui_print_help_tip(__('If the remote configuration is enabled, it will also go into standby mode when disabling it.'), true).'

'; +$table_adv_status = '
'; $table_adv_status .= html_print_checkbox_switch( 'disabled', 1, $disabled, true -).'
'; +); +$table_adv_status .= '

'.__('Disabled').': '.ui_print_help_tip(__('If the remote configuration is enabled, it will also go into standby mode when disabling it.'), true).'

'; +$table_adv_status .= '
'; // Url address. if (enterprise_installed()) { @@ -665,7 +667,14 @@ if (enterprise_installed()) { '', 45, 255, - true + true, + false, + false, + '', + '', + '', + // Autocomplete. + 'new-password' ).'
'; } else { $table_adv_url = '

'.__('Url address').':

'; @@ -679,9 +688,11 @@ if (enterprise_installed()) { ).'
'; } -$table_adv_quiet = '

'.__('Quiet').': '; +$table_adv_quiet = '

'; +$table_adv_quiet .= html_print_checkbox_switch('quiet', 1, $quiet, true); +$table_adv_quiet .= '

'.__('Quiet').': '; $table_adv_quiet .= ui_print_help_tip(__('The agent still runs but the alerts and events will be stop'), true).'

'; -$table_adv_quiet .= html_print_checkbox_switch('quiet', 1, $quiet, true).'
'; +$table_adv_quiet .= '
'; $listIcons = gis_get_array_list_icons(); @@ -753,31 +764,46 @@ if ($config['activate_gis']) { // General display distribution. -$table_adv_options = $table_adv_secondary_groups.'
-
- '.$table_adv_secondary_groups_left.' +$table_adv_options = ' +
+ '.$adv_secondary_groups_label.' +
+ '.$adv_secondary_groups_left.' +
+
+ '.$adv_secondary_groups_arrows.' +
+
+ '.$adv_secondary_groups_right.' +
-
- '.$table_adv_secondary_groups_arrows.' -
-
- '.$table_adv_secondary_groups_right.' -
-
-
-
'.$table_adv_parent.$table_adv_module_mode.$table_adv_cascade; +
+ '.$table_adv_parent.$table_adv_module_mode.$table_adv_cascade; if ($new_agent) { // If agent is new, show custom id as old style format. $table_adv_options .= $custom_id_div; } -$table_adv_options .= $table_adv_gis.'
-
'.$table_adv_agent_icon.$table_adv_url.$table_adv_quiet.$table_adv_status.$table_adv_remote.$table_adv_safe.'
-
'; +$table_adv_options .= '
'; + +$table_adv_options .= ' +
+ '.$table_adv_gis.$table_adv_agent_icon.$table_adv_url.$table_adv_quiet.$table_adv_status.$table_adv_remote.$table_adv_safe.' +
'; + echo '
'; - ui_toggle($table_adv_options, __('Advanced options'), '', true, false, 'white_box white_box_opened'); +ui_toggle( + $table_adv_options, + __('Advanced options'), + '', + '', + true, + false, + 'white_box white_box_opened', + 'no-border flex' +); echo '
'; @@ -831,7 +857,7 @@ foreach ($fields as $field) { $custom_value = ''; } - $table->rowstyle[$i] = 'cursor: pointer;'; + $table->rowstyle[$i] = 'cursor: pointer;user-select: none;'; if (!empty($custom_value)) { $table->rowstyle[($i + 1)] = 'display: table-row;'; } else { @@ -895,14 +921,16 @@ foreach ($fields as $field) { if (!empty($fields)) { echo '
'; - ui_toggle( - html_print_table($table, true), - __('Custom fields'), - '', - true, - false, - 'white_box white_box_opened' - ); + ui_toggle( + html_print_table($table, true), + __('Custom fields'), + '', + '', + true, + false, + 'white_box white_box_opened', + 'no-border' + ); echo '
'; } diff --git a/pandora_console/godmode/agentes/agent_wizard.snmp_interfaces_explorer.php b/pandora_console/godmode/agentes/agent_wizard.snmp_interfaces_explorer.php index 5730fea501..b08dc62c4f 100644 --- a/pandora_console/godmode/agentes/agent_wizard.snmp_interfaces_explorer.php +++ b/pandora_console/godmode/agentes/agent_wizard.snmp_interfaces_explorer.php @@ -322,7 +322,7 @@ if ($create_modules) { } else if (preg_match('/ifAdminStatus/', $name_array[1])) { $module_type = 2; } else if (preg_match('/ifOperStatus/', $name_array[1])) { - $module_type = 18; + $module_type = 2; } else { $module_type = 4; } @@ -608,11 +608,11 @@ ui_require_jquery_file('bgiframe'); $(document).ready (function () { var inputActive = true; - + $(document).data('text_for_module', $("#none_text").html()); - + $("#id_snmp").change(snmp_changed_by_multiple_snmp); - + $("#snmp_version").change(function () { if (this.value == "3") { $("#snmp3_options").css("display", ""); @@ -621,7 +621,7 @@ $(document).ready (function () { $("#snmp3_options").css("display", "none"); } }); - + $("#walk_form").submit(function() { $("#submit-snmp_walk").disable (); $("#oid_loading").show (); @@ -632,15 +632,15 @@ $(document).ready (function () { function snmp_changed_by_multiple_snmp (event, id_snmp, selected) { var idSNMP = Array(); - + jQuery.each ($("#id_snmp option:selected"), function (i, val) { idSNMP.push($(val).val()); }); $('#module').attr ('disabled', 1); $('#module').empty (); $('#module').append ($('').html ("Loading...").attr ("value", 0)); - - jQuery.post ('ajax.php', + + jQuery.post ('ajax.php', {"page" : "godmode/agentes/agent_manager", "get_modules_json_for_multiple_snmp": 1, "id_snmp[]": idSNMP, @@ -655,7 +655,7 @@ function snmp_changed_by_multiple_snmp (event, id_snmp, selected) { $('#module').fadeIn ('normal'); c++; }); - + if (c == 0) { if (typeof($(document).data('text_for_module')) != 'undefined') { $('#module').append ($('').html ($(document).data('text_for_module')).attr("value", 0).prop('selected', true)); @@ -666,11 +666,11 @@ function snmp_changed_by_multiple_snmp (event, id_snmp, selected) { } else { var anyText = $("#any_text").html(); //Trick for catch the translate text. - + if (anyText == null) { anyText = 'Any'; } - + $('#module').append ($('').html (anyText).attr ("value", 0).prop('selected', true)); } } @@ -684,4 +684,3 @@ function snmp_changed_by_multiple_snmp (event, id_snmp, selected) { /* ]]> */ - diff --git a/pandora_console/godmode/agentes/module_manager_editor.php b/pandora_console/godmode/agentes/module_manager_editor.php index cee4825faa..b340761265 100644 --- a/pandora_console/godmode/agentes/module_manager_editor.php +++ b/pandora_console/godmode/agentes/module_manager_editor.php @@ -583,7 +583,13 @@ echo ''; // TODO: Change to the ui_print_error system echo ''; -html_print_table($table_simple); +ui_toggle( + html_print_table($table_simple, true), + __('Base options'), + '', + '', + false +); ui_toggle( html_print_table($table_advanced, true), diff --git a/pandora_console/godmode/agentes/module_manager_editor_common.php b/pandora_console/godmode/agentes/module_manager_editor_common.php index cb2f071e1c..fbdd620f77 100644 --- a/pandora_console/godmode/agentes/module_manager_editor_common.php +++ b/pandora_console/godmode/agentes/module_manager_editor_common.php @@ -162,7 +162,7 @@ $edit_module = (bool) get_parameter_get('edit_module'); $table_simple = new stdClass(); $table_simple->id = 'simple'; $table_simple->width = '100%'; -$table_simple->class = 'databox'; +$table_simple->class = 'no-class'; $table_simple->data = []; $table_simple->style = []; $table_simple->style[0] = 'font-weight: bold; width: 25%;'; @@ -637,7 +637,7 @@ if ($disabledBecauseInPolicy) { $table_advanced = new stdClass(); $table_advanced->id = 'advanced'; $table_advanced->width = '100%'; -$table_advanced->class = 'databox filters'; +$table_advanced->class = 'no-class'; $table_advanced->data = []; $table_advanced->style = []; $table_advanced->style[0] = $table_advanced->style[3] = $table_advanced->style[5] = 'font-weight: bold;'; @@ -1066,7 +1066,7 @@ if (check_acl($config['id_user'], 0, 'PM')) { $table_macros = new stdClass(); $table_macros->id = 'module_macros'; $table_macros->width = '100%'; -$table_macros->class = 'databox filters'; +$table_macros->class = 'no-class'; $table_macros->data = []; $table_macros->style = []; $table_macros->style[0] = 'font-weight: bold;'; @@ -1107,7 +1107,7 @@ html_print_input_hidden('module_macro_count', $macro_count); $table_new_relations = new stdClass(); $table_new_relations->id = 'module_new_relations'; $table_new_relations->width = '100%'; -$table_new_relations->class = 'databox filters'; +$table_new_relations->class = 'no-class'; $table_new_relations->data = []; $table_new_relations->style = []; $table_new_relations->style[0] = 'width: 10%; font-weight: bold;'; diff --git a/pandora_console/godmode/alerts/alert_list.builder.php b/pandora_console/godmode/alerts/alert_list.builder.php index ca3a099bf3..c97fe2feff 100644 --- a/pandora_console/godmode/alerts/alert_list.builder.php +++ b/pandora_console/godmode/alerts/alert_list.builder.php @@ -37,14 +37,10 @@ $table->head = []; $table->data = []; $table->size = []; $table->size = []; -$table->size[0] = '5%'; -$table->size[1] = '25%'; -$table->size[2] = '5%'; -$table->size[3] = '20%'; -$table->style[0] = 'font-weight: bold; '; -$table->style[1] = 'font-weight: bold; '; -$table->style[2] = 'font-weight: bold; '; -$table->style[3] = 'font-weight: bold; '; +$table->style[0] = 'font-weight: bold;'; +$table->style[1] = 'font-weight: bold;display: flex;align-items: baseline;'; +$table->style[2] = 'font-weight: bold;'; +$table->style[3] = 'font-weight: bold;'; // This is because if this view is reused after list alert view then // styles in the previous view can affect this table. @@ -89,7 +85,7 @@ $table->data[0][1] = html_print_select( true, '', ($id_agente == 0), - 'width: 250px;' + 'min-width: 250px;margin-right: 0.5em;' ); $table->data[0][1] .= ' '; @@ -117,7 +113,7 @@ $table->data[1][1] = html_print_select( true, '', false, - 'width: 250px;' + 'min-width: 250px;' ); $table->data[1][1] .= ''; if (check_acl($config['id_user'], 0, 'LM')) { - $table->data[1][1] .= ''; + $table->data[1][1] .= ''; $table->data[1][1] .= html_print_image('images/add.png', true); - $table->data[1][1] .= ''.__('Create Action').''; + $table->data[1][1] .= ''.__('Create Action').''; $table->data[1][1] .= ''; } @@ -162,13 +158,13 @@ if ($own_info['is_admin'] || check_acl($config['id_user'], 0, 'PM')) { if (check_acl($config['id_user'], 0, 'LM')) { $table->data[2][1] .= ''; $table->data[2][1] .= html_print_image('images/add.png', true); - $table->data[2][1] .= ''.__('Create Template').''; + $table->data[2][1] .= ''.__('Create Template').''; $table->data[2][1] .= ''; } $table->data[3][0] = __('Threshold'); $table->data[3][1] = html_print_input_text('module_action_threshold', '0', '', 5, 7, true); - $table->data[3][1] .= ' '.__('seconds'); + $table->data[3][1] .= ''.__('seconds').''; if (!isset($step)) { echo ''; diff --git a/pandora_console/godmode/alerts/alert_list.list.php b/pandora_console/godmode/alerts/alert_list.list.php index 4b3a3395cf..f830f47dbd 100644 --- a/pandora_console/godmode/alerts/alert_list.list.php +++ b/pandora_console/godmode/alerts/alert_list.list.php @@ -438,11 +438,11 @@ if (! $id_agente) { $table->style = []; $table->style[0] = 'font-weight: bold;'; $table->head[0] = __('Agent').ui_get_sorting_arrows($url_up_agente, $url_down_agente, $selectAgentUp, $selectAgentDown); - $table->size[0] = '4%'; - $table->size[1] = '8%'; - $table->size[2] = '8%'; - $table->size[3] = '4%'; - $table->size[4] = '4%'; + $table->headstyle[0] = 'width: 100%; min-width: 12em;'; + $table->headstyle[1] = 'min-width: 15em;'; + $table->headstyle[2] = 'min-width: 20em;'; + $table->headstyle[3] = 'min-width: 1em;'; + $table->headstyle[4] = 'min-width: 15em;'; /* if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) { @@ -450,16 +450,11 @@ if (! $id_agente) { }*/ } else { $table->head[0] = __('Module').ui_get_sorting_arrows($url_up_module, $url_down_module, $selectModuleUp, $selectModuleDown); - // Different sizes or the layout screws up - $table->size[0] = '0%'; - $table->size[1] = '10%'; - $table->size[2] = '30%'; - /* - if ($isFunctionPolicies !== ENTERPRISE_NOT_HOOK) { - $table->size[4] = '25%'; - } */ - $table->size[3] = '1%'; - $table->size[4] = '1%'; + $table->headstyle[0] = 'width: 100%; min-width: 15em;'; + $table->headstyle[1] = 'min-width: 15em;'; + $table->headstyle[2] = 'min-width: 20em;'; + $table->headstyle[3] = 'min-width: 1em;'; + $table->headstyle[4] = 'min-width: 15em;'; } $table->head[1] = __('Template').ui_get_sorting_arrows($url_up_template, $url_down_template, $selectTemplateUp, $selectTemplateDown); diff --git a/pandora_console/godmode/events/custom_events.php b/pandora_console/godmode/events/custom_events.php index 0bf3b223e2..bfb0e8c64d 100644 --- a/pandora_console/godmode/events/custom_events.php +++ b/pandora_console/godmode/events/custom_events.php @@ -60,96 +60,12 @@ $fields_selected = explode(',', $config['event_fields']); $result_selected = []; -// show list of fields selected. +// Show list of fields selected. if ($fields_selected[0] != '') { foreach ($fields_selected as $field_selected) { - switch ($field_selected) { - case 'id_evento': - $result = __('Event Id'); - break; - - case 'evento': - $result = __('Event Name'); - break; - - case 'id_agente': - $result = __('Agent Name'); - break; - - case 'id_usuario': - $result = __('User'); - break; - - case 'id_grupo': - $result = __('Group'); - break; - - case 'estado': - $result = __('Status'); - break; - - case 'timestamp': - $result = __('Timestamp'); - break; - - case 'event_type': - $result = __('Event Type'); - break; - - case 'id_agentmodule': - $result = __('Module Name'); - break; - - case 'id_alert_am': - $result = __('Alert'); - break; - - case 'criticity': - $result = __('Severity'); - break; - - case 'user_comment': - $result = __('Comment'); - break; - - case 'tags': - $result = __('Tags'); - break; - - case 'source': - $result = __('Source'); - break; - - case 'id_extra': - $result = __('Extra Id'); - break; - - case 'owner_user': - $result = __('Owner'); - break; - - case 'ack_utimestamp': - $result = __('ACK Timestamp'); - break; - - case 'instructions': - $result = __('Instructions'); - break; - - case 'server_name': - $result = __('Server Name'); - break; - - case 'data': - $result = __('Data'); - break; - - case 'module_status': - $result = __('Module Status'); - break; - } - - $result_selected[$field_selected] = $result; + $result_selected[$field_selected] = events_get_column_name( + $field_selected + ); } } @@ -177,7 +93,8 @@ $fields_available = []; $fields_available['id_evento'] = __('Event Id'); $fields_available['evento'] = __('Event Name'); -$fields_available['id_agente'] = __('Agent Name'); +$fields_available['id_agente'] = __('Agent ID'); +$fields_available['agent_name'] = __('Agent Name'); $fields_available['id_usuario'] = __('User'); $fields_available['id_grupo'] = __('Group'); $fields_available['estado'] = __('Status'); @@ -197,12 +114,10 @@ $fields_available['server_name'] = __('Server Name'); $fields_available['data'] = __('Data'); $fields_available['module_status'] = __('Module Status'); -// remove fields already selected +// Remove fields already selected. foreach ($fields_available as $key => $available) { - foreach ($result_selected as $selected) { - if ($selected == $available) { - unset($fields_available[$key]); - } + if (isset($result_selected[$key])) { + unset($fields_available[$key]); } } diff --git a/pandora_console/godmode/massive/massive_delete_alerts.php b/pandora_console/godmode/massive/massive_delete_alerts.php index 862d54bbbc..d7f316fd4d 100755 --- a/pandora_console/godmode/massive/massive_delete_alerts.php +++ b/pandora_console/godmode/massive/massive_delete_alerts.php @@ -31,6 +31,7 @@ require_once $config['homedir'].'/include/functions_users.php'; if (is_ajax()) { $get_agents = (bool) get_parameter('get_agents'); $recursion = (int) get_parameter('recursion'); + $disabled_modules = (int) get_parameter('disabled_modules'); if ($get_agents) { $id_group = (int) get_parameter('id_group'); @@ -44,12 +45,18 @@ if (is_ajax()) { $groups = [$id_group]; } + if ($disabled_modules == 0) { + $filter['tagente_modulo.disabled'] = '<> 1'; + } else { + unset($filter['tagente_modulo.disabled']); + } + $agents_alerts = []; foreach ($groups as $group) { $agents_alerts_one_group = alerts_get_agents_with_alert_template( $id_alert_template, $group, - false, + $filter, [ 'tagente.alias', 'tagente.id_agente', @@ -253,6 +260,11 @@ $table->data[1][1] = html_print_select_groups( '', $id_alert_template == 0 ); + +$table->data[0][2] = __('Show alerts on disabled modules'); +$table->data[0][3] = html_print_checkbox('disabled_modules', 1, false, true, false); + + $table->data[1][2] = __('Group recursion'); $table->data[1][3] = html_print_checkbox('recursion', 1, false, true, false); @@ -360,6 +372,7 @@ $(document).ready (function () { "get_agents" : 1, "id_group" : this.value, "recursion" : $("#checkbox-recursion").is(":checked") ? 1 : 0, + "disabled_modules" : $("#checkbox-disabled_modules").is(":checked") ? 1 : 0, "id_alert_template" : $("#id_alert_template").val(), // Add a key prefix to avoid auto sorting in js object conversion "keys_prefix" : "_" @@ -387,6 +400,10 @@ $(document).ready (function () { $("#modules_selection_mode").change (function() { $("#id_agents").trigger('change'); }); + + $("#checkbox-disabled_modules").click(function () { + $("#id_group").trigger("change"); + }); }); /* ]]> */ diff --git a/pandora_console/godmode/menu.php b/pandora_console/godmode/menu.php index eaf33df640..bd980f5256 100644 --- a/pandora_console/godmode/menu.php +++ b/pandora_console/godmode/menu.php @@ -418,9 +418,11 @@ if (is_array($config['extensions'])) { $sub['godmode/extensions']['type'] = 'direct'; $sub['godmode/extensions']['subtype'] = 'nolink'; - $submenu = array_merge($menu_godmode['gextensions']['sub'], $sub); - if ($menu_godmode['gextensions']['sub'] != null) { - $menu_godmode['gextensions']['sub'] = $submenu; + if (is_array($menu_godmode['gextensions']['sub'])) { + $submenu = array_merge($menu_godmode['gextensions']['sub'], $sub); + if ($menu_godmode['gextensions']['sub'] != null) { + $menu_godmode['gextensions']['sub'] = $submenu; + } } } diff --git a/pandora_console/godmode/modules/manage_network_components.php b/pandora_console/godmode/modules/manage_network_components.php index 82cd02d771..60d39d26d9 100644 --- a/pandora_console/godmode/modules/manage_network_components.php +++ b/pandora_console/godmode/modules/manage_network_components.php @@ -36,6 +36,9 @@ require_once $config['homedir'].'/include/functions_component_groups.php'; if (defined('METACONSOLE')) { components_meta_print_header(); $sec = 'advanced'; + + $id_modulo = (int) get_parameter('id_component_type'); + $new_component = (bool) get_parameter('new_component'); } else { /* Hello there! :) diff --git a/pandora_console/godmode/reporting/create_container.php b/pandora_console/godmode/reporting/create_container.php index b0566d7867..3c2e144178 100644 --- a/pandora_console/godmode/reporting/create_container.php +++ b/pandora_console/godmode/reporting/create_container.php @@ -414,7 +414,7 @@ if ($edit_container) { echo ""; echo ''; echo ''; echo ''; echo '
'; - echo ui_toggle($single_table, 'Simple module graph', '', true, true); + echo ui_toggle($single_table, 'Simple module graph', '', '', true); echo '
'; @@ -466,7 +466,7 @@ if ($edit_container) { echo ""; echo ''; echo ''; echo ''; echo '
'; - echo ui_toggle(html_print_table($table, true), 'Custom graph', '', true, true); + echo ui_toggle(html_print_table($table, true), 'Custom graph', '', '', true); echo '
'; @@ -561,7 +561,7 @@ if ($edit_container) { echo ""; echo ''; echo ''; echo ''; echo '
'; - echo ui_toggle(html_print_table($table, true), 'Dynamic rules for simple module graph', '', true, true); + echo ui_toggle(html_print_table($table, true), 'Dynamic rules for simple module graph', '', '', true); echo '
'; diff --git a/pandora_console/godmode/reporting/graph_builder.graph_editor.php b/pandora_console/godmode/reporting/graph_builder.graph_editor.php index a03a67737f..33cacc9bab 100644 --- a/pandora_console/godmode/reporting/graph_builder.graph_editor.php +++ b/pandora_console/godmode/reporting/graph_builder.graph_editor.php @@ -356,9 +356,35 @@ echo "".__('Agents').''; echo ''; echo "".__('Modules').''; echo ''; -echo ''.html_print_select(agents_get_group_agents(), 'id_agents[]', 0, false, '', '', true, true, true, '', false, '').''; -echo "".html_print_image('images/darrowright.png', true).''; -echo ''.html_print_select([], 'module[]', 0, false, '', 0, true, true, true, '', false, '').''; +echo ''.html_print_select( + agents_get_group_agents(), + 'id_agents[]', + 0, + false, + '', + '', + true, + true, + true, + 'w100p', + false, + '' +).''; +echo "".html_print_image('images/darrowright.png', true).''; +echo ''.html_print_select( + [], + 'module[]', + 0, + false, + '', + 0, + true, + true, + true, + 'w100p', + false, + '' +).''; echo ''; echo ""; echo ""; diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index 93806138cb..a5e59e46ce 100755 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -221,7 +221,7 @@ switch ($action) { $server_name = $item['server_name']; // Metaconsole db connection. - if ($meta && $server_name != '') { + if ($meta && !empty($server_name)) { $connection = metaconsole_get_connection($server_name); if (metaconsole_load_external_db($connection) != NOERR) { continue; @@ -547,8 +547,43 @@ switch ($action) { break; case 'event_report_agent': - case 'event_report_group': + $description = $item['description']; + $period = $item['period']; + $group = $item['id_group']; $recursion = $item['recursion']; + $idAgent = $item['id_agent']; + $idAgentModule = $item['id_agent_module']; + + + $show_summary_group = $style['show_summary_group']; + $filter_event_severity = json_decode($style['filter_event_severity'], true); + $filter_event_status = json_decode($style['filter_event_status'], true); + $filter_event_type = json_decode($style['filter_event_type'], true); + + $event_graph_by_user_validator = $style['event_graph_by_user_validator']; + $event_graph_by_criticity = $style['event_graph_by_criticity']; + $event_graph_validated_vs_unvalidated = $style['event_graph_validated_vs_unvalidated']; + $include_extended_events = $item['show_extended_events']; + + $filter_search = $style['event_filter_search']; + + break; + + case 'event_report_group': + $description = $item['description']; + $period = $item['period']; + $group = $item['id_group']; + $recursion = $item['recursion']; + + $event_graph_by_agent = $style['event_graph_by_agent']; + $event_graph_by_user_validator = $style['event_graph_by_user_validator']; + $event_graph_by_criticity = $style['event_graph_by_criticity']; + $event_graph_validated_vs_unvalidated = $style['event_graph_validated_vs_unvalidated']; + + $filter_search = $style['event_filter_search']; + + + $include_extended_events = $item['show_extended_events']; break; @@ -2805,7 +2840,7 @@ function print_SLA_list($width, $action, $idItem=null) foreach ($itemsSLA as $item) { $server_name = $item['server_name']; // Metaconsole db connection. - if ($meta && $server_name != '') { + if ($meta && !empty($server_name)) { $connection = metaconsole_get_connection( $server_name ); @@ -3133,7 +3168,7 @@ function print_General_list($width, $action, $idItem=null, $type='general') foreach ($itemsGeneral as $item) { $server_name = $item['server_name']; // Metaconsole db connection. - if ($meta && $server_name != '') { + if ($meta && !empty($server_name)) { $connection = metaconsole_get_connection( $server_name ); @@ -3491,6 +3526,7 @@ $(document).ready (function () { $("#submit-create_item").click(function () { var type = $('#type').val(); + var name = $('#text-name').val(); switch (type){ case 'alert_report_module': case 'alert_report_agent': @@ -3521,6 +3557,13 @@ $(document).ready (function () { default: break; } + + if($('#text-name').val() == ''){ + alert( ); + return false; + } + + }); $("#submit-edit_item").click(function () { diff --git a/pandora_console/godmode/reporting/reporting_builder.php b/pandora_console/godmode/reporting/reporting_builder.php index e9d8b49176..d87a8f0e0a 100755 --- a/pandora_console/godmode/reporting/reporting_builder.php +++ b/pandora_console/godmode/reporting/reporting_builder.php @@ -774,31 +774,28 @@ switch ($action) { $table->head[1] = __('Description'); $table->head[2] = __('HTML'); $table->head[3] = __('XML'); - $table->size[0] = '20%'; - $table->size[1] = '30%'; + $table->size[0] = '60%'; + $table->size[1] = '20%'; $table->size[2] = '2%'; - $table->headstyle[2] = 'min-width: 35px;'; + $table->headstyle[2] = 'min-width: 35px;text-align: center;'; $table->size[3] = '2%'; - $table->headstyle[3] = 'min-width: 35px;'; + $table->headstyle[3] = 'min-width: 35px;text-align: center;'; $table->size[4] = '2%'; - $table->headstyle[4] = 'min-width: 35px;'; - $table->size[5] = '2%'; - $table->headstyle[5] = 'min-width: 35px;'; - $table->size[6] = '2%'; - $table->headstyle[6] = 'min-width: 35px;'; - $table->size[7] = '5%'; - $table->headstyle['csv'] = 'min-width: 65px;'; - $table->style[7] = 'text-align: center;'; - - $table->headstyle[9] = 'min-width: 100px;'; - $table->style[9] = 'text-align: center;'; + $table->headstyle[4] = 'min-width: 35px;text-align: center;'; $next = 4; // Calculate dinamically the number of the column. - if (enterprise_hook('load_custom_reporting_1') !== ENTERPRISE_NOT_HOOK) { + if (enterprise_hook('load_custom_reporting_1', [$table]) !== ENTERPRISE_NOT_HOOK) { $next = 7; } + $table->size[$next] = '2%'; + $table->style[$next] = 'text-align: center;'; + + $table->headstyle[($next + 2)] = 'min-width: 100px;'; + $table->style[($next + 2)] = 'text-align: center;'; + + // Admin options only for RM flag. if (check_acl($config['id_user'], 0, 'RM')) { $table->head[$next] = __('Private'); @@ -1348,6 +1345,8 @@ switch ($action) { $values['description'] = get_parameter('description'); $values['type'] = get_parameter('type', null); $values['recursion'] = get_parameter('recursion', null); + $values['show_extended_events'] = get_parameter('include_extended_events', null); + $label = get_parameter('label', ''); // Add macros name. @@ -1903,8 +1902,8 @@ switch ($action) { $style['event_graph_by_user_validator'] = $event_graph_by_user_validator; $style['event_graph_by_criticity'] = $event_graph_by_criticity; $style['event_graph_validated_vs_unvalidated'] = $event_graph_validated_vs_unvalidated; - $style['event_filter_search'] = $event_filter_search; + if ($label != '') { $style['label'] = $label; } else { @@ -2010,6 +2009,7 @@ switch ($action) { ); $name_it = (string) get_parameter('name'); $values['recursion'] = get_parameter('recursion', null); + $values['show_extended_events'] = get_parameter('include_extended_events', null); $values['name'] = reporting_label_macro( $items_label, $name_it @@ -2421,6 +2421,7 @@ switch ($action) { case 'event_report_agent': case 'event_report_group': case 'event_report_module': + $show_summary_group = get_parameter( 'show_summary_group', 0 @@ -2476,22 +2477,11 @@ switch ($action) { $style['event_graph_by_user_validator'] = $event_graph_by_user_validator; $style['event_graph_by_criticity'] = $event_graph_by_criticity; $style['event_graph_validated_vs_unvalidated'] = $event_graph_validated_vs_unvalidated; - - - switch ($values['type']) { - case 'event_report_group': - case 'event_report_agent': - $style['event_filter_search'] = $event_filter_search; - if ($label != '') { - $style['label'] = $label; - } else { - $style['label'] = ''; - } - break; - - default: - // Default. - break; + $style['event_filter_search'] = $event_filter_search; + if ($label != '') { + $style['label'] = $label; + } else { + $style['label'] = ''; } break; diff --git a/pandora_console/godmode/reporting/visual_console_builder.editor.php b/pandora_console/godmode/reporting/visual_console_builder.editor.php index 9ba8c56716..9b6697533f 100755 --- a/pandora_console/godmode/reporting/visual_console_builder.editor.php +++ b/pandora_console/godmode/reporting/visual_console_builder.editor.php @@ -25,6 +25,8 @@ if (empty($visualConsole)) { exit; } +ui_require_css_file('visual_maps'); + // ACL for the existing visual console // if (!isset($vconsole_read)) // $vconsole_read = check_acl ($config['id_user'], $visualConsole['id_group'], "VR"); @@ -170,6 +172,7 @@ echo "
'; - $out .= $events_table; + $out = $events_table; if (!$tactical_view) { + $out .= '
'; if ($agent_id != 0) { $out .= ''; $out .= '
'; @@ -1149,9 +2230,9 @@ function events_print_event_table( '.__('Event graph by agent').''.grafico_eventos_grupo(180, 60).''; $out .= '
'; } - } - $out .= '
'; + $out .= '
'; + } unset($table); @@ -1914,7 +2995,7 @@ function events_get_event_filter_select($manage=true) $sql = ' SELECT id_filter, id_name FROM tevent_filter - WHERE id_group_filter IN ('.implode(',', array_keys($user_groups)).')'; + WHERE id_group_filter IN (0, '.implode(',', array_keys($user_groups)).')'; $event_filters = db_get_all_rows_sql($sql); @@ -1946,6 +3027,7 @@ function events_page_responses($event, $childrens_ids=[]) // // Responses. // + $table_responses = new StdClass(); $table_responses->cellspacing = 2; $table_responses->cellpadding = 2; $table_responses->id = 'responses_table'; @@ -3255,10 +4337,14 @@ function events_page_general($event) $table_general->data[] = $data; $table_data = $table_general->data; - $table_data_total = count($table_data); + if (is_array($table_data)) { + $table_data_total = count($table_data); + } else { + $table_data_total = -1; + } for ($i = 0; $i <= $table_data_total; $i++) { - if (count($table_data[$i]) == 2) { + if (is_array($table_data[$i]) && count($table_data[$i]) == 2) { $table_general->colspan[$i][1] = 2; $table_general->style[2] = 'text-align:center; width:10%;'; } @@ -3273,34 +4359,49 @@ function events_page_general($event) /** * Generate 'comments' page for event viewer. * - * @param array $event Event. - * @param array $childrens_ids Children ids. + * @param array $event Event. * * @return string HTML. */ -function events_page_comments($event, $childrens_ids=[]) +function events_page_comments($event) { // Comments. global $config; + $comments = ''; + + $comments = $event['user_comment']; + if (isset($event['comments'])) { + $comments = $event['comments']; + } + $table_comments = new stdClass; $table_comments->width = '100%'; $table_comments->data = []; $table_comments->head = []; $table_comments->class = 'table_modal_alternate'; - $event_comments = $event['user_comment']; - $event_comments = str_replace(["\n", ' '], '
', $event_comments); + $comments = str_replace(["\n", ' '], '
', $comments); // If comments are not stored in json, the format is old. - $event_comments_array = json_decode($event_comments, true); - - // Show the comments more recent first. - if (is_array($event_comments_array)) { - $event_comments_array = array_reverse($event_comments_array); + $comments_array = json_decode(io_safe_output($comments), true); + if (!empty($comments) && json_last_error() != JSON_ERROR_NONE) { + $comments_array = [ + [ + 'comment' => 'Error retrieving comments', + 'action' => 'Internal message', + 'id_user' => 'SYSTEM', + 'utimestamp' => time(), + ], + ]; } - if (empty($event_comments_array)) { + // Show the comments more recent first. + if (is_array($comments_array)) { + $comments_array = array_reverse($comments_array); + } + + if (empty($comments_array)) { $comments_format = 'old'; } else { $comments_format = 'new'; @@ -3308,7 +4409,7 @@ function events_page_comments($event, $childrens_ids=[]) switch ($comments_format) { case 'new': - if (empty($event_comments_array)) { + if (empty($comments_array)) { $table_comments->style[0] = 'text-align:center;'; $table_comments->colspan[0][0] = 2; $data = []; @@ -3316,10 +4417,10 @@ function events_page_comments($event, $childrens_ids=[]) $table_comments->data[] = $data; } - if (isset($event_comments_array) === true - && is_array($event_comments_array) === true + if (isset($comments_array) === true + && is_array($comments_array) === true ) { - foreach ($event_comments_array as $c) { + foreach ($comments_array as $c) { $data[0] = ''.$c['action'].' by '.$c['id_user'].''; $data[0] .= '

'.date($config['date_format'], $c['utimestamp']).''; $data[1] = $c['comment']; @@ -3329,7 +4430,7 @@ function events_page_comments($event, $childrens_ids=[]) break; case 'old': - $comments_array = explode('
', $event_comments); + $comments_array = explode('
', $comments); // Split comments and put in table. $col = 0; @@ -3392,9 +4493,26 @@ function events_page_comments($event, $childrens_ids=[]) $childrens_ids ))) && $config['show_events_in_local'] == false || $config['event_replication'] == false ) { - $comments_form = '
'.html_print_textarea('comment', 3, 10, '', 'style="min-height: 15px; padding:0; width: 100%; disabled"', true); + $comments_form = '
'; + $comments_form .= html_print_textarea( + 'comment', + 3, + 10, + '', + 'style="min-height: 15px; padding:0; width: 100%; disabled"', + true + ); - $comments_form .= '
'.html_print_button(__('Add comment'), 'comment_button', false, 'event_comment();', 'class="sub next"', true).'

'; + $comments_form .= '
'; + $comments_form .= html_print_button( + __('Add comment'), + 'comment_button', + false, + 'event_comment();', + 'class="sub next"', + true + ); + $comments_form .= '

'; } else { $comments_form = ui_print_message( __('If event replication is ongoing, it won\'t be possible to enter comments here. This option is only to allow local pandora users to see comments, but not to operate with them. The operation, when event replication is enabled, must be done only in the Metaconsole.') @@ -5248,13 +6366,14 @@ function events_list_events_grouped_agents($sql) /** * Retrieves SQL for custom order. * - * @param string $sort_field Field. - * @param string $sort Order. - * @param integer $group_rep Group field. + * @param string $sort_field Field. + * @param string $sort Order. + * @param integer $group_rep Group field. + * @param boolean $only-fields Return only fields. * * @return string SQL. */ -function events_get_sql_order($sort_field='timestamp', $sort='DESC', $group_rep=0) +function events_get_sql_order($sort_field='timestamp', $sort='DESC', $group_rep=0, $only_fields=false) { $sort_field_translated = $sort_field; switch ($sort_field) { @@ -5303,11 +6422,19 @@ function events_get_sql_order($sort_field='timestamp', $sort='DESC', $group_rep= break; default: - // Ignore. + $sort_field_translated = $sort_field; break; } - $dir = ($sort == 'up') ? 'ASC' : 'DESC'; + if (strtolower($sort) != 'asc' && strtolower($sort) != 'desc') { + $dir = ($sort == 'up') ? 'ASC' : 'DESC'; + } else { + $dir = $sort; + } + + if ($only_fields) { + return $sort_field_translated.' '.$dir; + } return 'ORDER BY '.$sort_field_translated.' '.$dir; } diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index cde59c52bb..72bc9b5c91 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -2235,6 +2235,7 @@ function combined_graph_summatory_average( $data_array_pop[$key_reverse] = array_pop( $data_array_reverse[$key_reverse] ); + $count_data_array_reverse--; } } @@ -2343,14 +2344,21 @@ function graphic_agentaccess( $date = get_system_time(); $datelimit = ($date - $period); $data_array = []; + $interval = agents_get_interval($id_agent); $data = db_get_all_rows_sql( - "SELECT count(*) as data, min(utimestamp) as utimestamp - FROM tagent_access - WHERE id_agent = $id_agent - AND utimestamp > $datelimit - AND utimestamp < $date - GROUP by ROUND(utimestamp / 1800)" + sprintf( + 'SELECT utimestamp, count(*) as data + FROM tagent_access + WHERE id_agent = %d + AND utimestamp > %d + AND utimestamp < %d + GROUP BY ROUND(utimestamp/%d)', + $id_agent, + $datelimit, + $date, + $interval + ) ); if (isset($data) && is_array($data)) { @@ -2532,13 +2540,13 @@ function graph_agent_status($id_agent=false, $width=300, $height=200, $return=fa } // $colors = array(COL_CRITICAL, COL_WARNING, COL_NORMAL, COL_UNKNOWN); - $colors[__('Critical')] = COL_CRITICAL; - $colors[__('Warning')] = COL_WARNING; - $colors[__('Normal')] = COL_NORMAL; - $colors[__('Unknown')] = COL_UNKNOWN; + $colors['Critical'] = COL_CRITICAL; + $colors['Warning'] = COL_WARNING; + $colors['Normal'] = COL_NORMAL; + $colors['Unknown'] = COL_UNKNOWN; if ($show_not_init) { - $colors[__('Not init')] = COL_NOTINIT; + $colors['Not init'] = COL_NOTINIT; } if (array_sum($data) == 0) { diff --git a/pandora_console/include/functions_html.php b/pandora_console/include/functions_html.php index 505c395c68..bcb6108fec 100644 --- a/pandora_console/include/functions_html.php +++ b/pandora_console/include/functions_html.php @@ -1241,7 +1241,9 @@ function html_print_input_text_extended($name, $value, $id, $alt, $size, $maxlen $maxlength = 255; } - if ($size == 0) { + if ($size === false) { + $size = ''; + } else if ($size == 0) { $size = 10; } @@ -1442,7 +1444,9 @@ function html_print_input_password( $maxlength = 255; } - if ($size == 0) { + if ($size === false) { + $size = false; + } else if ($size == 0) { $size = 10; } @@ -1480,7 +1484,9 @@ function html_print_input_text($name, $value, $alt='', $size=50, $maxlength=255, $maxlength = 255; } - if ($size == 0) { + if ($size === false) { + $size = false; + } else if ($size == 0) { $size = 10; } @@ -2731,20 +2737,22 @@ function html_html2rgb($htmlcolor) /** * Print a magic-ajax control to select the module. * - * @param string $name The name of ajax control, by default is "module". - * @param string $default The default value to show in the ajax control. - * @param array $id_agents The array list of id agents as array(1,2,3), by default is false and the function use all agents (if the ACL desactive). - * @param boolean $ACL Filter the agents by the ACL list of user. - * @param string $scriptResult The source code of script to call, by default is - * empty. And the example is: - * function (e, data, formatted) { - * ... - * } + * @param string $name The name of ajax control, by default is "module". + * @param string $default The default value to show in the ajax control. + * @param array $id_agents The array list of id agents as array(1,2,3), by default is false and the function use all agents (if the ACL desactive). + * @param boolean $ACL Filter the agents by the ACL list of user. + * @param string $scriptResult The source code of script to call, by default is + * empty. And the example is: + * function (e, data, formatted) { + * ... + * } * - * And the formatted is the select item as string. + * And the formatted is the select item as string. * - * @param array $filter Other filter of modules. - * @param boolean $return If it is true return a string with the output instead to echo the output. + * @param array $filter Other filter of modules. + * @param boolean $return If it is true return a string with the output instead to echo the output. + * @param integer $id_agent_module Id agent module. + * @param string $size Size. * * @return mixed If the $return is true, return the output as string. */ @@ -2756,7 +2764,8 @@ function html_print_autocomplete_modules( $scriptResult='', $filter=[], $return=false, - $id_agent_module=0 + $id_agent_module=0, + $size='30' ) { global $config; @@ -2797,7 +2806,7 @@ function html_print_autocomplete_modules( $default, 'text-'.$name, '', - 30, + $size, 100, false, '', @@ -2933,7 +2942,10 @@ function html_print_sort_arrows($params, $order_tag, $up='up', $down='down') $url_down = 'index.php?'.http_build_query($params, '', '&'); // Build the links - return ' '.''.html_print_image('images/sort_up.png', true).''.''.html_print_image('images/sort_down.png', true).''; + $out = ' '; + $out .= html_print_image('images/sort_up_black.png', true); + $out .= ''; + $out .= html_print_image('images/sort_down_black.png', true).''; } @@ -3053,4 +3065,4 @@ function html_print_link_with_params($text, $params=[], $type='text', $style='') $html .= ''; return $html; -} \ No newline at end of file +} diff --git a/pandora_console/include/functions_menu.php b/pandora_console/include/functions_menu.php index 0dbe1049bc..3bf8a3448b 100644 --- a/pandora_console/include/functions_menu.php +++ b/pandora_console/include/functions_menu.php @@ -87,7 +87,7 @@ function menu_print_menu(&$menu) // ~ if (enterprise_hook ('enterprise_acl', array ($config['id_user'], $mainsec)) == false) // ~ continue; if (! isset($main['id'])) { - $id = 'menu_'.++$idcounter; + $id = 'menu_'.(++$idcounter); } else { $id = $main['id']; } @@ -405,9 +405,9 @@ function menu_print_menu(&$menu) $padding_top = ( $length >= 18) ? 6 : 12; if ($config['menu_type'] == 'classic') { - $output .= ''; + $output .= '
'.$main['text'].'
'; } else { - $output .= ''; + $output .= '
'.$main['text'].'
'; } // Add the notification ball if defined diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php index b9ed8e41d5..0335e851c9 100755 --- a/pandora_console/include/functions_modules.php +++ b/pandora_console/include/functions_modules.php @@ -2230,6 +2230,7 @@ function modules_get_agentmodule_data( 'module_name' => $values[$key]['module_name'], 'agent_id' => $values[$key]['agent_id'], 'agent_name' => $values[$key]['agent_name'], + 'module_type' => $values[$key]['module_type'], ]; } diff --git a/pandora_console/include/functions_networkmap.php b/pandora_console/include/functions_networkmap.php index af11deb541..ceaabaaadf 100644 --- a/pandora_console/include/functions_networkmap.php +++ b/pandora_console/include/functions_networkmap.php @@ -1807,9 +1807,9 @@ function networkmap_links_to_js_links( if (($relation['parent_type'] == NODE_MODULE) && ($relation['child_type'] == NODE_MODULE)) { if (($item['status_start'] == AGENT_MODULE_STATUS_CRITICAL_BAD) || ($item['status_end'] == AGENT_MODULE_STATUS_CRITICAL_BAD)) { - $item['link_color'] = '#FC4444'; + $item['link_color'] = '#e63c52'; } else if (($item['status_start'] == AGENT_MODULE_STATUS_WARNING) || ($item['status_end'] == AGENT_MODULE_STATUS_WARNING)) { - $item['link_color'] = '#FAD403'; + $item['link_color'] = '#f3b200'; } $agent = agents_get_agent_id_by_module_id( @@ -1837,9 +1837,9 @@ function networkmap_links_to_js_links( } } else if ($relation['child_type'] == NODE_MODULE) { if ($item['status_start'] == AGENT_MODULE_STATUS_CRITICAL_BAD) { - $item['link_color'] = '#FC4444'; + $item['link_color'] = '#e63c52'; } else if ($item['status_start'] == AGENT_MODULE_STATUS_WARNING) { - $item['link_color'] = '#FAD403'; + $item['link_color'] = '#f3b200'; } $agent2 = agents_get_agent_id_by_module_id( @@ -1864,9 +1864,9 @@ function networkmap_links_to_js_links( } } else if ($relation['parent_type'] == NODE_MODULE) { if ($item['status_end'] == AGENT_MODULE_STATUS_CRITICAL_BAD) { - $item['link_color'] = '#FC4444'; + $item['link_color'] = '#e63c52'; } else if ($item['status_end'] == AGENT_MODULE_STATUS_WARNING) { - $item['link_color'] = '#FAD403'; + $item['link_color'] = '#f3b200'; } $agent = agents_get_agent_id_by_module_id( diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index fba9d87a02..00860ac116 100755 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -151,11 +151,13 @@ function reporting_make_reporting_data( $contents = $report['contents']; } else { $report = io_safe_output(db_get_row('treport', 'id_report', $id_report)); - $contents = db_get_all_rows_field_filter( - 'treport_content', - 'id_report', - $id_report, - db_escape_key_identifier('order') + $contents = io_safe_output( + db_get_all_rows_field_filter( + 'treport_content', + 'id_report', + $id_report, + db_escape_key_identifier('order') + ) ); } @@ -326,26 +328,32 @@ function reporting_make_reporting_data( break; case 'general': - $report['contents'][] = reporting_general( - $report, - $content + $report['contents'][] = io_safe_output( + reporting_general( + $report, + $content + ) ); break; case 'availability': - $report['contents'][] = reporting_availability( - $report, - $content, - $date, - $time + $report['contents'][] = io_safe_output( + reporting_availability( + $report, + $content, + $date, + $time + ) ); break; case 'availability_graph': - $report['contents'][] = reporting_availability_graph( - $report, - $content, - $pdf + $report['contents'][] = io_safe_output( + reporting_availability_graph( + $report, + $content, + $pdf + ) ); break; @@ -475,9 +483,11 @@ function reporting_make_reporting_data( break; case 'agent_configuration': - $report['contents'][] = reporting_agent_configuration( - $report, - $content + $report['contents'][] = io_safe_output( + reporting_agent_configuration( + $report, + $content + ) ); break; @@ -673,12 +683,14 @@ function reporting_make_reporting_data( case 'agent_detailed_event': case 'event_report_agent': - $report_control = reporting_event_report_agent( - $report, - $content, - $type, - $force_width_chart, - $force_height_chart + $report_control = io_safe_output( + reporting_event_report_agent( + $report, + $content, + $type, + $force_width_chart, + $force_height_chart + ) ); if ($report_control['total_events'] == 0 && $content['hide_no_data'] == 1) { continue; @@ -1383,7 +1395,7 @@ function reporting_event_top_n( foreach ($tops as $key => $row) { // Metaconsole connection. $server_name = $row['server_name']; - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { $connection = metaconsole_get_connection($server_name); if (metaconsole_load_external_db($connection) != NOERR) { // ui_print_error_message ("Error connecting to ".$server_name); @@ -1426,7 +1438,7 @@ function reporting_event_top_n( } // Restore dbconnection. - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { metaconsole_restore_db(); } } @@ -2176,7 +2188,7 @@ function reporting_agent_module($report, $content) foreach ($agents as $agent) { $row = []; $row['agent_status'][$agent] = agents_get_status($agent); - $row['agent_name'] = agents_get_alias($agent); + $row['agent_name'] = io_safe_output(agents_get_alias($agent)); $agent_modules = agents_get_modules($agent); $row['modules'] = []; @@ -2330,7 +2342,7 @@ function reporting_exception( do { // Metaconsole connection. $server_name = $exceptions[$i]['server_name']; - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { $connection = metaconsole_get_connection($server_name); if (metaconsole_load_external_db($connection) != NOERR) { // ui_print_error_message ("Error connecting to ".$server_name); @@ -2372,7 +2384,7 @@ function reporting_exception( $i++; // Restore dbconnection. - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { metaconsole_restore_db(); } } while ($min === false && $i < count($exceptions)); @@ -2385,7 +2397,7 @@ function reporting_exception( foreach ($exceptions as $exc) { // Metaconsole connection. $server_name = $exc['server_name']; - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { $connection = metaconsole_get_connection($server_name); if (metaconsole_load_external_db($connection) != NOERR) { // ui_print_error_message ("Error connecting to ".$server_name); @@ -2499,7 +2511,7 @@ function reporting_exception( } // Restore dbconnection - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { metaconsole_restore_db(); } } @@ -2693,7 +2705,7 @@ function reporting_group_report($report, $content) { global $config; - $metaconsole_on = ($config['metaconsole'] == 1) && defined('METACONSOLE'); + $metaconsole_on = ($config['metaconsole'] == 1) && is_metaconsole(); $return['type'] = 'group_report'; @@ -2777,7 +2789,7 @@ function reporting_event_report_agent( } $return['title'] = $content['name']; - $return['subtitle'] = agents_get_alias($content['id_agent']); + $return['subtitle'] = io_safe_output(agents_get_alias($content['id_agent'])); $return['description'] = $content['description']; $return['date'] = reporting_get_date_text($report, $content); @@ -6073,7 +6085,7 @@ function reporting_advanced_sla( // SLA. $return['SLA'] = reporting_sla_get_compliance_from_array($return); - $return['SLA_fixed'] = sla_truncate( + $return['sla_fixed'] = sla_truncate( $return['SLA'], $config['graph_precision'] ); @@ -6173,7 +6185,7 @@ function reporting_availability($report, $content, $date=false, $time=false) foreach ($items as $item) { // aaMetaconsole connection $server_name = $item['server_name']; - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { $connection = metaconsole_get_connection($server_name); if (metaconsole_load_external_db($connection) != NOERR) { // ui_print_error_message ("Error connecting to ".$server_name); @@ -6185,7 +6197,7 @@ function reporting_availability($report, $content, $date=false, $time=false) || modules_is_not_init($item['id_agent_module']) ) { // Restore dbconnection - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { metaconsole_restore_db(); } @@ -6242,7 +6254,7 @@ function reporting_availability($report, $content, $date=false, $time=false) $text = $row['data']['agent'].' ('.$text.')'; // Restore dbconnection - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { metaconsole_restore_db(); } @@ -6396,10 +6408,12 @@ function reporting_availability_graph($report, $content, $pdf=false) $edge_interval = 10; if (empty($content['subitems'])) { - $slas = db_get_all_rows_field_filter( - 'treport_content_sla_combined', - 'id_report_content', - $content['id_rc'] + $slas = io_safe_output( + db_get_all_rows_field_filter( + 'treport_content_sla_combined', + 'id_report_content', + $content['id_rc'] + ) ); } else { $slas = $content['subitems']; @@ -6807,7 +6821,7 @@ function reporting_increment($report, $content) $return['data'] = []; - if (defined('METACONSOLE')) { + if (is_metaconsole()) { $sql1 = 'SELECT datos FROM tagente_datos WHERE id_agente_modulo = '.$id_agent_module.' AND utimestamp <= '.(time() - $period).' ORDER BY utimestamp DESC'; $sql2 = 'SELECT datos FROM tagente_datos WHERE id_agente_modulo = '.$id_agent_module.' ORDER BY utimestamp DESC'; @@ -6845,7 +6859,7 @@ function reporting_increment($report, $content) $last_data = db_get_value_sql('SELECT datos FROM tagente_datos WHERE id_agente_modulo = '.$id_agent_module.' ORDER BY utimestamp DESC'); } - if (!defined('METACONSOLE')) { + if (!is_metaconsole()) { } if ($old_data === false || $last_data === false) { @@ -6934,7 +6948,7 @@ function reporting_general($report, $content) foreach ($generals as $row) { // Metaconsole connection $server_name = $row['server_name']; - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { $connection = metaconsole_get_connection($server_name); if (metaconsole_load_external_db($connection) != NOERR) { // ui_print_error_message ("Error connecting to ".$server_name); @@ -7085,7 +7099,7 @@ function reporting_general($report, $content) $i++; // Restore dbconnection - if (($config['metaconsole'] == 1) && $server_name != '' && defined('METACONSOLE')) { + if (($config['metaconsole'] == 1) && $server_name != '' && is_metaconsole()) { metaconsole_restore_db(); } } @@ -10980,10 +10994,10 @@ function reporting_get_stats_servers() $tdata = []; ''.format_numeric($server_performance['total_local_modules']).''; - $tdata[0] = html_print_image('images/module.png', true, ['title' => __('Total running modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/module.png', true, ['title' => __('Total running modules')]); $tdata[1] = ''.format_numeric($server_performance['total_modules']).''; $tdata[2] = ''.format_numeric($server_performance['total_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; $table_srv->rowclass[] = ''; $table_srv->data[] = $tdata; @@ -10995,22 +11009,22 @@ function reporting_get_stats_servers() $table_srv->data[] = $tdata; $tdata = []; - $tdata[0] = html_print_image('images/database.png', true, ['title' => __('Local modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/database.png', true, ['title' => __('Local modules')]); $tdata[1] = ''.format_numeric($server_performance['total_local_modules']).''; $tdata[2] = ''.format_numeric($server_performance['local_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; $table_srv->rowclass[] = ''; $table_srv->data[] = $tdata; if (isset($server_performance['total_network_modules'])) { $tdata = []; - $tdata[0] = html_print_image('images/network.png', true, ['title' => __('Network modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/network.png', true, ['title' => __('Network modules')]); $tdata[1] = ''.format_numeric($server_performance['total_network_modules']).''; $tdata[2] = ''.format_numeric($server_performance['network_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; if ($server_performance['total_remote_modules'] > 10000 && !enterprise_installed()) { $tdata[4] = "
"; @@ -11024,11 +11038,11 @@ function reporting_get_stats_servers() if (isset($server_performance['total_plugin_modules'])) { $tdata = []; - $tdata[0] = html_print_image('images/plugin.png', true, ['title' => __('Plugin modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/plugin.png', true, ['title' => __('Plugin modules')]); $tdata[1] = ''.format_numeric($server_performance['total_plugin_modules']).''; $tdata[2] = ''.format_numeric($server_performance['plugin_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; $table_srv->rowclass[] = ''; $table_srv->data[] = $tdata; @@ -11036,11 +11050,11 @@ function reporting_get_stats_servers() if (isset($server_performance['total_prediction_modules'])) { $tdata = []; - $tdata[0] = html_print_image('images/chart_bar.png', true, ['title' => __('Prediction modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/chart_bar.png', true, ['title' => __('Prediction modules')]); $tdata[1] = ''.format_numeric($server_performance['total_prediction_modules']).''; $tdata[2] = ''.format_numeric($server_performance['prediction_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; $table_srv->rowclass[] = ''; $table_srv->data[] = $tdata; @@ -11048,11 +11062,11 @@ function reporting_get_stats_servers() if (isset($server_performance['total_wmi_modules'])) { $tdata = []; - $tdata[0] = html_print_image('images/wmi.png', true, ['title' => __('WMI modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/wmi.png', true, ['title' => __('WMI modules')]); $tdata[1] = ''.format_numeric($server_performance['total_wmi_modules']).''; $tdata[2] = ''.format_numeric($server_performance['wmi_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; $table_srv->rowclass[] = ''; $table_srv->data[] = $tdata; @@ -11060,11 +11074,11 @@ function reporting_get_stats_servers() if (isset($server_performance['total_web_modules'])) { $tdata = []; - $tdata[0] = html_print_image('images/world.png', true, ['title' => __('Web modules'), 'width' => '25px']); + $tdata[0] = html_print_image('images/world.png', true, ['title' => __('Web modules')]); $tdata[1] = ''.format_numeric($server_performance['total_web_modules']).''; $tdata[2] = ''.format_numeric($server_performance['web_modules_rate'], 2).''; - $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second'), 'width' => '16px']).'/sec '; + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Ratio').': '.__('Modules by second')]).'/sec '; $table_srv->rowclass[] = ''; $table_srv->data[] = $tdata; @@ -11082,7 +11096,6 @@ function reporting_get_stats_servers() true, [ 'title' => __('Total events'), - 'width' => '25px', ] ); $tdata[1] = ''.html_print_image('images/spinner.gif', true).''; diff --git a/pandora_console/include/functions_reporting_html.php b/pandora_console/include/functions_reporting_html.php index 10bef8631f..c8d5b3e29e 100644 --- a/pandora_console/include/functions_reporting_html.php +++ b/pandora_console/include/functions_reporting_html.php @@ -4270,16 +4270,16 @@ function reporting_get_agents_by_status($data, $graph_width=250, $graph_height=1 $agent_data = []; $agent_data[0] = html_print_image('images/agent_critical.png', true, ['title' => __('Agents critical')]); - $agent_data[1] = "".format_numeric($data['agent_critical']).''; + $agent_data[1] = "".format_numeric($data['agent_critical']).''; $agent_data[2] = html_print_image('images/agent_warning.png', true, ['title' => __('Agents warning')]); - $agent_data[3] = "".format_numeric($data['agent_warning']).''; + $agent_data[3] = "".format_numeric($data['agent_warning']).''; $table_agent->data[] = $agent_data; $agent_data = []; $agent_data[0] = html_print_image('images/agent_ok.png', true, ['title' => __('Agents ok')]); - $agent_data[1] = "".format_numeric($data['agent_ok']).''; + $agent_data[1] = "".format_numeric($data['agent_ok']).''; $agent_data[2] = html_print_image('images/agent_unknown.png', true, ['title' => __('Agents unknown')]); $agent_data[3] = "".format_numeric($data['agent_unknown']).''; @@ -4367,13 +4367,13 @@ function reporting_get_events($data, $links=false) } if (defined('METACONSOLE')) { - $table_events->style[0] = 'background-color:#FC4444'; + $table_events->style[0] = 'background-color:#e63c52'; $table_events->data[0][0] = html_print_image('images/module_event_critical.png', true, ['title' => __('Critical events')]); $table_events->data[0][0] .= '   '."".format_numeric($data['critical']).''; - $table_events->style[1] = 'background-color:#FAD403'; + $table_events->style[1] = 'background-color:#f3b200'; $table_events->data[0][1] = html_print_image('images/module_event_warning.png', true, ['title' => __('Warning events')]); $table_events->data[0][1] .= '   '."".format_numeric($data['warning']).''; - $table_events->style[2] = 'background-color:#80BA27'; + $table_events->style[2] = 'background-color:#82b92e'; $table_events->data[0][2] = html_print_image('images/module_event_ok.png', true, ['title' => __('OK events')]); $table_events->data[0][2] .= '   '."".format_numeric($data['normal']).''; $table_events->style[3] = 'background-color:#B2B2B2'; @@ -4381,11 +4381,11 @@ function reporting_get_events($data, $links=false) $table_events->data[0][3] .= '   '."".format_numeric($data['unknown']).''; } else { $table_events->data[0][0] = html_print_image('images/module_critical.png', true, ['title' => __('Critical events')]); - $table_events->data[0][0] .= '   '."".format_numeric($data['critical']).''; + $table_events->data[0][0] .= '   '."".format_numeric($data['critical']).''; $table_events->data[0][1] = html_print_image('images/module_warning.png', true, ['title' => __('Warning events')]); - $table_events->data[0][1] .= '   '."".format_numeric($data['warning']).''; + $table_events->data[0][1] .= '   '."".format_numeric($data['warning']).''; $table_events->data[0][2] = html_print_image('images/module_ok.png', true, ['title' => __('OK events')]); - $table_events->data[0][2] .= '   '."".format_numeric($data['normal']).''; + $table_events->data[0][2] .= '   '."".format_numeric($data['normal']).''; $table_events->data[0][3] = html_print_image('images/module_unknown.png', true, ['title' => __('Unknown events')]); $table_events->data[0][3] .= '   '."".format_numeric($data['unknown']).''; } diff --git a/pandora_console/include/functions_snmp_browser.php b/pandora_console/include/functions_snmp_browser.php index ca2b2d055b..8e916166df 100644 --- a/pandora_console/include/functions_snmp_browser.php +++ b/pandora_console/include/functions_snmp_browser.php @@ -756,10 +756,10 @@ function snmp_browser_print_container($return=false, $width='100%', $height='500 $output .= ''; $output .= '
'; - $output .= ui_toggle(html_print_table($table2, true), __('Search options'), '', true, true); + $output .= ui_toggle(html_print_table($table2, true), __('Search options'), '', '', true, true); $output .= '
'; // SNMP tree container diff --git a/pandora_console/include/functions_tags.php b/pandora_console/include/functions_tags.php index 952677ce66..6d0211f89d 100644 --- a/pandora_console/include/functions_tags.php +++ b/pandora_console/include/functions_tags.php @@ -744,7 +744,8 @@ function tags_get_acl_tags( $query_table='', $meta=false, $childrens_ids=[], - $force_group_and_tag=false + $force_group_and_tag=false, + $id_grupo_table_pretag='' ) { global $config; @@ -814,7 +815,13 @@ function tags_get_acl_tags( case 'event_condition': // Return the condition of the tags for tevento table. - $condition = tags_get_acl_tags_event_condition($acltags, $meta, $force_group_and_tag); + $condition = tags_get_acl_tags_event_condition( + $acltags, + $meta, + $force_group_and_tag, + false, + $id_grupo_table_pretag + ); if (!empty($condition)) { return " $query_prefix ".'('.$condition.')'; @@ -905,8 +912,13 @@ function tags_get_acl_tags_module_condition($acltags, $modules_table='', $force_ */ -function tags_get_acl_tags_event_condition($acltags, $meta=false, $force_group_and_tag=false, $force_equal=false) -{ +function tags_get_acl_tags_event_condition( + $acltags, + $meta=false, + $force_group_and_tag=false, + $force_equal=false, + $id_grupo_table_pretag='' +) { global $config; $condition = []; @@ -923,7 +935,7 @@ function tags_get_acl_tags_event_condition($acltags, $meta=false, $force_group_a // Group condition (The module belongs to an agent of the group X) // $group_condition = sprintf('id_grupo IN (%s)', implode(',', array_values(groups_get_id_recursive($group_id, true))));. - $group_condition = "(id_grupo = $group_id OR id_group = $group_id)"; + $group_condition = '('.$id_grupo_table_pretag.'id_grupo = '.$group_id.' OR id_group = '.$group_id.')'; // Tags condition (The module has at least one of the restricted tags). $tags_condition = ''; @@ -959,7 +971,7 @@ function tags_get_acl_tags_event_condition($acltags, $meta=false, $force_group_a } $in_group = implode(',', $without_tags); - $condition .= sprintf('(id_grupo IN (%s) OR id_group IN (%s))', $in_group, $in_group); + $condition .= sprintf('('.$id_grupo_table_pretag.'id_grupo IN (%s) OR id_group IN (%s))', $in_group, $in_group); } $condition = !empty($condition) ? "($condition)" : ''; @@ -1097,6 +1109,12 @@ function tags_get_user_tags($id_user=false, $access='AR', $return_tag_any=false) if (empty($user_tags_id)) { $user_tags_id = $t; } else { + if (empty($t)) { + // Empty is 'all of them'. + // TODO: Review this... + $t = []; + } + $user_tags_id = array_unique(array_merge($t, $user_tags_id)); } } diff --git a/pandora_console/include/functions_treeview.php b/pandora_console/include/functions_treeview.php index 5341424efa..c8b893c091 100755 --- a/pandora_console/include/functions_treeview.php +++ b/pandora_console/include/functions_treeview.php @@ -327,7 +327,7 @@ function treeview_printModuleTable($id_module, $server_data=false, $no_head=fals if ($user_access_node && check_acl($config['id_user'], $id_group, 'AW')) { // Actions table - echo '
'; + echo '
'; echo ''; html_print_submit_button(__('Go to module edition'), 'upd_button', false, 'class="sub config"'); echo ''; @@ -637,7 +637,13 @@ function treeview_printTable($id_agente, $server_data=[], $no_head=false) $row = []; $row['title'] = __('Next agent contact'); - $row['data'] = progress_bar($progress, 150, 20); + $row['data'] = ui_progress( + $progress, + '100%', + '1.5', + '#82b92e', + true + ); $table->data['next_contact'] = $row; // End of table @@ -664,7 +670,7 @@ function treeview_printTable($id_agente, $server_data=[], $no_head=false) $agent_table .= '
'; // print agent data toggle - ui_toggle($agent_table, __('Agent data'), '', false); + ui_toggle($agent_table, __('Agent data'), '', '', false); // Advanced data $table = new StdClass(); diff --git a/pandora_console/include/functions_ui.php b/pandora_console/include/functions_ui.php index c81148b9c9..ea07c20d6a 100755 --- a/pandora_console/include/functions_ui.php +++ b/pandora_console/include/functions_ui.php @@ -1441,11 +1441,16 @@ function ui_require_css_file($name, $path='include/styles/') if (! file_exists($filename) && ! file_exists($config['homedir'].'/'.$filename) + && ! file_exists($config['homedir'].'/'.ENTERPRISE_DIR.'/'.$filename) ) { return false; } - $config['css'][$name] = $filename; + if (is_metaconsole()) { + $config['css'][$name] = '/../../'.$filename; + } else { + $config['css'][$name] = $filename; + } return true; } @@ -1738,6 +1743,7 @@ function ui_process_page_head($string, $bitfield) // Add the jquery UI styles CSS. $config['css']['jquery-UI'] = 'include/styles/js/jquery-ui.min.css'; + $config['css']['jquery-UI-custom'] = 'include/styles/js/jquery-ui_custom.css'; // Add the dialog styles CSS. $config['css']['dialog'] = 'include/styles/dialog.css'; // Add the dialog styles CSS. @@ -1756,6 +1762,7 @@ function ui_process_page_head($string, $bitfield) [ 'common' => 'include/styles/common.css', 'menu' => 'include/styles/menu.css', + 'tables' => 'include/styles/tables.css', $config['style'] => 'include/styles/'.$config['style'].'.css', ], $config['css'] @@ -1783,47 +1790,6 @@ function ui_process_page_head($string, $bitfield) * End load CSS */ - /* - * Load JS - */ - - if (empty($config['js'])) { - $config['js'] = []; - // If it's empty, false or not init set array to empty just in case. - } - - // Pandora specific JavaScript should go first. - $config['js'] = array_merge(['pandora' => 'include/javascript/pandora.js'], $config['js']); - // Load base64 javascript library. - $config['js']['base64'] = 'include/javascript/encode_decode_base64.js'; - // Load webchat javascript library. - $config['js']['webchat'] = 'include/javascript/webchat.js'; - // Load qrcode library. - $config['js']['qrcode'] = 'include/javascript/qrcode.js'; - // Load intro.js library (for bubbles and clippy). - $config['js']['intro'] = 'include/javascript/intro.js'; - $config['js']['clippy'] = 'include/javascript/clippy.js'; - // Load Underscore.js library. - $config['js']['underscore'] = 'include/javascript/underscore-min.js'; - - // Load other javascript. - // We can't load empty. - $loaded = ['']; - foreach ($config['js'] as $name => $filename) { - if (in_array($name, $loaded)) { - continue; - } - - array_push($loaded, $name); - - $url_js = ui_get_full_url($filename); - $output .= ''."\n\t"; - } - - /* - * End load JS - */ - /* * Load jQuery */ @@ -1881,6 +1847,47 @@ function ui_process_page_head($string, $bitfield) * End load JQuery */ + /* + * Load JS + */ + + if (empty($config['js'])) { + $config['js'] = []; + // If it's empty, false or not init set array to empty just in case. + } + + // Pandora specific JavaScript should go first. + $config['js'] = array_merge(['pandora' => 'include/javascript/pandora.js'], $config['js']); + // Load base64 javascript library. + $config['js']['base64'] = 'include/javascript/encode_decode_base64.js'; + // Load webchat javascript library. + $config['js']['webchat'] = 'include/javascript/webchat.js'; + // Load qrcode library. + $config['js']['qrcode'] = 'include/javascript/qrcode.js'; + // Load intro.js library (for bubbles and clippy). + $config['js']['intro'] = 'include/javascript/intro.js'; + $config['js']['clippy'] = 'include/javascript/clippy.js'; + // Load Underscore.js library. + $config['js']['underscore'] = 'include/javascript/underscore-min.js'; + + // Load other javascript. + // We can't load empty. + $loaded = ['']; + foreach ($config['js'] as $name => $filename) { + if (in_array($name, $loaded)) { + continue; + } + + array_push($loaded, $name); + + $url_js = ui_get_full_url($filename); + $output .= ''."\n\t"; + } + + /* + * End load JS + */ + include_once __DIR__.'/graphs/functions_flot.php'; $output .= include_javascript_dependencies_flot_graph(true); @@ -2717,6 +2724,15 @@ function ui_print_module_status( * @param string $color Color. * @param boolean $return Return or paint (if false). * @param boolean $text Text to be displayed,by default progress %. + * @param array $ajax Ajax: [ 'page' => 'page', 'data' => 'data' ] Sample: + * [ + * 'page' => 'operation/agentes/ver_agente', Target page. + * 'interval' => 100 / $agent["intervalo"], Ask every interval seconds. + * 'data' => [ Data to be sent to target page. + * 'id_agente' => $id_agente, + * 'refresh_contact' => 1, + * ], + * ]. * * @return string HTML code. */ @@ -2724,9 +2740,10 @@ function ui_progress( $progress, $width='100%', $height='2.5', - $color='#80ba27', + $color='#82b92e', $return=true, - $text='' + $text='', + $ajax=false ) { if (!$progress) { $progress = 0; @@ -2745,10 +2762,56 @@ function ui_progress( } ui_require_css_file('progress'); - $output .= '
'; - $output .= ''.$text.''; - $output .= '
'; - $output .= '
'; + $output .= ''; + $output .= ''; + $output .= ''; + + if ($ajax !== false && is_array($ajax)) { + $output .= ''; + } if (!$return) { echo $output; @@ -2758,6 +2821,462 @@ function ui_progress( } +/** + * Generate needed code to print a datatables jquery plugin. + * + * @param array $parameters All desired data using following format: + * [ + * 'print' => true (by default printed) + * 'id' => datatable id. + * 'class' => datatable class. + * 'style' => datatable style. + * 'order' => [ + * 'field' => column name + * 'direction' => asc or desc + * ], + * 'default_pagination' => integer, default pagination is set to block_size + * 'ajax_url' => 'include/ajax.php' ajax_url. + * 'ajax_data' => [ operation => 1 ] extra info to be sent. + * 'ajax_postprocess' => a javscript function to postprocess data received + * by ajax call. It is applied foreach row and must + * use following format: + * * [code] + * * function (item) { + * * // Process received item, for instance, name: + * * tmp = '' + item.name + ''; + * * item.name = tmp; + * * } + * * [/code] + * 'columns_names' => [ + * 'column1' :: Used as th text. Direct text entry. It could be array: + * OR + * [ + * 'id' => th id. + * 'class' => th class. + * 'style' => th style. + * 'text' => 'column1'. + * ] + * ], + * 'columns' => [ + * 'column1', + * 'column2', + * ... + * ], + * 'no_sortable_columns' => [ indexes ] 1,2... -1 etc. Avoid sorting. + * 'form' => [ + * 'html' => 'html code' a directly defined inputs in HTML. + * 'extra_buttons' => [ + * [ + * 'id' => button id, + * 'class' => button class, + * 'style' => button style, + * 'text' => button text, + * 'onclick' => button onclick, + * ] + * ], + * 'search_button_class' => search button class. + * 'class' => form class. + * 'id' => form id. + * 'style' => form style. + * 'js' => optional extra actions onsubmit. + * 'inputs' => [ + * 'label' => Input label. + * 'type' => Input type. + * 'value' => Input value. + * 'name' => Input name. + * 'id' => Input id. + * 'options' => [ + * 'option1' + * 'option2' + * ... + * ] + * ] + * ], + * 'extra_html' => HTML content to be placed after 'filter' section. + * 'drawCallback' => function to be called after draw. Sample in: + * https://datatables.net/examples/advanced_init/row_grouping.html + * ] + * End. + * + * @return string HTML code with datatable. + * @throws Exception On error. + */ +function ui_print_datatable(array $parameters) +{ + global $config; + + if (isset($parameters['id'])) { + $table_id = $parameters['id']; + } else { + $table_id = uniqid('datatable_'); + } + + if (!isset($parameters['columns']) || !is_array($parameters['columns'])) { + throw new Exception('[ui_print_datatable]: You must define columns for datatable'); + } + + if (!isset($parameters['ajax_url'])) { + throw new Exception('[ui_print_datatable]: Parameter ajax_url is required'); + } + + if (!isset($parameters['default_pagination'])) { + $parameters['default_pagination'] = $config['block_size']; + } + + $no_sortable_columns = []; + if (isset($parameters['no_sortable_columns'])) { + $no_sortable_columns = json_encode($parameters['no_sortable_columns']); + } + + if (!is_array($parameters['order'])) { + $order = '0, "asc"'; + } else { + if (!isset($parameters['order']['direction'])) { + $direction = 'asc'; + } + + if (!isset($parameters['order']['field'])) { + $order = 1; + } else { + $order = array_search( + $parameters['order']['field'], + $parameters['columns'] + ); + + if (empty($order)) { + $order = 1; + } + } + + $order .= ', "'.$parameters['order']['direction'].'"'; + } + + if (!isset($parameters['ajax_data'])) { + $parameters['ajax_data'] = ''; + } + + $search_button_class = 'sub filter'; + if (isset($parameters['search_button_class'])) { + $search_button_class = $parameters['search_button_class']; + } + + if (isset($parameters['pagination_options'])) { + $pagination_options = $parameters['pagination_options']; + } else { + $pagination_options = [ + [ + $parameters['default_pagination'], + 10, + 25, + 100, + 200, + 500, + 1000, + -1, + ], + [ + $parameters['default_pagination'], + 10, + 25, + 100, + 200, + 500, + 1000, + 'All', + ], + ]; + } + + if (!is_array($parameters['datacolumns'])) { + $parameters['datacolumns'] = $parameters['columns']; + } + + // Datatable filter. + if (isset($parameters['form']) && is_array($parameters['form'])) { + if (isset($parameters['form']['id'])) { + $form_id = $parameters['form']['id']; + } else { + $form_id = uniqid('datatable_filter_'); + } + + if (isset($parameters['form']['class'])) { + $form_class = $parameters['form']['class']; + } else { + $form_class = ''; + } + + if (isset($parameters['form']['style'])) { + $form_style = $parameters['form']['style']; + } else { + $form_style = ''; + } + + if (isset($parameters['form']['js'])) { + $form_js = $parameters['form']['js']; + } else { + $form_js = ''; + } + + $filter = '
'; + + if (isset($parameters['form']['html'])) { + $filter .= $parameters['form']['html']; + } + + $filter .= '
    '; + + foreach ($parameters['form']['inputs'] as $input) { + $filter .= '
  • '; + $filter .= ''; + if ($input['type'] != 'select') { + $filter .= ''; + } else { + // Select. + $filter .= ''; + } + + $filter .= '
  • '; + } + + $filter .= '
  • '; + // Search button. + $filter .= ''; + + // Extra buttons. + if (is_array($parameters['form']['extra_buttons'])) { + foreach ($parameters['form']['extra_buttons'] as $button) { + $filter .= ''; + } + } + + $filter .= '
  • '; + + $filter .= '
'; + $filter = ui_toggle( + $filter, + __('Filter'), + '', + '', + true, + false, + 'white_box white_box_opened', + 'no-border' + ); + } else if (isset($parameters['form_html'])) { + $filter = ui_toggle( + $parameters['form_html'], + __('Filter'), + '', + '', + true, + false, + 'white_box white_box_opened', + 'no-border' + ); + } + + // Extra html. + $extra = ''; + if (isset($parameters['extra_html']) && !empty($parameters['extra_html'])) { + $extra = $parameters['extra_html']; + } + + // Base table. + $table = ''; + $table .= ''; + + if (isset($parameters['column_names']) + && is_array($parameters['column_names']) + ) { + $names = $parameters['column_names']; + } else { + $names = $parameters['columns']; + } + + foreach ($names as $column) { + if (is_array($column)) { + $table .= ''; + } else { + $table .= ''; + } + } + + $table .= ''; + $table .= '
'.__($column['text']); + $table .= $column['extra']; + $table .= ''.__($column).'
'; + + $pagination_class = 'pandora_pagination'; + if (!empty($parameters['pagination_class'])) { + $pagination_class = $parameters['pagination_class']; + } + + // Javascript controller. + $js = ''; + + // Order. + $err_msg = '
'; + $output = $err_msg.$filter.$extra.$table.$js; + + ui_require_css_file('datatables.min', 'include/styles/js/'); + ui_require_javascript_file('datatables.min'); + ui_require_javascript_file('buttons.dataTables.min'); + ui_require_javascript_file('dataTables.buttons.min'); + ui_require_javascript_file('buttons.html5.min'); + ui_require_javascript_file('buttons.print.min'); + + $output = $include.$output; + + // Print datatable if needed. + if (!(isset($parameters['print']) && $parameters['print'] === false)) { + echo $output; + } + + return $output; +} + + /** * Returns a div wich represents the type received. * @@ -2919,12 +3438,15 @@ function ui_print_event_priority( /** * Print a code into a DIV and enable a toggle to show and hide it. * - * @param string $code Html code. - * @param string $name Name of the link. - * @param string $title Title of the link. - * @param boolean $hidden_default If the div will be hidden by default (default: true). - * @param boolean $return Whether to return an output string or echo now (default: true). - * @param string $toggle_class Toggle class. + * @param string $code Html code. + * @param string $name Name of the link. + * @param string $title Title of the link. + * @param string $id Block id. + * @param boolean $hidden_default If the div will be hidden by default (default: true). + * @param boolean $return Whether to return an output string or echo now (default: true). + * @param string $toggle_class Toggle class. + * @param string $container_class Container class. + * @param string $main_class Main object class. * * @return string HTML. */ @@ -2932,10 +3454,12 @@ function ui_toggle( $code, $name, $title='', + $id='', $hidden_default=true, $return=false, $toggle_class='', - $container_class='white-box-content' + $container_class='white-box-content', + $main_class='box-shadow white_table_graph' ) { // Generate unique Id. $uniqid = uniqid(''); @@ -2952,7 +3476,7 @@ function ui_toggle( } // Link to toggle. - $output = '
'; + $output = '
'; $output .= '
'.html_print_image( $original, true, @@ -3295,11 +3819,11 @@ function ui_print_page_header( if ($godmode == true) { $type = 'view'; - $type2 = (empty($breadcrumbs)) ? 'menu_tab_frame_view' : 'menu_tab_frame_view_bc'; + $type2 = 'menu_tab_frame_view'; $separator_class = 'separator'; } else { $type = 'view'; - $type2 = (empty($breadcrumbs)) ? 'menu_tab_frame_view' : 'menu_tab_frame_view_bc'; + $type2 = 'menu_tab_frame_view'; $separator_class = 'separator_view'; } diff --git a/pandora_console/include/functions_update_manager.php b/pandora_console/include/functions_update_manager.php index cc148be7b9..73a654a50d 100755 --- a/pandora_console/include/functions_update_manager.php +++ b/pandora_console/include/functions_update_manager.php @@ -468,7 +468,7 @@ function registration_wiz_modal( __('Cancel'), 'cancel_registration', false, - 'class="ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel" style="color: red; width:100px;"', + 'class="ui-widget ui-state-default ui-corner-all ui-button-text-only sub upd submit-cancel"', true ); $output .= '
'; diff --git a/pandora_console/include/functions_users.php b/pandora_console/include/functions_users.php index 2a29155228..3b4af210d0 100755 --- a/pandora_console/include/functions_users.php +++ b/pandora_console/include/functions_users.php @@ -249,13 +249,13 @@ function groups_combine_acl($acl_group_a, $acl_group_b) /** * Get all the groups a user has reading privileges. * - * @param string User id - * @param string The privilege to evaluate, and it is false then no check ACL. - * @param boolean $returnAllGroup Flag the return group, by default true. - * @param boolean $returnAllColumns Flag to return all columns of groups. - * @param array $id_groups The list of group to scan to bottom child. By default null. - * @param string $keys_field The field of the group used in the array keys. By default ID - * @param boolean $cache Set it to false to not use cache + * @param string $id_user User id + * @param string $privilege The privilege to evaluate, and it is false then no check ACL. + * @param boolean $returnAllGroup Flag the return group, by default true. + * @param boolean $returnAllColumns Flag to return all columns of groups. + * @param array $id_groups The list of group to scan to bottom child. By default null. + * @param string $keys_field The field of the group used in the array keys. By default ID + * @param boolean $cache Set it to false to not use cache * * @return array A list of the groups the user has certain privileges. */ diff --git a/pandora_console/include/functions_visual_map.php b/pandora_console/include/functions_visual_map.php index 680d6e3ce9..ee97467430 100755 --- a/pandora_console/include/functions_visual_map.php +++ b/pandora_console/include/functions_visual_map.php @@ -1966,7 +1966,7 @@ function visual_map_print_item( echo ''; echo ""; echo ''; - echo "
".remove_right_zeros(number_format($stat_agent_cr, 2)).'%
'; + echo "
".remove_right_zeros(number_format($stat_agent_cr, 2)).'%
'; echo "
Critical
"; echo "
".remove_right_zeros(number_format($stat_agent_wa, 2)).'%
'; echo "
Warning
"; diff --git a/pandora_console/include/graphs/flot/pandora.flot.js b/pandora_console/include/graphs/flot/pandora.flot.js index 55cc748261..38b7f75f1c 100644 --- a/pandora_console/include/graphs/flot/pandora.flot.js +++ b/pandora_console/include/graphs/flot/pandora.flot.js @@ -152,12 +152,12 @@ function pandoraFlotPieCustom( colors = colors.split(separator); } var colors_data = [ - "#FC4444", + "#e63c52", "#FFA631", - "#FAD403", + "#f3b200", "#5BB6E5", "#F2919D", - "#80BA27" + "#82b92e" ]; var color = null; for (var i = 0; i < data.length; i++) { @@ -380,12 +380,12 @@ function pandoraFlotHBars( max ) { var colors_data = [ - "#FC4444", + "#e63c52", "#FFA631", - "#FAD403", + "#f3b200", "#5BB6E5", "#F2919D", - "#80BA27" + "#82b92e" ]; values = values.split(separator2); font = font @@ -639,7 +639,7 @@ function pandoraFlotVBars( var colors_data = colors.length > 0 ? colors - : ["#FFA631", "#FC4444", "#FAD403", "#5BB6E5", "#F2919D", "#80BA27"]; + : ["#FFA631", "#e63c52", "#f3b200", "#5BB6E5", "#F2919D", "#82b92e"]; var datas = new Array(); for (i = 0; i < values.length; i++) { @@ -2681,13 +2681,13 @@ function pandoraFlotArea( if (events_data.event_type.search("alert") >= 0) { extra_color = "#FFA631"; } else if (events_data.event_type.search("critical") >= 0) { - extra_color = "#FC4444"; + extra_color = "#e63c52"; } else if (events_data.event_type.search("warning") >= 0) { - extra_color = "#FAD403"; + extra_color = "#f3b200"; } else if (events_data.event_type.search("unknown") >= 0) { - extra_color = "#3BA0FF"; + extra_color = "#4a83f3"; } else if (events_data.event_type.search("normal") >= 0) { - extra_color = "#80BA27"; + extra_color = "#82b92e"; } else { extra_color = "#ffffff"; } diff --git a/pandora_console/include/graphs/functions_d3.php b/pandora_console/include/graphs/functions_d3.php index 129baaa54e..b9f2212b16 100644 --- a/pandora_console/include/graphs/functions_d3.php +++ b/pandora_console/include/graphs/functions_d3.php @@ -190,8 +190,8 @@ function d3_bullet_chart( } .bullet { font: 7px sans-serif; } - .bullet .marker.s0 { stroke: #FC4444; stroke-width: 2px; } - .bullet .marker.s1 { stroke: #FAD403; stroke-width: 2px; } + .bullet .marker.s0 { stroke: #e63c52; stroke-width: 2px; } + .bullet .marker.s1 { stroke: #f3b200; stroke-width: 2px; } .bullet .marker.s2 { stroke: steelblue; stroke-width: 2px; } .bullet .tick line { stroke: #666; stroke-width: .5px; } .bullet .range.s0 { fill: #ddd; } diff --git a/pandora_console/include/graphs/pandora.d3.js b/pandora_console/include/graphs/pandora.d3.js index 427de827e3..49d026ed0f 100644 --- a/pandora_console/include/graphs/pandora.d3.js +++ b/pandora_console/include/graphs/pandora.d3.js @@ -1614,9 +1614,9 @@ function print_phases_donut(recipient, phases) { .insert("path") .style("fill", function(d) { if (d.data.value == 0) { - return "#80BA27"; + return "#82b92e"; } else { - return "#FC4444"; + return "#e63c52"; } }) .attr("class", "slice"); @@ -2849,7 +2849,6 @@ function donutNarrowGraph(colores, width, height, total) { }) .attr("d", arc) .attr("stroke", "white") - .style("stroke-width", 2) .style("fill", function(d) { return color(d.data.key); }); @@ -2873,8 +2872,6 @@ function donutNarrowGraph(colores, width, height, total) { .attr("y", 0 + radius / 10) .attr("class", "text-tooltip") .style("text-anchor", "middle") - .attr("font-weight", "bold") - .style("font-family", "Arial, Verdana") //.attr("fill", "#82b92e") .style("font-size", function(d) { if (normal_status) { diff --git a/pandora_console/include/javascript/buttons.dataTables.min.js b/pandora_console/include/javascript/buttons.dataTables.min.js new file mode 100644 index 0000000000..90389767ac --- /dev/null +++ b/pandora_console/include/javascript/buttons.dataTables.min.js @@ -0,0 +1,5 @@ +/*! + DataTables styling wrapper for Buttons + ©2018 SpryMedia Ltd - datatables.net/license +*/ +(function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net-dt","datatables.net-buttons"],function(a){return c(a,window,document)}):"object"===typeof exports?module.exports=function(a,b){a||(a=window);b&&b.fn.dataTable||(b=require("datatables.net-dt")(a,b).$);b.fn.dataTable.Buttons||require("datatables.net-buttons")(a,b);return c(b,a,a.document)}:c(jQuery,window,document)})(function(c,a,b,d){return c.fn.dataTable}); diff --git a/pandora_console/include/javascript/buttons.print.min.js b/pandora_console/include/javascript/buttons.print.min.js new file mode 100644 index 0000000000..373295a00e --- /dev/null +++ b/pandora_console/include/javascript/buttons.print.min.js @@ -0,0 +1,9 @@ +/*! + Print button for Buttons and DataTables. + 2016 SpryMedia Ltd - datatables.net/license +*/ +(function(c){"function"===typeof define&&define.amd?define(["jquery","datatables.net","datatables.net-buttons"],function(e){return c(e,window,document)}):"object"===typeof exports?module.exports=function(e,a){e||(e=window);a&&a.fn.dataTable||(a=require("datatables.net")(e,a).$);a.fn.dataTable.Buttons||require("datatables.net-buttons")(e,a);return c(a,e,e.document)}:c(jQuery,window,document)})(function(c,e,a,q){var k=c.fn.dataTable,d=a.createElement("a"),p=function(b){d.href=b;b=d.host;-1===b.indexOf("/")&& +0!==d.pathname.indexOf("/")&&(b+="/");return d.protocol+"//"+b+d.pathname+d.search};k.ext.buttons.print={className:"buttons-print",text:function(b){return b.i18n("buttons.print","Print")},action:function(b,a,d,g){b=a.buttons.exportData(c.extend({decodeEntities:!1},g.exportOptions));d=a.buttons.exportInfo(g);var k=a.columns(g.exportOptions.columns).flatten().map(function(b){return a.settings()[0].aoColumns[a.column(b).index()].sClass}).toArray(),m=function(b,a){for(var d="",c=0,e=b.length;c"+(null===b[c]||b[c]===q?"":b[c])+"";return d+""},h='';g.header&&(h+=""+m(b.header,"th")+"");h+="";for(var n=0,r=b.body.length;n";g.footer&&b.footer&&(h+=""+m(b.footer,"th")+"");h+="
";var f=e.open("","");f.document.close();var l=""+d.title+"";c("style, link").each(function(){var b=l,a=c(this).clone()[0]; +"link"===a.nodeName.toLowerCase()&&(a.href=p(a.href));l=b+a.outerHTML});try{f.document.head.innerHTML=l}catch(t){c(f.document.head).html(l)}f.document.body.innerHTML="

"+d.title+"

"+(d.messageTop||"")+"
"+h+"
"+(d.messageBottom||"")+"
";c(f.document.body).addClass("dt-print-view");c("img",f.document.body).each(function(b,a){a.setAttribute("src",p(a.getAttribute("src")))});g.customize&&g.customize(f,g,a);b=function(){g.autoPrint&&(f.print(),f.close())};navigator.userAgent.match(/Trident\/\d.\d/)? +b():f.setTimeout(b,1E3)},title:"*",messageTop:"*",messageBottom:"*",exportOptions:{},header:!0,footer:!1,autoPrint:!0,customize:null};return k.Buttons}); diff --git a/pandora_console/include/javascript/datatables.min.js b/pandora_console/include/javascript/datatables.min.js index ce584c1da6..7587a5921d 100644 --- a/pandora_console/include/javascript/datatables.min.js +++ b/pandora_console/include/javascript/datatables.min.js @@ -4,30 +4,12 @@ * * To rebuild or modify this file with the latest versions of the included * software please visit: - * https://datatables.net/download/#ju-1.12.1/jq-3.3.1/dt-1.10.18 + * https://datatables.net/download/#dt/dt-1.10.18 * * Included libraries: - * jQuery UI 1.12.1, jQuery 3 3.3.1, DataTables 1.10.18 + * DataTables 1.10.18 */ -/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w(" diff --git a/pandora_console/operation/agentes/status_events.php b/pandora_console/operation/agentes/status_events.php index 5e6e060f82..df30d75dda 100755 --- a/pandora_console/operation/agentes/status_events.php +++ b/pandora_console/operation/agentes/status_events.php @@ -25,6 +25,7 @@ ui_toggle( "
".html_print_image('images/spinner.gif', true).'
', __('Latest events for this agent'), __('Latest events for this agent'), + '', false, false, '', diff --git a/pandora_console/operation/agentes/status_monitor.php b/pandora_console/operation/agentes/status_monitor.php index 6b948faf8a..0f7257663a 100644 --- a/pandora_console/operation/agentes/status_monitor.php +++ b/pandora_console/operation/agentes/status_monitor.php @@ -421,7 +421,7 @@ if (!is_metaconsole()) { $table->data[0][5] = html_print_select($rows_select, 'modulegroup', $modulegroup, '', __('All'), -1, true, false, true, '', false, 'width: 120px;'); -$table->rowspan[0][6] = 2; +$table->rowspan[0][6] = 3; $table->data[0][6] = html_print_submit_button( __('Show'), 'uptbutton', @@ -705,13 +705,14 @@ if (is_metaconsole()) { html_print_table($table_custom_fields, true), __('Advanced Options'), '', + '', true, true ); $filters .= html_print_table($table, true); $filters .= ''; - ui_toggle($filters, __('Show Options'), '', false); + ui_toggle($filters, __('Show Options'), '', '', false); } else { $table->colspan[3][0] = 7; $table->cellstyle[3][0] = 'padding-left: 10px;'; @@ -722,8 +723,12 @@ if (is_metaconsole()) { ), __('Agent custom fields'), '', + '', true, - true + true, + '', + 'white-box-content', + 'white_table_graph' ); $filters .= html_print_table($table, true); diff --git a/pandora_console/operation/agentes/tactical.php b/pandora_console/operation/agentes/tactical.php index 10e4ff5736..1a54e84afc 100755 --- a/pandora_console/operation/agentes/tactical.php +++ b/pandora_console/operation/agentes/tactical.php @@ -116,13 +116,13 @@ if (!empty($all_data)) { } echo ''; -echo ''; echo '
'; +echo ''; // --------------------------------------------------------------------- // The status horizontal bars (Global health, Monitor sanity... // --------------------------------------------------------------------- $table = new stdClass(); $table->width = '100%'; -$table->class = 'info_table no-td-borders'; +$table->class = 'info_table no-td-borders td-bg-white'; $table->cellpadding = 2; $table->cellspacing = 2; $table->border = 0; @@ -130,7 +130,6 @@ $table->head = []; $table->data = []; $table->style = []; -$table->head[0] = ''.__('Report of State').''; $stats = reporting_get_stats_indicators($data, 120, 10, false); $status = ''; foreach ($stats as $stat) { @@ -166,7 +165,13 @@ if ($is_admin) { $table->rowclass[] = ''; } -html_print_table($table); +ui_toggle( + html_print_table($table, true), + __('Report of State'), + '', + '', + false +); echo ''; // Left column @@ -190,7 +195,8 @@ if (check_acl($config['id_user'], 0, 'ER')) { ui_toggle( $events, __('Latest events'), - false, + '', + '', false ); } @@ -210,7 +216,15 @@ $out = '
'.__('Event graph by agent').''.html_print_image('images/spinner.gif', true, ['id' => 'spinner_graphic_event_group']).''; $out .= '
'; -echo $out; + + +ui_toggle( + $out, + __('Event graphs'), + '', + '', + false +); echo '
'; diff --git a/pandora_console/operation/agentes/ver_agente.php b/pandora_console/operation/agentes/ver_agente.php index 9bed24a3db..5f7f29f916 100644 --- a/pandora_console/operation/agentes/ver_agente.php +++ b/pandora_console/operation/agentes/ver_agente.php @@ -62,6 +62,36 @@ if (is_ajax()) { $agent_alias = get_parameter('alias', ''); $agents_inserted = get_parameter('agents_inserted', []); $id_group = (int) get_parameter('id_group'); + + $refresh_contact = get_parameter('refresh_contact', 0); + + if ($refresh_contact) { + $id_agente = get_parameter('id_agente', 0); + if ($id_agente > 0) { + $d = db_get_row( + 'tagente', + 'id_agente', + $id_agente + ); + + $progress = agents_get_next_contact($id_agente); + $last_contact = floor(($d['intervalo'] * (100 - $progress) / 100)); + + if ($progress < 0 || $progress > 100) { + $progress = 100; + } + + echo json_encode( + [ + 'progress' => $progress, + 'last_contact' => $last_contact, + ] + ); + } + + return; + } + if ($get_agents_group_json) { $id_group = (int) get_parameter('id_group'); $recursion = (bool) get_parameter('recursion'); diff --git a/pandora_console/operation/events/event_statistics.php b/pandora_console/operation/events/event_statistics.php index 437ec0f47c..a4a5b1632a 100644 --- a/pandora_console/operation/events/event_statistics.php +++ b/pandora_console/operation/events/event_statistics.php @@ -1,30 +1,48 @@ '; diff --git a/pandora_console/operation/events/events.build_query.php b/pandora_console/operation/events/events.build_query.php index f915a5093b..7da35b6977 100755 --- a/pandora_console/operation/events/events.build_query.php +++ b/pandora_console/operation/events/events.build_query.php @@ -142,41 +142,43 @@ switch ($status) { break; } - -$events_wi_cdata = db_get_all_rows_sql('SELECT id_evento,custom_data from tevento WHERE custom_data != ""'); -$count_events = 0; -$events_wi_cdata_id = 'OR id_evento IN ('; -if ($events_wi_cdata === false) { - $events_wi_cdata = []; -} - -foreach ($events_wi_cdata as $key => $value) { - $needle = base64_decode($value['custom_data']); - if (($needle != '') && ($search != '')) { - if (strpos(strtolower($needle), strtolower($search)) != false) { - $events_wi_cdata_id .= $value['id_evento']; - $count_events++; - } - } - - if ($value !== end($events_wi_cdata) && $count_events > 0) { - $events_wi_cdata_id .= ','; - $events_wi_cdata_id = str_replace(',,', ',', $events_wi_cdata_id); - } -} - -$events_wi_cdata_id .= ')'; - -$events_wi_cdata_id = str_replace(',)', ')', $events_wi_cdata_id); - -if ($count_events == 0) { - $events_wi_cdata_id = ''; -} - +/* + * Never use things like this. + * + * $events_wi_cdata = db_get_all_rows_sql('SELECT id_evento,custom_data from tevento WHERE custom_data != ""'); + * $count_events = 0; + * $events_wi_cdata_id = 'OR id_evento IN ('; + * if ($events_wi_cdata === false) { + * $events_wi_cdata = []; + * } + * + * foreach ($events_wi_cdata as $key => $value) { + * $needle = base64_decode($value['custom_data']); + * if (($needle != '') && ($search != '')) { + * if (strpos(strtolower($needle), strtolower($search)) != false) { + * $events_wi_cdata_id .= $value['id_evento']; + * $count_events++; + * } + * } + * + * if ($value !== end($events_wi_cdata) && $count_events > 0) { + * $events_wi_cdata_id .= ','; + * $events_wi_cdata_id = str_replace(',,', ',', $events_wi_cdata_id); + * } + * } + * + * $events_wi_cdata_id .= ')'; + * + * $events_wi_cdata_id = str_replace(',)', ')', $events_wi_cdata_id); + * + * if ($count_events == 0) { + * $events_wi_cdata_id = ''; + * } + */ if ($search != '') { $filter_resume['free_search'] = $search; - $sql_post .= " AND (evento LIKE '%".$search."%' OR id_evento LIKE '%$search%' ".$events_wi_cdata_id.')'; + $sql_post .= " AND (evento LIKE '%".$search."%' OR id_evento LIKE '%$search%' )"; } if ($event_type != '') { diff --git a/pandora_console/operation/events/events.build_table.php b/pandora_console/operation/events/events.build_table.php index 3e112f3fb8..a07ec2a703 100644 --- a/pandora_console/operation/events/events.build_table.php +++ b/pandora_console/operation/events/events.build_table.php @@ -29,7 +29,7 @@ $table->id = 'eventtable'; $table->cellpadding = 4; $table->cellspacing = 4; if (!isset($table->class)) { - $table->class = 'databox data'; + $table->class = 'info_table'; } $table->head = []; @@ -91,11 +91,11 @@ if ($group_rep == 2) { if ($res['event_type'] == 'alert_fired') { $table->rowstyle[$key] = 'background: #FFA631;'; } else if ($res['event_type'] == 'going_up_critical' || $res['event_type'] == 'going_down_critical') { - $table->rowstyle[$key] = 'background: #FC4444;'; + $table->rowstyle[$key] = 'background: #e63c52;'; } else if ($res['event_type'] == 'going_up_warning' || $res['event_type'] == 'going_down_warning') { - $table->rowstyle[$key] = 'background: #FAD403;'; + $table->rowstyle[$key] = 'background: #f3b200;'; } else if ($res['event_type'] == 'going_up_normal' || $res['event_type'] == 'going_down_normal') { - $table->rowstyle[$key] = 'background: #80BA27;'; + $table->rowstyle[$key] = 'background: #82b92e;'; } else if ($res['event_type'] == 'going_unknown') { $table->rowstyle[$key] = 'background: #B2B2B2;'; } @@ -990,12 +990,12 @@ if ($group_rep == 2) { html_print_button(__('Execute event response'), 'submit_event_response', false, 'execute_event_response(true);', 'class="sub next"'); echo "'; echo ''; - echo '
'; - // Floating menu - End. - ui_require_jquery_file('countdown'); } // Error div for ajax messages. @@ -627,570 +605,1513 @@ echo "
"; echo '
'; -if (($section == 'validate') && ($ids[0] == -1)) { - $section = 'list'; - ui_print_error_message(__('No events selected')); -} - -// Process validation (pass array or single value). -if ($validate) { - $ids = get_parameter('eventid', -1); - $comment = get_parameter('comment', ''); - $new_status = get_parameter('select_validate', 1); - $ids = explode(',', $ids); - $standby_alert = (bool) get_parameter('standby-alert'); - - // Avoid to re-set inprocess events. - if ($new_status == 2) { - foreach ($ids as $key => $id) { - $event = events_get_event($id); - if ($event['estado'] == 2) { - unset($ids[$key]); - } - } - } - - if (isset($ids[0]) && $ids[0] != -1) { - $return = events_change_status($ids, $new_status, $meta); - - if ($new_status == 1) { - ui_print_result_message( - $return, - __('Successfully validated'), - __('Could not be validated') +// Controls. +if (is_metaconsole() !== true) { + if (isset($config['event_replication']) + && $config['event_replication'] == 1 + ) { + if ($config['show_events_in_local'] == 0) { + db_pandora_audit( + 'ACL Violation', + 'Trying to access event viewer. View disabled due event replication.' ); - } else if ($new_status == 2) { - ui_print_result_message( - $return, - __('Successfully set in process'), - __('Could not be set in process') + ui_print_info_message( + [ + 'message' => __( + 'Event viewer is disabled due event replication. For more information, please contact with the administrator' + ), + 'no_close' => true, + ] ); + return; + } else { + $readonly = true; } } } -// Process deletion (pass array or single value). -if ($delete) { - $ids = (array) get_parameter('validate_ids', -1); +/* + * Load user default form. + */ - // Discard deleting in progress events. - $in_process_status = db_get_all_rows_sql( - ' - SELECT id_evento - FROM tevento - WHERE estado=2' +$user_filter = db_get_row_sql( + sprintf( + 'SELECT f.id_filter, f.id_name + FROM tevent_filter f + INNER JOIN tusuario u + ON u.default_event_filter=f.id_filter + WHERE u.id_user = "%s" ', + $config['id_user'] + ) +); +if ($user_filter !== false) { + $filter = events_get_event_filter($user_filter['id_filter']); + if ($filter !== false) { + $id_group = $filter['id_group']; + $event_type = $filter['event_type']; + $severity = $filter['severity']; + $status = $filter['status']; + $search = $filter['search']; + $text_agent = $filter['text_agent']; + $id_agent = $filter['id_agent']; + $id_agent_module = $filter['id_agent_module']; + $pagination = $filter['pagination']; + $event_view_hr = $filter['event_view_hr']; + $id_user_ack = $filter['id_user_ack']; + $group_rep = $filter['group_rep']; + $tag_with = $filter['tag_with']; + $tag_without = $filter['tag_without']; + $filter_only_alert = $filter['filter_only_alert']; + $id_group_filter = $filter['id_group_filter']; + $date_from = $filter['date_from']; + $date_to = $filter['date_to']; + $source = $filter['source']; + $id_extra = $filter['id_extra']; + $user_comment = $filter['user_comment']; + } +} + +/* + * Load filter form. + */ + +// Group. +$user_groups_array = users_get_groups_for_select( + $config['id_user'], + $access, + true, + true, + false +); +$data = html_print_select( + $user_groups_array, + 'id_group_filter', + $id_group_filter, + '', + '', + 0, + true, + false, + false, + 'w130' +); +$in = '
'; +$in .= $data.'
'; +$inputs[] = $in; + +// Event type. +$types = get_event_types(); +$types['not_normal'] = __('Not normal'); +$data = html_print_select( + $types, + 'event_type', + $event_type, + '', + __('All'), + '', + true +); +$in = '
'; +$in .= $data.'
'; +$inputs[] = $in; + +// Criticity - severity. +$severity_select .= html_print_select( + get_priorities(), + 'severity', + $severity, + '', + __('All'), + '-1', + true, + false, + false +); +$in = '
'; +$in .= $severity_select.'
'; +$inputs[] = $in; + +// Event status. +$data = html_print_select( + events_get_all_status(), + 'status', + $status, + '', + '', + '', + true +); +$in = '
'; +$in .= $data.'
'; +$inputs[] = $in; + +// Max hours old. +$data = html_print_input_text( + 'event_view_hr', + $event_view_hr, + '', + 5, + 255, + true +); +$in = '
'; +$in .= $data.'
'; +$inputs[] = $in; + +// Duplicates group { events | agents }. +$data = html_print_select( + [ + 0 => __('All events'), + 1 => __('Group events'), + 2 => __('Group agents'), + ], + 'group_rep', + $group_rep, + '', + '', + 0, + true +); +$in = '
'; +$in .= $data.'
'; +$inputs[] = $in; + +// Free search. +$data = html_print_input_text('search', $search, '', '', 255, true); +$in = '
'; +$in .= $data.'
'; +$inputs[] = $in; + +$buttons = []; + +$buttons[] = [ + 'id' => 'load-filter', + 'class' => 'float-left margin-right-2 sub config', + 'text' => __('Load filter'), + 'onclick' => '', +]; + +$buttons[] = [ + 'id' => 'save-filter', + 'class' => 'float-left margin-right-2 sub wand', + 'text' => __('Save filter'), + 'onclick' => '', +]; + +/* + * Advanced filter. + */ + +$adv_inputs = []; + + +// Source. +$data = html_print_input_text('source', $source, '', '', 255, true); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + + +// Extra ID. +$data = html_print_input_text('id_extra', $id_extra, '', 11, 255, true); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// Comment. +$data = html_print_input_text( + 'user_comment', + $user_comment, + '', + '', + 255, + true +); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// Agent search. +$params = []; +$params['show_helptip'] = true; +$params['input_name'] = 'text_agent'; +$params['value'] = $text_agent; +$params['return'] = true; + +if ($meta) { + $params['javascript_page'] = 'enterprise/meta/include/ajax/events.ajax'; +} + +$params['print_hidden_input_idagent'] = true; +$params['hidden_input_idagent_name'] = 'id_agent'; +$params['hidden_input_idagent_value'] = $id_agent; +$params['size'] = ''; + +$data = ui_print_agent_autocomplete_input($params); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// Mixed. Metaconsole => server, Console => module. +if (is_metaconsole()) { + $title = __('Server'); + $data = html_print_select_from_sql( + 'SELECT id, server_name FROM tmetaconsole_setup', + 'server_id', + $server_id, + 'script', + __('All'), + '0', + true + ); +} else { + $title = __('Module search'); + $data = html_print_autocomplete_modules( + 'module_search', + $text_module, + false, + true, + '', + [], + true, + $id_agent_module, + '' + ); +} + +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// User ack. +$user_users = users_get_user_users( + $config['id_user'], + $access, + users_can_manage_group_all() +); + +$data = html_print_select( + $user_users, + 'id_user_ack', + $id_user_ack, + '', + __('Any'), + 0, + true +); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// Only alert events. +$data = html_print_select( + [ + '-1' => __('All'), + '0' => __('Filter alert events'), + '1' => __('Only alert events'), + ], + 'filter_only_alert', + $filter_only_alert, + '', + '', + '', + true +); +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// Gap. +$adv_inputs[] = '
'; + +// Date from. +$data = html_print_input_text( + 'date_from', + $date_from, + '', + false, + 10, + true, + // Disabled. + false, + // Required. + false, + // Function. + '', + // Class. + '', + // OnChange. + '', + // Autocomplete. + 'off' +); +$in = '
'; +$in .= '
'; +$in .= $data.'
'; + +// Time from. +$data = html_print_input_text( + 'time_from', + $time_from, + '', + false, + 10, + true, + // Disabled. + false, + // Required. + false, + // Function. + '', + // Class. + '', + // OnChange. + '', + // Autocomplete. + 'off' +); +$in .= '
'; +$in .= $data.'
'; +$in .= '
'; +$adv_inputs[] = $in; + +// Date to. +$data = html_print_input_text( + 'date_to', + $date_to, + '', + false, + 10, + true, + // Disabled. + false, + // Required. + false, + // Function. + '', + // Class. + '', + // OnChange. + '', + // Autocomplete. + 'off' +); +$in = '
'; +$in .= '
'; +$in .= $data.'
'; + +// Time to. +$data = html_print_input_text( + 'time_to', + $time_to, + '', + false, + 10, + true, + // Disabled. + false, + // Required. + false, + // Function. + '', + // Class. + '', + // OnChange. + '', + // Autocomplete. + 'off' +); +$in .= '
'; +$in .= $data.'
'; +$in .= '
'; +$adv_inputs[] = $in; + + +// Tags. +if (is_metaconsole()) { + $data = '
'.__('Events with following tags').''.html_print_table($tabletags_with, true).'
'; + $data .= '
'.__('Events without following tags').''.html_print_table($tabletags_without, true).'
'; +} else { + $data = '
'.__('Events with following tags').''.html_print_table($tabletags_with, true).'
'; + $data .= '
'.__('Events without following tags').''.html_print_table($tabletags_without, true).'
'; +} + +$in = '
'; +$in .= $data.'
'; +$adv_inputs[] = $in; + +// Load view. +$adv_filter = join('', $adv_inputs); +$filter = join('', $inputs); +$filter .= ui_toggle( + $adv_filter, + __('Advanced options'), + '', + '', + true, + true, + 'white_box white_box_opened', + 'no-border flex-row' +); + +try { + $checkbox_all = html_print_checkbox( + 'all_validate_box', + 1, + false, + true ); - foreach ($in_process_status as $val) { - if (($key = array_search($val['id_evento'], $ids)) !== false) { - unset($ids[$key]); - } + $default_fields = [ + [ + 'text' => 'evento', + 'class' => 'mw120px', + ], + 'id_evento', + // 'id_agente', + // 'id_usuario', + // 'id_grupo', + // 'estado', + 'agent_name', + 'timestamp', + // 'utimestamp', + // 'event_type', + // 'id_agentmodule', + // 'id_alert_am', + 'event_type', + // 'user_comment', + // 'tags', + // 'source', + // 'id_extra', + // 'critical_instructions', + // 'warning_instructions', + // 'unknown_instructions', + // 'owner_user', + // 'ack_utimestamp', + // 'custom_data', + // 'data', + // 'module_status', + // 'similar_ids', + // 'event_rep', + // 'timestamp_rep', + // 'timestamp_rep_min', + // 'module_name', + [ + 'text' => 'options', + 'class' => 'action_buttons w120px', + ],[ + 'text' => 'm', + 'extra' => $checkbox_all, + 'class' => 'mw120px', + ], + ]; + $fields = explode(',', $config['event_fields']); + + // Always check something is shown. + if (empty($fields)) { + $fields = $default_fields; } - if ($ids[0] != -1) { - $return = events_delete_event($ids, ($group_rep == 1), $meta); - ui_print_result_message( - $return, - __('Successfully deleted'), - __('Could not be deleted') - ); + + $evento_id = array_search('evento', $fields); + if ($evento_id !== false) { + $fields[$evento_id] = [ + 'text' => 'evento', + 'class' => 'mw250px', + ]; } - include_once $config['homedir'].'/operation/events/events_list.php'; -} else { - switch ($section) { - case 'list': - case 'history': - include_once $config['homedir'].'/operation/events/events_list.php'; + // Always add options column. + $fields = array_merge( + $fields, + [ + [ + 'text' => 'options', + 'class' => 'action_buttons mw120px', + ],[ + 'text' => 'm', + 'extra' => $checkbox_all, + 'class' => 'w20px no-text-imp', + ], + ] + ); + + // Get column names. + $column_names = events_get_column_names($fields); + + // Open current filter quick reference. + $active_filters_div = '
'; + + // Current filter. + $active_filters_div .= '
'; + $active_filters_div .= '
'.__('Current filter').'
'; + $active_filters_div .= '
'; + if ($user_filter !== false) { + $active_filters_div .= io_safe_output($user_filter['id_name']); + } else { + $active_filters_div .= __('Not set.'); + } + + $active_filters_div .= '
'; + $active_filters_div .= '
'; + + // Event status. + $active_filters_div .= '
'; + $active_filters_div .= '
'.__('Event status').'
'; + $active_filters_div .= '
'; + switch ($status) { + case EVENT_ALL: + default: + $active_filters_div .= __('Any status.'); + break; + + case EVENT_NEW: + $active_filters_div .= __('New events.'); + break; + + case EVENT_VALIDATE: + $active_filters_div .= __('Validated.'); + break; + + case EVENT_PROCESS: + $active_filters_div .= __('In proccess.'); + break; + + case EVENT_NO_VALIDATED: + $active_filters_div .= __('Not validated.'); break; } + + $active_filters_div .= '
'; + $active_filters_div .= '
'; + + // Max. hours old. + $active_filters_div .= '
'; + $active_filters_div .= '
'.__('Max. hours old').'
'; + $active_filters_div .= '
'; + if ($event_view_hr == 0) { + $active_filters_div .= __('Any time.'); + } else if ($event_view_hr == 1) { + $active_filters_div .= __('Last hour.'); + } else if ($event_view_hr > 1) { + $active_filters_div .= __('Last %d hours.', $event_view_hr); + } + + $active_filters_div .= '
'; + $active_filters_div .= '
'; + + // Duplicates. + $active_filters_div .= '
'; + $active_filters_div .= '
'.__('Duplicated').'
'; + $active_filters_div .= '
'; + if ($group_rep == 0) { + $active_filters_div .= __('All events.'); + } else if ($group_rep == 1) { + $active_filters_div .= __('Group events'); + } else if ($group_rep == 2) { + $active_filters_div .= __('Group agents.'); + } + + $active_filters_div .= '
'; + $active_filters_div .= '
'; + + // Close. + $active_filters_div .= '
'; + + $table_id = 'events'; + + // Print datatable. + ui_print_datatable( + [ + 'id' => $table_id, + 'class' => 'info_table events', + 'style' => 'width: 100%;', + 'ajax_url' => 'operation/events/events', + 'ajax_data' => ['get_events' => 1], + 'form' => [ + 'id' => 'events_form', + 'class' => 'flex-row', + 'html' => $filter, + 'inputs' => [], + 'extra_buttons' => $buttons, + ], + 'extra_html' => $active_filters_div, + 'pagination_options' => [ + [ + $config['block_size'], + 10, + 25, + 100, + 200, + 500, + 1000, + -1, + ], + [ + $config['block_size'], + 10, + 25, + 100, + 200, + 500, + 1000, + 'All', + ], + ], + 'order' => [ + 'field' => 'timestamp', + 'direction' => 'desc', + ], + 'column_names' => $column_names, + 'columns' => $fields, + 'no_sortable_columns' => [ + -1, + -2, + ], + 'ajax_postprocess' => 'process_datatables_item(item)', + 'drawCallback' => 'process_datatables_callback(this, settings)', + ] + ); +} catch (Exception $e) { + ui_print_error_message($e->getMessage()); } +// Event responses. +$sql_event_resp = "SELECT id, name FROM tevent_response WHERE type LIKE 'command'"; +$event_responses = db_get_all_rows_sql($sql_event_resp); + +if (check_acl($config['id_user'], 0, 'EW') == 1 && !$readonly) { + $array_events_actions['in_progress_selected'] = __('In progress selected'); + $array_events_actions['validate_selected'] = __('Validate selected'); +} + +if (check_acl($config['id_user'], 0, 'EM') == 1 && !$readonly) { + $array_events_actions['delete_selected'] = __('Delete selected'); +} + +foreach ($event_responses as $val) { + $array_events_actions[$val['id']] = $val['name']; +} + +if ($config['event_replication'] != 1) { + echo '
'; + echo '
'; + echo ''; + html_print_select($array_events_actions, 'response_id', '', '', '', 0, false, false, false); + echo '  '; + html_print_button(__('Execute event response'), 'submit_event_response', false, 'execute_event_response(true);', 'class="sub next"'); + echo "'; + echo '
'; + echo ''; + echo ''; + echo '
'; +} + +// Close viewer. +enterprise_hook('close_meta_frame'); + +// Datepicker requirements. +ui_require_css_file('datepicker'); +ui_include_time_picker(); +ui_require_jquery_file( + 'ui.datepicker-'.get_user_language(), + 'include/javascript/i18n/' +); + +// End. Load required JS. +html_print_input_hidden('meta', (int) is_metaconsole()); +html_print_input_hidden('history', (int) $history); +html_print_input_hidden('filterid', $is_filter); +html_print_input_hidden( + 'ajax_file', + ui_get_full_url('ajax.php', false, false, false) +); + +// AJAX call options responses. echo "
"; echo "
"; echo "
"; -ui_require_jquery_file('bgiframe'); -ui_require_javascript_file('pandora_events'); -enterprise_hook('close_meta_frame'); -ui_require_javascript_file('wz_jsgraphics'); -ui_require_javascript_file('pandora_visual_console'); - -$ignored_params['refresh'] = ''; +// Load filter div for dialog. +echo ''; +echo ''; ?> - \ No newline at end of file + diff --git a/pandora_console/operation/events/events_list.php b/pandora_console/operation/events/events_list.php index 8333ca5b0d..298310a845 100644 --- a/pandora_console/operation/events/events_list.php +++ b/pandora_console/operation/events/events_list.php @@ -992,6 +992,7 @@ $data[0] = ui_toggle( html_print_table($table_advanced, true), __('Advanced options'), '', + '', true, true ); diff --git a/pandora_console/operation/reporting/custom_reporting.php b/pandora_console/operation/reporting/custom_reporting.php index a5267a21bd..68ff8c80c0 100644 --- a/pandora_console/operation/reporting/custom_reporting.php +++ b/pandora_console/operation/reporting/custom_reporting.php @@ -36,7 +36,7 @@ $table->head[1] = __('Description'); $table->head[2] = __('HTML'); $table->head[3] = __('XML'); -enterprise_hook('load_custom_reporting_1'); +enterprise_hook('load_custom_reporting_1', [$table]); $table->align = []; $table->align[2] = 'center'; diff --git a/pandora_console/operation/reporting/reporting_viewer.php b/pandora_console/operation/reporting/reporting_viewer.php index 5e9dda1e57..e8431ddeb2 100755 --- a/pandora_console/operation/reporting/reporting_viewer.php +++ b/pandora_console/operation/reporting/reporting_viewer.php @@ -169,12 +169,12 @@ $table->rowspan[0][0] = 2; // Set initial conditions for these controls, later will be modified by javascript if (!$enable_init_date) { $table->style[1] = 'display: none'; - $table->style[2] = 'display: ""'; + $table->style[2] = 'display: flex;align-items: baseline;'; $display_to = 'none'; $display_item = ''; } else { - $table->style[1] = 'display: ""'; - $table->style[2] = 'display: ""'; + $table->style[1] = 'display: "block"'; + $table->style[2] = 'display: flex;align-items: baseline;'; $display_to = ''; $display_item = 'none'; } @@ -210,11 +210,11 @@ if ($html_enterprise !== ENTERPRISE_NOT_HOOK) { $table->data[0][1] .= '
'; -$table->data[1][1] = '
'.__('From').':
'; +$table->data[1][1] = '
'.__('From').':
'; $table->data[1][1] .= html_print_input_text('date_init', $date_init, '', 12, 10, true).' '; $table->data[1][1] .= html_print_input_text('time_init', $time_init, '', 10, 7, true).' '; -$table->data[1][2] = '
'.__('Items period before').':
'; -$table->data[1][2] .= '
'.__('to').':
'; +$table->data[1][2] = '
'.__('Items period before').':
'; +$table->data[1][2] .= '
'.__('to').':
'; $table->data[1][2] .= html_print_input_text('date', $date, '', 12, 10, true).' '; $table->data[1][2] .= html_print_input_text('time', $time, '', 10, 7, true).' '; $table->data[1][2] .= html_print_submit_button(__('Update'), 'date_submit', false, 'class="sub next"', true); diff --git a/pandora_console/operation/search_reports.php b/pandora_console/operation/search_reports.php index 668f6f717b..a3b95357a3 100755 --- a/pandora_console/operation/search_reports.php +++ b/pandora_console/operation/search_reports.php @@ -35,7 +35,7 @@ if ($reports === false || !$searchReports) { $table->head[1] = __('Description'); $table->head[2] = __('HTML'); $table->head[3] = __('XML'); - enterprise_hook('load_custom_reporting_1'); + enterprise_hook('load_custom_reporting_1', [$table]); $table->align = []; $table->align[2] = 'center'; diff --git a/pandora_console/operation/snmpconsole/snmp_view.php b/pandora_console/operation/snmpconsole/snmp_view.php index cb72a91ecd..c7f69b4109 100755 --- a/pandora_console/operation/snmpconsole/snmp_view.php +++ b/pandora_console/operation/snmpconsole/snmp_view.php @@ -778,7 +778,7 @@ $table->headstyle[7] = 'text-align: center'; $table->head[8] = __('Action'); $table->align[8] = 'center'; $table->size[8] = '10%'; -$table->headstyle[8] = 'text-align: center'; +$table->headstyle[8] = 'min-width: 125px;text-align: center'; $table->head[9] = html_print_checkbox_extended( 'allbox', diff --git a/pandora_console/operation/visual_console/public_view.php b/pandora_console/operation/visual_console/public_view.php index 90fe29a545..1122daf285 100644 --- a/pandora_console/operation/visual_console/public_view.php +++ b/pandora_console/operation/visual_console/public_view.php @@ -198,6 +198,14 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( } } } + + // Add the datetime when the item was received. + var receivedAt = new Date(); + items.map(function(item) { + item["receivedAt"] = receivedAt; + return item; + }); + var visualConsoleManager = createVisualConsole( container, props, diff --git a/pandora_console/operation/visual_console/view.php b/pandora_console/operation/visual_console/view.php index 9c79ba7742..61633b1fc6 100644 --- a/pandora_console/operation/visual_console/view.php +++ b/pandora_console/operation/visual_console/view.php @@ -155,6 +155,16 @@ if (!is_metaconsole()) { html_print_input_hidden('metaconsole', 1); } +if ($pure === false) { + echo '
'; + echo ''.__('Move and resize mode').''; + echo ''; + echo html_print_checkbox_switch('edit-mode', 1, false, true); + echo ''; + echo '
'; + echo '
'; +} + echo '
'; if ($pure === true) { @@ -306,6 +316,14 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( } } } + + // Add the datetime when the item was received. + var receivedAt = new Date(); + items.map(function(item) { + item["receivedAt"] = receivedAt; + return item; + }); + var visualConsoleManager = createVisualConsole( container, props, @@ -315,6 +333,17 @@ $visualConsoleItems = VisualConsole::getItemsFromDB( handleUpdate ); + // Enable/disable the edition mode. + $('input[name=edit-mode]').change(function(event) { + if ($(this).prop('checked')) { + visualConsoleManager.visualConsole.enableEditMode(); + visualConsoleManager.changeUpdateInterval(0); + } else { + visualConsoleManager.visualConsole.disableEditMode(); + visualConsoleManager.changeUpdateInterval(); // To ms. + } + }); + // Update the data fetch interval. $('select#vc-refr').change(function(event) { var refr = Number.parseInt(event.target.value); diff --git a/pandora_console/pandora_console.redhat.spec b/pandora_console/pandora_console.redhat.spec index 494b09e337..a181733e7d 100644 --- a/pandora_console/pandora_console.redhat.spec +++ b/pandora_console/pandora_console.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.735 -%define release 190614 +%define release 190625 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.rhel7.spec b/pandora_console/pandora_console.rhel7.spec index 4b3b40fe26..2bf8d0c433 100644 --- a/pandora_console/pandora_console.rhel7.spec +++ b/pandora_console/pandora_console.rhel7.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.735 -%define release 190614 +%define release 190625 # User and Group under which Apache is running %define httpd_name httpd diff --git a/pandora_console/pandora_console.spec b/pandora_console/pandora_console.spec index 4e357335f2..14a500325d 100644 --- a/pandora_console/pandora_console.spec +++ b/pandora_console/pandora_console.spec @@ -3,7 +3,7 @@ # %define name pandorafms_console %define version 7.0NG.735 -%define release 190614 +%define release 190625 %define httpd_name httpd # User and Group under which Apache is running %define httpd_name apache2 diff --git a/pandora_server/DEBIAN/control b/pandora_server/DEBIAN/control index 4bd51f6c75..906e793d8e 100644 --- a/pandora_server/DEBIAN/control +++ b/pandora_server/DEBIAN/control @@ -1,5 +1,5 @@ package: pandorafms-server -Version: 7.0NG.735-190614 +Version: 7.0NG.735-190625 Architecture: all Priority: optional Section: admin diff --git a/pandora_server/DEBIAN/make_deb_package.sh b/pandora_server/DEBIAN/make_deb_package.sh index b3c32f50d5..7fff838f35 100644 --- a/pandora_server/DEBIAN/make_deb_package.sh +++ b/pandora_server/DEBIAN/make_deb_package.sh @@ -14,7 +14,7 @@ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. -pandora_version="7.0NG.735-190614" +pandora_version="7.0NG.735-190625" package_cpan=0 package_pandora=1 diff --git a/pandora_server/lib/PandoraFMS/Config.pm b/pandora_server/lib/PandoraFMS/Config.pm index 4d77d2c109..60b50d2552 100644 --- a/pandora_server/lib/PandoraFMS/Config.pm +++ b/pandora_server/lib/PandoraFMS/Config.pm @@ -45,7 +45,7 @@ our @EXPORT = qw( # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.735"; -my $pandora_build = "190614"; +my $pandora_build = "190625"; our $VERSION = $pandora_version." ".$pandora_build; # Setup hash diff --git a/pandora_server/lib/PandoraFMS/Core.pm b/pandora_server/lib/PandoraFMS/Core.pm index 548ddafd06..ee66b5ca68 100644 --- a/pandora_server/lib/PandoraFMS/Core.pm +++ b/pandora_server/lib/PandoraFMS/Core.pm @@ -3352,7 +3352,7 @@ sub pandora_event ($$$$$$$$$$;$$$$$$$$$$$) { # Validate events with the same event id if (defined ($id_extra) && $id_extra ne '') { logger($pa_config, "Updating events with extended id '$id_extra'.", 10); - db_do ($dbh, 'UPDATE ' . $event_table . ' SET estado = 1, ack_utimestamp = ? WHERE estado = 0 AND id_extra=?', $utimestamp, $id_extra); + db_do ($dbh, 'UPDATE ' . $event_table . ' SET estado = 1, ack_utimestamp = ? WHERE estado IN (0,2) AND id_extra=?', $utimestamp, $id_extra); } # Create the event @@ -4810,7 +4810,7 @@ sub pandora_process_event_replication ($) { } # Get server id on metaconsole - my $metaconsole_server_id = enterprise_hook('get_metaconsole_setup_server_id', [$dbh_metaconsole, safe_input($pa_config->{'servername'})]); + my $metaconsole_server_id = enterprise_hook('get_metaconsole_setup_server_id', [$dbh]); # If the server name is not found in metaconsole setup: abort if($metaconsole_server_id == -1) { diff --git a/pandora_server/lib/PandoraFMS/PluginTools.pm b/pandora_server/lib/PandoraFMS/PluginTools.pm index 812f96ec86..3b0caf9619 100644 --- a/pandora_server/lib/PandoraFMS/PluginTools.pm +++ b/pandora_server/lib/PandoraFMS/PluginTools.pm @@ -32,7 +32,7 @@ our @ISA = qw(Exporter); # version: Defines actual version of Pandora Server for this module only my $pandora_version = "7.0NG.735"; -my $pandora_build = "190614"; +my $pandora_build = "190625"; our $VERSION = $pandora_version." ".$pandora_build; our %EXPORT_TAGS = ( 'all' => [ qw() ] ); diff --git a/pandora_server/pandora_server.redhat.spec b/pandora_server/pandora_server.redhat.spec index 3e5fe6d418..d6b4578521 100644 --- a/pandora_server/pandora_server.redhat.spec +++ b/pandora_server/pandora_server.redhat.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.735 -%define release 190614 +%define release 190625 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server.spec b/pandora_server/pandora_server.spec index 46e455555a..f3758822ff 100644 --- a/pandora_server/pandora_server.spec +++ b/pandora_server/pandora_server.spec @@ -3,7 +3,7 @@ # %define name pandorafms_server %define version 7.0NG.735 -%define release 190614 +%define release 190625 Summary: Pandora FMS Server Name: %{name} diff --git a/pandora_server/pandora_server_installer b/pandora_server/pandora_server_installer index dd265ae9f5..b63386d7df 100755 --- a/pandora_server/pandora_server_installer +++ b/pandora_server/pandora_server_installer @@ -9,7 +9,7 @@ # ********************************************************************** PI_VERSION="7.0NG.735" -PI_BUILD="190614" +PI_BUILD="190625" MODE=$1 if [ $# -gt 1 ]; then diff --git a/pandora_server/util/pandora_db.pl b/pandora_server/util/pandora_db.pl index 0a202ba562..875f8f51dd 100644 --- a/pandora_server/util/pandora_db.pl +++ b/pandora_server/util/pandora_db.pl @@ -34,7 +34,7 @@ use PandoraFMS::Config; use PandoraFMS::DB; # version: define current version -my $version = "7.0NG.735 PS190614"; +my $version = "7.0NG.735 PS190625"; # Pandora server configuration my %conf; diff --git a/pandora_server/util/pandora_manage.pl b/pandora_server/util/pandora_manage.pl index d7233faa28..e00e964276 100644 --- a/pandora_server/util/pandora_manage.pl +++ b/pandora_server/util/pandora_manage.pl @@ -36,7 +36,7 @@ use Encode::Locale; Encode::Locale::decode_argv; # version: define current version -my $version = "7.0NG.735 PS190614"; +my $version = "7.0NG.735 PS190625"; # save program name for logging my $progname = basename($0); @@ -3801,9 +3801,8 @@ sub cli_get_agent_group() { else { my $id_group = get_agent_group ($dbh_metaconsole, $id_agent); my $group_name = get_group_name ($dbh_metaconsole, $id_group); - my $metaconsole_name = enterprise_hook('get_metaconsole_setup_server_name',[$dbh, $server]); $agent_name = safe_output($agent_name); - print "[INFO] Server: $metaconsole_name Agent: $agent_name Name Group: $group_name\n\n"; + print "[INFO] Agent: $agent_name Name Group: $group_name\n\n"; } } } @@ -3843,7 +3842,6 @@ sub cli_get_agent_group_id() { foreach my $server (@servers_id) { my $dbh_metaconsole = enterprise_hook('get_node_dbh',[$conf, $server, $dbh]); - my $metaconsole_name = enterprise_hook('get_metaconsole_setup_server_name',[$dbh, $server]); my $id_agent = get_agent_id($dbh_metaconsole,$agent_name); if ($id_agent == -1) { @@ -3852,7 +3850,7 @@ sub cli_get_agent_group_id() { else { my $id_group = get_agent_group ($dbh_metaconsole, $id_agent); $agent_name = safe_output($agent_name); - print "Server: $metaconsole_name Agent: $agent_name ID Group: $id_group\n\n"; + print "Agent: $agent_name ID Group: $id_group\n\n"; } } } diff --git a/pandora_server/util/plugin/dns_plugin.sh b/pandora_server/util/plugin/dns_plugin.sh index 6ec4de874e..cbbebc1ff5 100755 --- a/pandora_server/util/plugin/dns_plugin.sh +++ b/pandora_server/util/plugin/dns_plugin.sh @@ -68,27 +68,16 @@ then help fi -TMPFILE=/tmp/dns_$DNS_CHECK.tmp -dig @$DNS_CHECK $DOMAIN_CHECK > $TMPFILE -RETURN_IP=`cat $TMPFILE | grep "^$DOMAIN_CHECK" | awk '{print $5}'` -RETURN_TIMEOUT=`cat $TMPFILE | grep "Query time" | grep -o "[0-9]*"` - - rm $TMPFILE 2> /dev/null - -if [ $TIMEOUT_CHECK == 1 ] -then - echo $RETURN_TIMEOUT - exit 0 -fi - -if [ "$RETURN_IP" != "$IP_CHECK" ] -then - echo 0 - exit 1 -else - echo 1 - exit 0 -fi +results=`dig @$DNS_CHECK +nocmd $DOMAIN_CHECK +multiline +noall +answer A` +targets=`echo "$results"| awk '{print $5}'` +for x in $targets; do + if [ "$x" == "$IP_CHECK" ]; then + echo 1 + exit 0 + fi +done +echo 0 +exit 0 diff --git a/visual_console_client/src/Item.ts b/visual_console_client/src/Item.ts index 7ad0f779d6..b7c44f8c12 100644 --- a/visual_console_client/src/Item.ts +++ b/visual_console_client/src/Item.ts @@ -1,4 +1,10 @@ -import { Position, Size, UnknownObject, WithModuleProps } from "./types"; +import { + Position, + Size, + AnyObject, + WithModuleProps, + ItemMeta +} from "./lib/types"; import { sizePropsDecoder, positionPropsDecoder, @@ -9,7 +15,7 @@ import { humanDate, humanTime } from "./lib"; -import TypedEvent, { Listener, Disposable } from "./TypedEvent"; +import TypedEvent, { Listener, Disposable } from "./lib/TypedEvent"; // Enum: https://www.typescriptlang.org/docs/handbook/enums.html. export const enum ItemType { @@ -52,14 +58,14 @@ export interface ItemProps extends Position, Size { // FIXME: Fix type compatibility. export interface ItemClickEvent { // data: Props; - data: UnknownObject; + data: AnyObject; nativeEvent: Event; } // FIXME: Fix type compatibility. export interface ItemRemoveEvent { // data: Props; - data: UnknownObject; + data: AnyObject; } /** @@ -89,7 +95,7 @@ const parseLabelPosition = ( * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function itemBasePropsDecoder(data: UnknownObject): ItemProps | never { +export function itemBasePropsDecoder(data: AnyObject): ItemProps | never { if (data.id == null || isNaN(parseInt(data.id))) { throw new TypeError("invalid id."); } @@ -118,6 +124,8 @@ export function itemBasePropsDecoder(data: UnknownObject): ItemProps | never { abstract class VisualConsoleItem { // Properties of the item. private itemProps: Props; + // Metadata of the item. + private _metadata: ItemMeta; // Reference to the DOM element which will contain the item. public elementRef: HTMLElement; public readonly labelElementRef: HTMLElement; @@ -138,8 +146,9 @@ abstract class VisualConsoleItem { */ protected abstract createDomElement(): HTMLElement; - public constructor(props: Props) { + public constructor(props: Props, metadata: ItemMeta) { this.itemProps = props; + this._metadata = metadata; /* * Get a HTMLElement which represents the container box @@ -185,8 +194,14 @@ abstract class VisualConsoleItem { box.style.zIndex = this.props.isOnTop ? "2" : "1"; box.style.left = `${this.props.x}px`; box.style.top = `${this.props.y}px`; - box.onclick = e => - this.clickEventManager.emit({ data: this.props, nativeEvent: e }); + box.addEventListener("click", e => { + if (this.meta.editMode) { + e.preventDefault(); + e.stopPropagation(); + } else { + this.clickEventManager.emit({ data: this.props, nativeEvent: e }); + } + }); return box; } @@ -310,7 +325,34 @@ abstract class VisualConsoleItem { // From this point, things which rely on this.props can access to the changes. // Check if we should re-render. - if (this.shouldBeUpdated(prevProps, newProps)) this.render(prevProps); + if (this.shouldBeUpdated(prevProps, newProps)) + this.render(prevProps, this._metadata); + } + + /** + * Public accessor of the `meta` property. + * @return Properties. + */ + public get meta(): ItemMeta { + return { ...this._metadata }; // Return a copy. + } + + /** + * Public setter of the `meta` property. + * If the new meta are different enough than the + * stored meta, a render would be fired. + * @param newProps + */ + public set meta(newMetadata: ItemMeta) { + const prevMetadata = this._metadata; + // Update the internal meta. + this._metadata = newMetadata; + + // From this point, things which rely on this.props can access to the changes. + + // Check if we should re-render. + // if (this.shouldBeUpdated(prevMetadata, newMetadata)) + this.render(this.itemProps, prevMetadata); } /** @@ -333,7 +375,10 @@ abstract class VisualConsoleItem { * To recreate or update the HTMLElement which represents the item into the DOM. * @param prevProps If exists it will be used to only perform DOM updates instead of a full replace. */ - public render(prevProps: Props | null = null): void { + public render( + prevProps: Props | null = null, + prevMeta: ItemMeta | null = null + ): void { this.updateDomElement(this.childElementRef); // Move box. @@ -378,6 +423,29 @@ abstract class VisualConsoleItem { // Changed the reference to the main element. It's ugly, but needed. this.elementRef = container; } + + // Change metadata related things. + if (!prevMeta || prevMeta.editMode !== this.meta.editMode) { + if (this.meta.editMode) { + this.elementRef.classList.add("is-editing"); + } else { + this.elementRef.classList.remove("is-editing"); + } + } + if (!prevMeta || prevMeta.isFetching !== this.meta.isFetching) { + if (this.meta.isFetching) { + this.elementRef.classList.add("is-fetching"); + } else { + this.elementRef.classList.remove("is-fetching"); + } + } + if (!prevMeta || prevMeta.isUpdating !== this.meta.isUpdating) { + if (this.meta.isUpdating) { + this.elementRef.classList.add("is-updating"); + } else { + this.elementRef.classList.remove("is-updating"); + } + } } /** diff --git a/visual_console_client/src/VisualConsole.ts b/visual_console_client/src/VisualConsole.ts index 7b45ccc2f1..091cc08f92 100644 --- a/visual_console_client/src/VisualConsole.ts +++ b/visual_console_client/src/VisualConsole.ts @@ -1,9 +1,10 @@ -import { UnknownObject, Size } from "./types"; +import { AnyObject, Size } from "./lib/types"; import { parseBoolean, sizePropsDecoder, parseIntOr, - notEmptyStringOr + notEmptyStringOr, + itemMetaDecoder } from "./lib"; import Item, { ItemType, @@ -24,7 +25,7 @@ import EventsHistory, { eventsHistoryPropsDecoder } from "./items/EventsHistory"; import Percentile, { percentilePropsDecoder } from "./items/Percentile"; -import TypedEvent, { Disposable, Listener } from "./TypedEvent"; +import TypedEvent, { Disposable, Listener } from "./lib/TypedEvent"; import DonutGraph, { donutGraphPropsDecoder } from "./items/DonutGraph"; import BarsGraph, { barsGraphPropsDecoder } from "./items/BarsGraph"; import ModuleGraph, { moduleGraphPropsDecoder } from "./items/ModuleGraph"; @@ -32,47 +33,49 @@ import Service, { servicePropsDecoder } from "./items/Service"; // TODO: Document. // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -function itemInstanceFrom(data: UnknownObject) { +function itemInstanceFrom(data: AnyObject) { const type = parseIntOr(data.type, null); if (type == null) throw new TypeError("missing item type."); + const meta = itemMetaDecoder(data); + switch (type as ItemType) { case ItemType.STATIC_GRAPH: - return new StaticGraph(staticGraphPropsDecoder(data)); + return new StaticGraph(staticGraphPropsDecoder(data), meta); case ItemType.MODULE_GRAPH: - return new ModuleGraph(moduleGraphPropsDecoder(data)); + return new ModuleGraph(moduleGraphPropsDecoder(data), meta); case ItemType.SIMPLE_VALUE: case ItemType.SIMPLE_VALUE_MAX: case ItemType.SIMPLE_VALUE_MIN: case ItemType.SIMPLE_VALUE_AVG: - return new SimpleValue(simpleValuePropsDecoder(data)); + return new SimpleValue(simpleValuePropsDecoder(data), meta); case ItemType.PERCENTILE_BAR: case ItemType.PERCENTILE_BUBBLE: case ItemType.CIRCULAR_PROGRESS_BAR: case ItemType.CIRCULAR_INTERIOR_PROGRESS_BAR: - return new Percentile(percentilePropsDecoder(data)); + return new Percentile(percentilePropsDecoder(data), meta); case ItemType.LABEL: - return new Label(labelPropsDecoder(data)); + return new Label(labelPropsDecoder(data), meta); case ItemType.ICON: - return new Icon(iconPropsDecoder(data)); + return new Icon(iconPropsDecoder(data), meta); case ItemType.SERVICE: - return new Service(servicePropsDecoder(data)); + return new Service(servicePropsDecoder(data), meta); case ItemType.GROUP_ITEM: - return new Group(groupPropsDecoder(data)); + return new Group(groupPropsDecoder(data), meta); case ItemType.BOX_ITEM: - return new Box(boxPropsDecoder(data)); + return new Box(boxPropsDecoder(data), meta); case ItemType.LINE_ITEM: - return new Line(linePropsDecoder(data)); + return new Line(linePropsDecoder(data), meta); case ItemType.AUTO_SLA_GRAPH: - return new EventsHistory(eventsHistoryPropsDecoder(data)); + return new EventsHistory(eventsHistoryPropsDecoder(data), meta); case ItemType.DONUT_GRAPH: - return new DonutGraph(donutGraphPropsDecoder(data)); + return new DonutGraph(donutGraphPropsDecoder(data), meta); case ItemType.BARS_GRAPH: - return new BarsGraph(barsGraphPropsDecoder(data)); + return new BarsGraph(barsGraphPropsDecoder(data), meta); case ItemType.CLOCK: - return new Clock(clockPropsDecoder(data)); + return new Clock(clockPropsDecoder(data), meta); case ItemType.COLOR_CLOUD: - return new ColorCloud(colorCloudPropsDecoder(data)); + return new ColorCloud(colorCloudPropsDecoder(data), meta); default: throw new TypeError("item not found"); } @@ -80,7 +83,7 @@ function itemInstanceFrom(data: UnknownObject) { // TODO: Document. // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -function decodeProps(data: UnknownObject) { +function decodeProps(data: AnyObject) { const type = parseIntOr(data.type, null); if (type == null) throw new TypeError("missing item type."); @@ -147,7 +150,7 @@ export interface VisualConsoleProps extends Size { * is missing from the raw object or have an invalid type. */ export function visualConsolePropsDecoder( - data: UnknownObject + data: AnyObject ): VisualConsoleProps | never { // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation const { @@ -226,8 +229,8 @@ export default class VisualConsole { public constructor( container: HTMLElement, - props: UnknownObject, - items: UnknownObject[] + props: AnyObject, + items: AnyObject[] ) { this.containerRef = container; this._props = visualConsolePropsDecoder(props); @@ -288,13 +291,13 @@ export default class VisualConsole { * Public setter of the `elements` property. * @param items. */ - public updateElements(items: UnknownObject[]): void { - const itemIds = items.map(item => item.id || null).filter(id => id != null); - itemIds as number[]; // Tell the type system to rely on us. + public updateElements(items: AnyObject[]): void { + // Ensure the type cause Typescript doesn't know the filter removes null items. + const itemIds = items + .map(item => item.id || null) + .filter(id => id != null) as number[]; // Get the elements we should delete. - const deletedIds: number[] = this.elementIds.filter( - id => itemIds.indexOf(id) < 0 - ); + const deletedIds = this.elementIds.filter(id => itemIds.indexOf(id) < 0); // Delete the elements. deletedIds.forEach(id => { if (this.elementsById[id] != null) { @@ -530,6 +533,9 @@ export default class VisualConsole { height: 0, lineWidth: this.props.relationLineWidth, color: "#CCCCCC" + }), + itemMetaDecoder({ + receivedAt: new Date() }) ); // Save a reference to the line item. @@ -557,4 +563,22 @@ export default class VisualConsole { return disposable; } + + /** + * Enable the edition mode. + */ + public enableEditMode(): void { + this.elements.forEach(item => { + item.meta = { ...item.meta, editMode: true }; + }); + } + + /** + * Disable the edition mode. + */ + public disableEditMode(): void { + this.elements.forEach(item => { + item.meta = { ...item.meta, editMode: false }; + }); + } } diff --git a/visual_console_client/src/items/BarsGraph.ts b/visual_console_client/src/items/BarsGraph.ts index d1a6fe97a5..7fcde89177 100644 --- a/visual_console_client/src/items/BarsGraph.ts +++ b/visual_console_client/src/items/BarsGraph.ts @@ -1,4 +1,4 @@ -import { UnknownObject, WithModuleProps } from "../types"; +import { AnyObject, WithModuleProps } from "../lib/types"; import { modulePropsDecoder, decodeBase64, stringIsEmpty } from "../lib"; import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item"; @@ -17,9 +17,7 @@ export type BarsGraphProps = { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function barsGraphPropsDecoder( - data: UnknownObject -): BarsGraphProps | never { +export function barsGraphPropsDecoder(data: AnyObject): BarsGraphProps | never { if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) { throw new TypeError("missing html content."); } diff --git a/visual_console_client/src/items/Box.ts b/visual_console_client/src/items/Box.ts index ca3078c0a6..042621c5a6 100644 --- a/visual_console_client/src/items/Box.ts +++ b/visual_console_client/src/items/Box.ts @@ -1,4 +1,4 @@ -import { UnknownObject } from "../types"; +import { AnyObject } from "../lib/types"; import { parseIntOr, notEmptyStringOr } from "../lib"; import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item"; @@ -24,7 +24,7 @@ interface BoxProps extends ItemProps { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function boxPropsDecoder(data: UnknownObject): BoxProps | never { +export function boxPropsDecoder(data: AnyObject): BoxProps | never { return { ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects. type: ItemType.BOX_ITEM, diff --git a/visual_console_client/src/items/Clock/index.ts b/visual_console_client/src/items/Clock/index.ts index 52e0e65775..e775c00102 100644 --- a/visual_console_client/src/items/Clock/index.ts +++ b/visual_console_client/src/items/Clock/index.ts @@ -1,6 +1,11 @@ import "./styles.css"; -import { LinkedVisualConsoleProps, UnknownObject, Size } from "../../types"; +import { + LinkedVisualConsoleProps, + AnyObject, + Size, + ItemMeta +} from "../../lib/types"; import { linkedVCPropsDecoder, parseIntOr, @@ -60,7 +65,7 @@ const parseClockFormat = (clockFormat: unknown): ClockProps["clockFormat"] => { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function clockPropsDecoder(data: UnknownObject): ClockProps | never { +export function clockPropsDecoder(data: AnyObject): ClockProps | never { if ( typeof data.clockTimezone !== "string" || data.clockTimezone.length === 0 @@ -85,9 +90,9 @@ export default class Clock extends Item { public static readonly TICK_INTERVAL = 1000; // In ms. private intervalRef: number | null = null; - public constructor(props: ClockProps) { + public constructor(props: ClockProps, meta: ItemMeta) { // Call the superclass constructor. - super(props); + super(props, meta); /* The item is already loaded and inserted into the DOM. * The class properties are now initialized. diff --git a/visual_console_client/src/items/Clock/spec.ts b/visual_console_client/src/items/Clock/spec.ts index 7380f98468..acd4233ed1 100644 --- a/visual_console_client/src/items/Clock/spec.ts +++ b/visual_console_client/src/items/Clock/spec.ts @@ -1,4 +1,5 @@ import Clock, { clockPropsDecoder } from "."; +import { itemMetaDecoder } from "../../lib"; const genericRawProps = { id: 1, @@ -46,6 +47,9 @@ describe("Clock item", () => { ...sizeRawProps, ...linkedModuleProps, ...digitalClockProps + }), + itemMetaDecoder({ + receivedAt: new Date(1) }) ); diff --git a/visual_console_client/src/items/ColorCloud.spec.ts b/visual_console_client/src/items/ColorCloud.spec.ts index 103850b04b..fb873b8894 100644 --- a/visual_console_client/src/items/ColorCloud.spec.ts +++ b/visual_console_client/src/items/ColorCloud.spec.ts @@ -1,4 +1,5 @@ import ColorCloud, { colorCloudPropsDecoder } from "./ColorCloud"; +import { itemMetaDecoder } from "../lib"; const genericRawProps = { id: 1, @@ -41,6 +42,9 @@ describe("Color cloud item", () => { ...sizeRawProps, ...linkedModuleProps, ...colorCloudProps + }), + itemMetaDecoder({ + receivedAt: new Date(1) }) ); diff --git a/visual_console_client/src/items/ColorCloud.ts b/visual_console_client/src/items/ColorCloud.ts index 0b5dfe9948..ced87424d9 100644 --- a/visual_console_client/src/items/ColorCloud.ts +++ b/visual_console_client/src/items/ColorCloud.ts @@ -1,8 +1,8 @@ import { WithModuleProps, LinkedVisualConsoleProps, - UnknownObject -} from "../types"; + AnyObject +} from "../lib/types"; import { modulePropsDecoder, linkedVCPropsDecoder } from "../lib"; import Item, { itemBasePropsDecoder, ItemType, ItemProps } from "../Item"; @@ -24,7 +24,7 @@ export type ColorCloudProps = { * is missing from the raw object or have an invalid type. */ export function colorCloudPropsDecoder( - data: UnknownObject + data: AnyObject ): ColorCloudProps | never { // TODO: Validate the color. if (typeof data.color !== "string" || data.color.length === 0) { diff --git a/visual_console_client/src/items/DonutGraph.ts b/visual_console_client/src/items/DonutGraph.ts index d60f268567..c6436583c4 100644 --- a/visual_console_client/src/items/DonutGraph.ts +++ b/visual_console_client/src/items/DonutGraph.ts @@ -1,8 +1,8 @@ import { LinkedVisualConsoleProps, - UnknownObject, + AnyObject, WithModuleProps -} from "../types"; +} from "../lib/types"; import { linkedVCPropsDecoder, modulePropsDecoder, @@ -28,7 +28,7 @@ export type DonutGraphProps = { * is missing from the raw object or have an invalid type. */ export function donutGraphPropsDecoder( - data: UnknownObject + data: AnyObject ): DonutGraphProps | never { if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) { throw new TypeError("missing html content."); diff --git a/visual_console_client/src/items/EventsHistory.ts b/visual_console_client/src/items/EventsHistory.ts index 7e9db0ae9b..1d460e5b5b 100644 --- a/visual_console_client/src/items/EventsHistory.ts +++ b/visual_console_client/src/items/EventsHistory.ts @@ -1,4 +1,4 @@ -import { UnknownObject, WithModuleProps } from "../types"; +import { AnyObject, WithModuleProps } from "../lib/types"; import { modulePropsDecoder, parseIntOr, @@ -24,7 +24,7 @@ export type EventsHistoryProps = { * is missing from the raw object or have an invalid type. */ export function eventsHistoryPropsDecoder( - data: UnknownObject + data: AnyObject ): EventsHistoryProps | never { if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) { throw new TypeError("missing html content."); diff --git a/visual_console_client/src/items/Group.spec.ts b/visual_console_client/src/items/Group.spec.ts index e00a5cf327..c117a95b42 100644 --- a/visual_console_client/src/items/Group.spec.ts +++ b/visual_console_client/src/items/Group.spec.ts @@ -1,4 +1,5 @@ import Group, { groupPropsDecoder } from "./Group"; +import { itemMetaDecoder } from "../lib"; const genericRawProps = { id: 1, @@ -33,6 +34,9 @@ describe("Group item", () => { ...positionRawProps, ...sizeRawProps, ...groupRawProps + }), + itemMetaDecoder({ + receivedAt: new Date(1) }) ); diff --git a/visual_console_client/src/items/Group.ts b/visual_console_client/src/items/Group.ts index fa97f69a62..98552a0f1b 100644 --- a/visual_console_client/src/items/Group.ts +++ b/visual_console_client/src/items/Group.ts @@ -1,4 +1,4 @@ -import { LinkedVisualConsoleProps, UnknownObject } from "../types"; +import { LinkedVisualConsoleProps, AnyObject } from "../lib/types"; import { linkedVCPropsDecoder, parseIntOr, @@ -19,7 +19,7 @@ export type GroupProps = { } & ItemProps & LinkedVisualConsoleProps; -function extractHtml(data: UnknownObject): string | null { +function extractHtml(data: AnyObject): string | null { if (!stringIsEmpty(data.html)) return data.html; if (!stringIsEmpty(data.encodedHtml)) return decodeBase64(data.encodedHtml); return null; @@ -34,7 +34,7 @@ function extractHtml(data: UnknownObject): string | null { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function groupPropsDecoder(data: UnknownObject): GroupProps | never { +export function groupPropsDecoder(data: AnyObject): GroupProps | never { if ( (typeof data.imageSrc !== "string" || data.imageSrc.length === 0) && data.encodedHtml === null diff --git a/visual_console_client/src/items/Icon.ts b/visual_console_client/src/items/Icon.ts index 12c1b035c7..d6e4a21fc6 100644 --- a/visual_console_client/src/items/Icon.ts +++ b/visual_console_client/src/items/Icon.ts @@ -1,4 +1,4 @@ -import { LinkedVisualConsoleProps, UnknownObject } from "../types"; +import { LinkedVisualConsoleProps, AnyObject } from "../lib/types"; import { linkedVCPropsDecoder } from "../lib"; import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item"; @@ -17,7 +17,7 @@ export type IconProps = { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function iconPropsDecoder(data: UnknownObject): IconProps | never { +export function iconPropsDecoder(data: AnyObject): IconProps | never { if (typeof data.imageSrc !== "string" || data.imageSrc.length === 0) { throw new TypeError("invalid image src."); } diff --git a/visual_console_client/src/items/Label.ts b/visual_console_client/src/items/Label.ts index c8de572c15..4f6a382a08 100644 --- a/visual_console_client/src/items/Label.ts +++ b/visual_console_client/src/items/Label.ts @@ -1,4 +1,4 @@ -import { LinkedVisualConsoleProps, UnknownObject } from "../types"; +import { LinkedVisualConsoleProps, AnyObject } from "../lib/types"; import { linkedVCPropsDecoder } from "../lib"; import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item"; @@ -16,7 +16,7 @@ export type LabelProps = { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function labelPropsDecoder(data: UnknownObject): LabelProps | never { +export function labelPropsDecoder(data: AnyObject): LabelProps | never { return { ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects. type: ItemType.LABEL, diff --git a/visual_console_client/src/items/Line.ts b/visual_console_client/src/items/Line.ts index 20532e44ea..8735279a9b 100644 --- a/visual_console_client/src/items/Line.ts +++ b/visual_console_client/src/items/Line.ts @@ -1,4 +1,4 @@ -import { UnknownObject, Position, Size } from "../types"; +import { AnyObject, Position, Size, ItemMeta } from "../lib/types"; import { parseIntOr, notEmptyStringOr } from "../lib"; import Item, { ItemType, ItemProps, itemBasePropsDecoder } from "../Item"; @@ -25,7 +25,7 @@ interface LineProps extends ItemProps { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function linePropsDecoder(data: UnknownObject): LineProps | never { +export function linePropsDecoder(data: AnyObject): LineProps | never { const props: LineProps = { ...itemBasePropsDecoder({ ...data, width: 1, height: 1 }), // Object spread. It will merge the properties of the two objects. type: ItemType.LINE_ITEM, @@ -71,17 +71,20 @@ export default class Line extends Item { /** * @override */ - public constructor(props: LineProps) { + public constructor(props: LineProps, meta: ItemMeta) { /* * We need to override the constructor cause we need to obtain * the * box size and position from the start and finish points * of the line. */ - super({ - ...props, - ...Line.extractBoxSizeAndPosition(props) - }); + super( + { + ...props, + ...Line.extractBoxSizeAndPosition(props) + }, + meta + ); } /** diff --git a/visual_console_client/src/items/ModuleGraph.ts b/visual_console_client/src/items/ModuleGraph.ts index 3440496d19..ce23785d36 100644 --- a/visual_console_client/src/items/ModuleGraph.ts +++ b/visual_console_client/src/items/ModuleGraph.ts @@ -1,8 +1,8 @@ import { LinkedVisualConsoleProps, - UnknownObject, + AnyObject, WithModuleProps -} from "../types"; +} from "../lib/types"; import { linkedVCPropsDecoder, modulePropsDecoder, @@ -28,7 +28,7 @@ export type ModuleGraphProps = { * is missing from the raw object or have an invalid type. */ export function moduleGraphPropsDecoder( - data: UnknownObject + data: AnyObject ): ModuleGraphProps | never { if (stringIsEmpty(data.html) && stringIsEmpty(data.encodedHtml)) { throw new TypeError("missing html content."); diff --git a/visual_console_client/src/items/Percentile.ts b/visual_console_client/src/items/Percentile.ts index 4c93b86b1f..0706f55ed9 100644 --- a/visual_console_client/src/items/Percentile.ts +++ b/visual_console_client/src/items/Percentile.ts @@ -2,9 +2,9 @@ import { arc as arcFactory } from "d3-shape"; import { LinkedVisualConsoleProps, - UnknownObject, + AnyObject, WithModuleProps -} from "../types"; +} from "../lib/types"; import { linkedVCPropsDecoder, modulePropsDecoder, @@ -81,7 +81,7 @@ function extractValueType(valueType: unknown): PercentileProps["valueType"] { * is missing from the raw object or have an invalid type. */ export function percentilePropsDecoder( - data: UnknownObject + data: AnyObject ): PercentileProps | never { return { ...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects. diff --git a/visual_console_client/src/items/Service.ts b/visual_console_client/src/items/Service.ts index 9440503e80..09a8c26824 100644 --- a/visual_console_client/src/items/Service.ts +++ b/visual_console_client/src/items/Service.ts @@ -1,4 +1,4 @@ -import { UnknownObject } from "../types"; +import { AnyObject } from "../lib/types"; import { stringIsEmpty, notEmptyStringOr, @@ -24,7 +24,7 @@ export type ServiceProps = { * @throws Will throw a TypeError if some property * is missing from the raw object or have an invalid type. */ -export function servicePropsDecoder(data: UnknownObject): ServiceProps | never { +export function servicePropsDecoder(data: AnyObject): ServiceProps | never { if (data.imageSrc !== null) { if ( typeof data.statusImageSrc !== "string" || diff --git a/visual_console_client/src/items/SimpleValue.ts b/visual_console_client/src/items/SimpleValue.ts index 7cc5e139af..10b8e4097a 100644 --- a/visual_console_client/src/items/SimpleValue.ts +++ b/visual_console_client/src/items/SimpleValue.ts @@ -1,8 +1,8 @@ import { LinkedVisualConsoleProps, - UnknownObject, + AnyObject, WithModuleProps -} from "../types"; +} from "../lib/types"; import { linkedVCPropsDecoder, parseIntOr, @@ -69,7 +69,7 @@ const parseProcessValue = ( * is missing from the raw object or have an invalid type. */ export function simpleValuePropsDecoder( - data: UnknownObject + data: AnyObject ): SimpleValueProps | never { if (typeof data.value !== "string" || data.value.length === 0) { throw new TypeError("invalid value"); diff --git a/visual_console_client/src/items/StaticGraph.ts b/visual_console_client/src/items/StaticGraph.ts index 899d54ec70..39267e33f9 100644 --- a/visual_console_client/src/items/StaticGraph.ts +++ b/visual_console_client/src/items/StaticGraph.ts @@ -1,8 +1,8 @@ import { WithModuleProps, LinkedVisualConsoleProps, - UnknownObject -} from "../types"; + AnyObject +} from "../lib/types"; import { modulePropsDecoder, @@ -47,7 +47,7 @@ const parseShowLastValueTooltip = ( * is missing from the raw object or have an invalid type. */ export function staticGraphPropsDecoder( - data: UnknownObject + data: AnyObject ): StaticGraphProps | never { if (typeof data.imageSrc !== "string" || data.imageSrc.length === 0) { throw new TypeError("invalid image src."); diff --git a/visual_console_client/src/lib/AsyncTaskManager.ts b/visual_console_client/src/lib/AsyncTaskManager.ts index 5ad261194b..ef187f45ad 100644 --- a/visual_console_client/src/lib/AsyncTaskManager.ts +++ b/visual_console_client/src/lib/AsyncTaskManager.ts @@ -1,4 +1,4 @@ -import TypedEvent, { Disposable, Listener } from "../TypedEvent"; +import TypedEvent, { Disposable, Listener } from "./TypedEvent"; interface Cancellable { cancel(): void; diff --git a/visual_console_client/src/TypedEvent.ts b/visual_console_client/src/lib/TypedEvent.ts similarity index 100% rename from visual_console_client/src/TypedEvent.ts rename to visual_console_client/src/lib/TypedEvent.ts diff --git a/visual_console_client/src/lib/index.ts b/visual_console_client/src/lib/index.ts index 1a04ca74af..65f0a1ab86 100644 --- a/visual_console_client/src/lib/index.ts +++ b/visual_console_client/src/lib/index.ts @@ -1,12 +1,14 @@ import { - UnknownObject, + AnyObject, Position, Size, WithAgentProps, WithModuleProps, LinkedVisualConsoleProps, - LinkedVisualConsolePropsStatus -} from "../types"; + LinkedVisualConsolePropsStatus, + UnknownObject, + ItemMeta +} from "./types"; /** * Return a number or a default value from a raw value. @@ -72,6 +74,23 @@ export function parseBoolean(value: unknown): boolean { else return false; } +/** + * Return a valid date or a default value from a raw value. + * @param value Raw value from which we will try to extract a valid date. + * @param defaultValue Default value to use if we cannot extract a valid date. + * @return A valid date or the default value. + */ +export function parseDateOr(value: unknown, defaultValue: T): Date | T { + if (value instanceof Date) return value; + else if (typeof value === "number") return new Date(value * 1000); + else if ( + typeof value === "string" && + !Number.isNaN(new Date(value).getTime()) + ) + return new Date(value); + else return defaultValue; +} + /** * Pad the current string with another string (multiple times, if needed) * until the resulting string reaches the given length. @@ -113,7 +132,7 @@ export function leftPad( * @param data Raw object. * @return An object representing the position. */ -export function positionPropsDecoder(data: UnknownObject): Position { +export function positionPropsDecoder(data: AnyObject): Position { return { x: parseIntOr(data.x, 0), y: parseIntOr(data.y, 0) @@ -126,7 +145,7 @@ export function positionPropsDecoder(data: UnknownObject): Position { * @return An object representing the size. * @throws Will throw a TypeError if the width and height are not valid numbers. */ -export function sizePropsDecoder(data: UnknownObject): Size | never { +export function sizePropsDecoder(data: AnyObject): Size | never { if ( data.width == null || isNaN(parseInt(data.width)) || @@ -147,7 +166,7 @@ export function sizePropsDecoder(data: UnknownObject): Size | never { * @param data Raw object. * @return An object representing the agent properties. */ -export function agentPropsDecoder(data: UnknownObject): WithAgentProps { +export function agentPropsDecoder(data: AnyObject): WithAgentProps { const agentProps: WithAgentProps = { agentId: parseIntOr(data.agent, null), agentName: notEmptyStringOr(data.agentName, null), @@ -169,7 +188,7 @@ export function agentPropsDecoder(data: UnknownObject): WithAgentProps { * @param data Raw object. * @return An object representing the module and agent properties. */ -export function modulePropsDecoder(data: UnknownObject): WithModuleProps { +export function modulePropsDecoder(data: AnyObject): WithModuleProps { return { moduleId: parseIntOr(data.moduleId, null), moduleName: notEmptyStringOr(data.moduleName, null), @@ -185,7 +204,7 @@ export function modulePropsDecoder(data: UnknownObject): WithModuleProps { * @throws Will throw a TypeError if the status calculation properties are invalid. */ export function linkedVCPropsDecoder( - data: UnknownObject + data: AnyObject ): LinkedVisualConsoleProps | never { // Object destructuring: http://es6-features.org/#ObjectMatchingShorthandNotation const { @@ -246,6 +265,29 @@ export function linkedVCPropsDecoder( : linkedLayoutBaseProps; } +/** + * Build a valid typed object from a raw object. + * @param data Raw object. + * @return An object representing the item's meta properties. + */ +export function itemMetaDecoder(data: UnknownObject): ItemMeta | never { + const receivedAt = parseDateOr(data.receivedAt, null); + if (receivedAt === null) throw new TypeError("invalid meta structure"); + + let error = null; + if (data.error instanceof Error) error = data.error; + else if (typeof data.error === "string") error = new Error(data.error); + + return { + receivedAt, + error, + editMode: parseBoolean(data.editMode), + isFromCache: parseBoolean(data.isFromCache), + isFetching: false, + isUpdating: false + }; +} + /** * To get a CSS rule with the most used prefixes. * @param ruleName Name of the CSS rule. diff --git a/visual_console_client/src/lib/spec.ts b/visual_console_client/src/lib/spec.ts index ca86e2f499..ae8ffb02cc 100644 --- a/visual_console_client/src/lib/spec.ts +++ b/visual_console_client/src/lib/spec.ts @@ -7,7 +7,8 @@ import { decodeBase64, humanDate, humanTime, - replaceMacros + replaceMacros, + itemMetaDecoder } from "."; describe("function parseIntOr", () => { @@ -72,14 +73,14 @@ describe("function prefixedCssRules", () => { describe("function decodeBase64", () => { it("should decode the base64 without errors", () => { - expect(decodeBase64("SGkgSSdtIGRlY29kZWQ=")).toEqual("Hi I'm decoded"); - expect(decodeBase64("Rk9PQkFSQkFa")).toEqual("FOOBARBAZ"); - expect(decodeBase64("eyJpZCI6MSwibmFtZSI6ImZvbyJ9")).toEqual( + expect(decodeBase64("SGkgSSdtIGRlY29kZWQ=")).toBe("Hi I'm decoded"); + expect(decodeBase64("Rk9PQkFSQkFa")).toBe("FOOBARBAZ"); + expect(decodeBase64("eyJpZCI6MSwibmFtZSI6ImZvbyJ9")).toBe( '{"id":1,"name":"foo"}' ); expect( decodeBase64("PGRpdj5Cb3ggPHA+UGFyYWdyYXBoPC9wPjxociAvPjwvZGl2Pg==") - ).toEqual("
Box

Paragraph


"); + ).toBe("
Box

Paragraph


"); }); }); @@ -118,3 +119,46 @@ describe("replaceMacros function", () => { expect(replaceMacros(macros, text)).toBe("Lorem foo Ipsum baz"); }); }); + +describe("itemMetaDecoder function", () => { + it("should extract a default meta object", () => { + expect( + itemMetaDecoder({ + receivedAt: 1 + }) + ).toEqual({ + receivedAt: new Date(1000), + error: null, + isFromCache: false, + isFetching: false, + isUpdating: false, + editMode: false + }); + }); + + it("should extract a valid meta object", () => { + expect( + itemMetaDecoder({ + receivedAt: new Date(1000), + error: new Error("foo"), + editMode: 1 + }) + ).toEqual({ + receivedAt: new Date(1000), + error: new Error("foo"), + isFromCache: false, + isFetching: false, + isUpdating: false, + editMode: true + }); + }); + + it("should fail when a invalid structure is used", () => { + expect(() => itemMetaDecoder({})).toThrowError(TypeError); + expect(() => + itemMetaDecoder({ + receivedAt: "foo" + }) + ).toThrowError(TypeError); + }); +}); diff --git a/visual_console_client/src/types.ts b/visual_console_client/src/lib/types.ts similarity index 83% rename from visual_console_client/src/types.ts rename to visual_console_client/src/lib/types.ts index 79dee56e74..97f6cb622d 100644 --- a/visual_console_client/src/types.ts +++ b/visual_console_client/src/lib/types.ts @@ -1,7 +1,11 @@ -export interface UnknownObject { +export interface AnyObject { [key: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any } +export interface UnknownObject { + [key: string]: unknown; +} + export interface Position { x: number; y: number; @@ -45,3 +49,12 @@ export type LinkedVisualConsoleProps = { linkedLayoutId: number | null; linkedLayoutAgentId: number | null; } & LinkedVisualConsolePropsStatus; + +export interface ItemMeta { + receivedAt: Date; + error: Error | null; + isFromCache: boolean; + isFetching: boolean; + isUpdating: boolean; + editMode: boolean; +} diff --git a/visual_console_client/src/main.css b/visual_console_client/src/main.css index 427c8895af..95217070c2 100644 --- a/visual_console_client/src/main.css +++ b/visual_console_client/src/main.css @@ -14,3 +14,8 @@ align-items: center; user-select: text; } + +.visual-console-item.is-editing { + border: 2px dashed #33ccff; + transform: translateX(-2px) translateY(-2px); +}