Merge branch 'master' of ../ZoneMinder.connortechnology
commit
8fa1d98a7b
|
@ -1,6 +1,6 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
github: [connortechnology,pliablepixels] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
github: [zoneminder,connortechnology,pliablepixels] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
|
||||
patreon: zoneminder # Replace with a single Patreon username
|
||||
open_collective: zoneminder # Replace with a single Open Collective username
|
||||
ko_fi: # Replace with a single Ko-fi username
|
||||
|
|
|
@ -30,6 +30,7 @@ To use this repository instead of the official Ubuntu repository, enter the foll
|
|||
**Step 3:** Install Zoneminder
|
||||
|
||||
::
|
||||
|
||||
sudo apt install -y zoneminder
|
||||
|
||||
|
||||
|
|
|
@ -1585,6 +1585,14 @@ our @options = (
|
|||
},
|
||||
category => 'web',
|
||||
},
|
||||
{
|
||||
name => 'ZM_WEB_NAVBAR_STICKY',
|
||||
default => '1',
|
||||
description => 'Are navbars and button bars sticky?',
|
||||
help => 'Do navbars and button bars remain fixed in place or scroll with the page content? Please note that this will only affect large browsers. Due to our responsive layout on narrow screens everything will become unsticky.',
|
||||
type => $types{boolean},
|
||||
category => 'web',
|
||||
},
|
||||
{
|
||||
name => 'ZM_WEB_TITLE',
|
||||
default => 'ZoneMinder',
|
||||
|
|
|
@ -227,7 +227,7 @@ int FfmpegCamera::Capture(std::shared_ptr<ZMPacket> &zm_packet) {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
if ((packet->pts < 0) and (lastPTS >=0)) {
|
||||
if ((packet->pts < 0) and (packet->pts != AV_NOPTS_VALUE) and (lastPTS >= 0)) {
|
||||
// 32-bit wrap around?
|
||||
Info("Suspected 32bit wraparound in input pts. %" PRId64, packet->pts);
|
||||
return -1;
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
/* Function to send the contents of a file. Will use sendfile or fall back to reading/writing */
|
||||
|
||||
ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, size_t size) {
|
||||
ssize_t zm_sendfile(int out_fd, int in_fd, off_t *offset, ssize_t size) {
|
||||
#ifdef HAVE_SENDFILE4_SUPPORT
|
||||
ssize_t err = sendfile(out_fd, in_fd, offset, size);
|
||||
if (err < 0) {
|
||||
|
|
|
@ -983,10 +983,10 @@ int VideoStore::writePacket(const std::shared_ptr<ZMPacket> &zm_pkt) {
|
|||
} // end while
|
||||
|
||||
if (have_out_of_order) {
|
||||
AVPacket *p = ((*rit)->packet).get();
|
||||
if (rit == queue.rend()) {
|
||||
Warning("Unable to re-order packet, packet dts is %" PRId64, p->dts);
|
||||
Debug(1, "Unable to re-order packet, packet dts is %" PRId64, av_pkt->dts);
|
||||
} else {
|
||||
AVPacket *p = ((*rit)->packet).get();
|
||||
Debug(1, "Found out of order packet, inserting after %" PRId64, p->dts);
|
||||
}
|
||||
queue.insert(rit.base(), zm_pkt);
|
||||
|
|
|
@ -34,15 +34,15 @@ var Server = function() {
|
|||
}
|
||||
},
|
||||
{
|
||||
key: 'UrlToZMS',
|
||||
value: function UrlToZMS() {
|
||||
key: 'urlToZMS',
|
||||
value: function urlToZMS() {
|
||||
const port = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||
return this.Protocol + '://' + this.Hostname + (port ? ':' + port : '') + (this.PathToZMS && this.PathToZMS != 'null' ? this.PathToZMS : '');
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'UrlToApi',
|
||||
value: function UrlToApi() {
|
||||
key: 'urlToApi',
|
||||
value: function urlToApi() {
|
||||
const port = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
||||
return this.Protocol + '://' + this.Hostname + (port ? ':' + port : '') + (this.PathToApi && this.PathToApi != 'null' ? this.PathToApi : '');
|
||||
}
|
||||
|
|
|
@ -50,11 +50,24 @@
|
|||
.material-icons.md-18 { font-size: 18px; }
|
||||
.material-icons.md-36 { font-size: 36px; }
|
||||
|
||||
html,
|
||||
body {
|
||||
font-family: "Open Sans", Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: "Open Sans", Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
body.sticky {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
|
@ -220,7 +233,24 @@ ul.tabList li.active {
|
|||
}
|
||||
|
||||
ul.tabList li.active a {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#content {
|
||||
width: 100%;
|
||||
margin: 0 auto 8px auto;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
}
|
||||
body.sticky #content {
|
||||
/*
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
*/
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -454,6 +484,12 @@ th.table-th-sort-rev span.table-th-sort-span {
|
|||
#page {
|
||||
width: 100%;
|
||||
}
|
||||
body.sticky #page {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#header {
|
||||
width: 100%;
|
||||
|
@ -505,13 +541,6 @@ th.table-th-sort-rev span.table-th-sort-span {
|
|||
margin-left: 4px;
|
||||
}
|
||||
|
||||
#content {
|
||||
width: 100%;
|
||||
margin: 0 auto 8px auto;
|
||||
line-height: 130%;
|
||||
text-align: center;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
#content p {
|
||||
margin-top: 4px;
|
||||
|
@ -629,10 +658,6 @@ color:#ffa801;
|
|||
border:none;
|
||||
}
|
||||
|
||||
.container-fluid {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
|
|
|
@ -114,3 +114,13 @@
|
|||
.SourceFilter input {
|
||||
padding: 3px 5px 4px 5px;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
height: 100%;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
#monitorList {
|
||||
flex: 1 1 auto;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
|
|
@ -7,3 +7,7 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#controls {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
|
|
@ -88,3 +88,7 @@ min-width: 500px;
|
|||
clear: both;
|
||||
visibility: hidden;
|
||||
}
|
||||
#contentForm {
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
@ -31,3 +31,6 @@ th[data-field="DateTime"] {
|
|||
.search .form-control {
|
||||
font-size: 100%;
|
||||
}
|
||||
#logsTable {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
|
|
@ -73,3 +73,8 @@ tr td input[type="radio"] {
|
|||
padding-right: 1rem;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#monitor {
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,10 @@
|
|||
*/
|
||||
}
|
||||
|
||||
#monitors {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
#monitors:after {
|
||||
content: ".";
|
||||
display: block;
|
||||
|
|
|
@ -41,6 +41,7 @@ min-width: 0;
|
|||
position:relative;
|
||||
width:100%;
|
||||
height:100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
input[type=range]::-ms-tooltip {
|
||||
display: none;
|
||||
|
|
|
@ -25,6 +25,15 @@ input.large {
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
#options {
|
||||
overflow-y: auto;
|
||||
padding-top: 15px;
|
||||
height: 100%;
|
||||
}
|
||||
#options div.col-md {
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -60,9 +69,6 @@ input[name="newStorage[Url]"] {
|
|||
#options label {
|
||||
font-weight: bold;
|
||||
}
|
||||
#options {
|
||||
font-size:90%;
|
||||
}
|
||||
|
||||
#options .help-block {
|
||||
margin-top: 0;
|
||||
|
@ -76,3 +82,14 @@ input[name="newStorage[Url]"] {
|
|||
#options .col-md {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#contentButtons {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 2rem;
|
||||
}
|
||||
form {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
padding-top: 4rem;
|
||||
}
|
||||
|
|
|
@ -10,3 +10,8 @@
|
|||
.colZeroSize {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#results {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#content {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.Name {
|
||||
|
@ -15,3 +14,8 @@
|
|||
.Description textarea {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#video {
|
||||
overflow-y: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
|
|
@ -4,3 +4,8 @@ th[data-field="CreatedOn"],
|
|||
th[data-field="Name"] {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#snapshots {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
|
|
@ -30,15 +30,10 @@ function xhtmlHeaders($file, $title) {
|
|||
# This idea is that we always include the classic css files,
|
||||
# and then any different skin only needs to contain things that are different.
|
||||
$baseCssPhpFile = getSkinFile('css/base/skin.css.php');
|
||||
|
||||
$skinCssPhpFile = getSkinFile('css/'.$css.'/skin.css.php');
|
||||
|
||||
|
||||
$basename = basename($file, '.php');
|
||||
|
||||
$baseViewCssPhpFile = getSkinFile('/css/base/views/'.$basename.'.css.php');
|
||||
$viewCssPhpFile = getSkinFile('/css/'.$css.'/views/'.$basename.'.css.php');
|
||||
|
||||
function output_link_if_exists($files, $cache_bust=true) {
|
||||
global $skin;
|
||||
$html = array();
|
||||
|
@ -140,12 +135,15 @@ if ( $css != 'base' )
|
|||
?>
|
||||
<style>
|
||||
<?php
|
||||
if ( $baseViewCssPhpFile ) {
|
||||
require_once($baseViewCssPhpFile);
|
||||
}
|
||||
if ( $viewCssPhpFile ) {
|
||||
require_once($viewCssPhpFile);
|
||||
}
|
||||
$baseCssPhpFile = getSkinFile('css/base/skin.css.php');
|
||||
if ($baseCssPhpFile) require_once($baseCssPhpFile);
|
||||
$skinCssPhpFile = getSkinFile('css/'.$css.'/skin.css.php');
|
||||
if ($skinCssPhpFile) require_once($baseCssPhpFile);
|
||||
|
||||
$baseViewCssPhpFile = getSkinFile('/css/base/views/'.$basename.'.css.php');
|
||||
if ($baseViewCssPhpFile) require_once($baseViewCssPhpFile);
|
||||
$viewCssPhpFile = getSkinFile('/css/'.$css.'/views/'.$basename.'.css.php');
|
||||
if ($viewCssPhpFile) require_once($viewCssPhpFile);
|
||||
?>
|
||||
</style>
|
||||
|
||||
|
@ -157,7 +155,7 @@ if ( $css != 'base' )
|
|||
// Outputs an opening body tag, and any additional content that should go at the very top, like warnings and error messages.
|
||||
function getBodyTopHTML() {
|
||||
echo '
|
||||
<body>
|
||||
<body'.((defined('ZM_WEB_NAVBAR_STICKY') and ZM_WEB_NAVBAR_STICKY) ? ' class="sticky"' : '').'>
|
||||
<noscript>
|
||||
<div style="background-color:red;color:white;font-size:x-large;">
|
||||
'. validHtmlStr(ZM_WEB_TITLE) .' requires Javascript. Please enable Javascript in your browser for this site.
|
||||
|
@ -248,8 +246,10 @@ function getNormalNavBarHTML($running, $user, $bandwidth_options, $view, $skin)
|
|||
</div>
|
||||
</nav><!-- End First Navbar -->
|
||||
|
||||
<nav class="navbar navbar-expand-md justify-content-center" id="navbar-two">
|
||||
<div class="container-fluid" id="panel"<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down' ) ? 'style="display:none;"' : '' ?>>
|
||||
<nav class="navbar navbar-expand-md justify-content-center" id="navbar-two"
|
||||
<?php echo ( isset($_COOKIE['zmHeaderFlip']) and $_COOKIE['zmHeaderFlip'] == 'down' ) ? 'style="display:none;"' : '' ?>
|
||||
>
|
||||
<div class="container-fluid" id="panel" >
|
||||
<?php
|
||||
|
||||
if ( (!ZM_OPT_USE_AUTH) or $user ) {
|
||||
|
|
|
@ -275,8 +275,8 @@ if ( currentView != 'none' && currentView != 'login' ) {
|
|||
reminderClickFunction();
|
||||
// Manage the widget bar minimize chevron
|
||||
$j("#flip").click(function() {
|
||||
$j("#panel").slideToggle("slow");
|
||||
var flip = $j("#flip");
|
||||
$j("#navbar-two").slideToggle("slow");
|
||||
const flip = $j("#flip");
|
||||
if ( flip.html() == 'keyboard_arrow_up' ) {
|
||||
flip.html('keyboard_arrow_down');
|
||||
setCookie('zmHeaderFlip', 'down', 3600);
|
||||
|
|
|
@ -39,7 +39,7 @@ const cancelString = '<?php echo translate('Cancel') ?>';
|
|||
try to avoid using PHP_SELF but here I try to replace everything after '.php'. */ ?>
|
||||
const thisUrl = '<?php echo ZM_BASE_URL.preg_replace('/\.php.*$/i', '.php', $_SERVER['PHP_SELF']) ?>';
|
||||
const skinPath = '<?php echo ZM_SKIN_PATH ?>';
|
||||
const serverId = '<?php echo defined('ZM_SERVER_ID') ? ZM_SERVER_ID : '' ?>';
|
||||
const serverId = <?php echo defined('ZM_SERVER_ID') ? ZM_SERVER_ID : '0' ?>;
|
||||
const Servers = [];
|
||||
<?php
|
||||
// Fall back to get Server paths, etc when no using multi-server mode
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
<?php
|
||||
//
|
||||
// ZoneMinder web options view file, $Date$, $Revision$
|
||||
// Copyright (C) 2001-2008 Philip Coombes
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License
|
||||
// as published by the Free Software Foundation; either version 2
|
||||
// of the License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if (!canView('System')) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
|
||||
$canEdit = canEdit('System');
|
||||
|
||||
if ((!defined('ZM_OPT_USE_API')) or ZM_OPT_USE_API != '1') {
|
||||
echo '<div class="errorText">APIs are disabled. To enable, please turn on OPT_USE_API in Options->System</div>';
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<form name="userForm" method="post" action="?">
|
||||
<button class="float-left" type="submit" name="updateSelected" id="updateSelected"><?php echo translate('Update')?></button>
|
||||
<button class="float-left" type="button" id="btnNewToken"><?php echo translate('New Token')?></button>
|
||||
<button class="btn-danger float-right" type="submit" name="revokeAllTokens" id="revokeAllTokens"><?php echo translate('RevokeAllTokens')?></button>
|
||||
<br/>
|
||||
<?php
|
||||
function revokeAllTokens() {
|
||||
$minTokenTime = time();
|
||||
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=?', array($minTokenTime));
|
||||
echo '<span class="timedSuccessBox">'.translate('AllTokensRevoked').'</span>';
|
||||
}
|
||||
|
||||
function updateSelected() {
|
||||
# Turn them all off, then selectively turn the checked ones back on
|
||||
dbQuery('UPDATE `Users` SET `APIEnabled`=0');
|
||||
|
||||
if (isset($_REQUEST['tokenUids'])) {
|
||||
$minTime = time();
|
||||
foreach ($_REQUEST['tokenUids'] as $markUid) {
|
||||
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $markUid));
|
||||
}
|
||||
}
|
||||
if (isset($_REQUEST['apiUids'])) {
|
||||
foreach ($_REQUEST['apiUids'] as $markUid) {
|
||||
dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid));
|
||||
}
|
||||
}
|
||||
echo '<span class="timedSuccessBox">'.translate('Updated').'</span>';
|
||||
}
|
||||
|
||||
if (array_key_exists('revokeAllTokens', $_POST)) {
|
||||
revokeAllTokens();
|
||||
}
|
||||
|
||||
if (array_key_exists('updateSelected', $_POST)) {
|
||||
updateSelected();
|
||||
}
|
||||
?>
|
||||
<br/><br/>
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
||||
<input type="hidden" name="action" value="delete"/>
|
||||
<table id="contentTable" class="table table-striped">
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
<th class="colUsername"><?php echo translate('Username') ?></th>
|
||||
<th class="colMark"><?php echo translate('Revoke Token') ?></th>
|
||||
<th class="colMark"><?php echo translate('API Enabled') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
foreach (ZM\User::find([], ['order'=>'Username']) as $u) {
|
||||
?>
|
||||
<tr>
|
||||
<td class="colUsername"><?php echo validHtmlStr($u->Username()) ?></td>
|
||||
<td class="colMark"><input type="checkbox" name="tokenUids[]" value="<?php echo $u->Id() ?>" /></td>
|
||||
<td class="colMark"><input type="checkbox" name="apiUids[]" value="<?php echo $u->Id() ?>" <?php echo $u->APIEnabled()?'checked':''?> /></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
|
@ -164,8 +164,8 @@ if ( $show_storage_areas ) $left_columns += 1;
|
|||
|
||||
xhtmlHeaders(__FILE__, translate('Console'));
|
||||
getBodyTopHTML();
|
||||
?>
|
||||
<?php echo $navbar ?>
|
||||
echo $navbar ?>
|
||||
<div id="page">
|
||||
<div id="content">
|
||||
<form name="monitorForm" method="post" action="?view=<?php echo $view; ?>">
|
||||
<input type="hidden" name="action" value=""/>
|
||||
|
@ -174,7 +174,7 @@ getBodyTopHTML();
|
|||
<?php echo $filterbar ?>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid pt-2">
|
||||
<div class="container-fluid pt-2" id="contentButtons">
|
||||
<div class="statusBreakdown float-left">
|
||||
<?php
|
||||
$html = '';
|
||||
|
@ -213,10 +213,11 @@ getBodyTopHTML();
|
|||
</button>
|
||||
|
||||
<a href="#"><i id="fbflip" class="material-icons md-18">keyboard_arrow_<?php echo ( isset($_COOKIE['zmFilterBarFlip']) and $_COOKIE['zmFilterBarFlip'] == 'down') ? 'down' : 'up' ?></i></a>
|
||||
</div><!-- contentButtons -->
|
||||
<?php
|
||||
ob_start();
|
||||
?>
|
||||
<div class="table-responsive-sm pt-2">
|
||||
<div class="container-fluid table-responsive-sm pt-2" id="monitorList">
|
||||
<table class="table table-striped table-hover table-condensed consoleTable">
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
|
@ -449,10 +450,10 @@ for ($monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1) {
|
|||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- content table responsive div -->
|
||||
</form>
|
||||
</div><!--content-->
|
||||
</div><!--page-->
|
||||
<?php
|
||||
xhtmlFooter();
|
||||
?>
|
||||
|
|
|
@ -28,9 +28,9 @@ $controls = dbFetchAll('SELECT * FROM Controls ORDER BY Name');
|
|||
$focusWindow = true;
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('ControlCaps'));
|
||||
getBodyTopHTML();
|
||||
echo getNavBarHTML();
|
||||
?>
|
||||
<body>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="page">
|
||||
|
||||
<!-- Toolbar button placement and styling handled by bootstrap-tables -->
|
||||
|
@ -43,6 +43,7 @@ xhtmlHeaders(__FILE__, translate('ControlCaps'));
|
|||
</div>
|
||||
|
||||
<div id="content" class="table-responsive-sm">
|
||||
<div id="controls">
|
||||
<table
|
||||
id="controlTable"
|
||||
data-locale="<?php echo i18n() ?>"
|
||||
|
@ -95,6 +96,7 @@ foreach( $controls as $control ) {
|
|||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div><!--controls-->
|
||||
</div>
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -42,8 +42,8 @@ foreach ( $Groups as $id=>$Group ) {
|
|||
$max_depth = $Group->depth();
|
||||
}
|
||||
xhtmlHeaders(__FILE__, translate('Groups'));
|
||||
getBodyTopHTML();
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
<?php echo $navbar = getNavBarHTML(); ?>
|
||||
<div id="content">
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
var form = $j('#monitorPresetForm');
|
||||
|
||||
function submitPreset( element ) {
|
||||
form.target = opener.name;
|
||||
form.view.value = 'monitor';
|
||||
form.submit();
|
||||
}
|
||||
|
||||
function configureButtons() {
|
||||
const form = document.getElementById('monitorPresetForm');
|
||||
form.saveBtn.disabled = (form.preset.selectedIndex==0);
|
||||
}
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ function findFrameByTime(arr, time) {
|
|||
//console.log(keys);
|
||||
//console.log(keys[start]);
|
||||
// Iterate while start not meets end
|
||||
//console.log("Looking for "+ time+ "start: " + start + ' end ' + end, arr[keys[start]]);
|
||||
//console.log("Looking for "+ time+ "start: " + start + ' end ' + end, arr[keys[start]]);
|
||||
while ((start <= end)) {
|
||||
//&& arr[keys[start]] && (arr[keys[start]].TimeStampSecs <= time) && (arr[keys[end]].NextTimeStampSecs >= time)) {
|
||||
// Find the mid index
|
||||
|
@ -101,7 +101,7 @@ function findFrameByTime(arr, time) {
|
|||
(!frame.NextTimeStampSecs) || // only if event.EndTime is null
|
||||
(frame.NextTimeStampSecs > time)
|
||||
)
|
||||
) {
|
||||
) {
|
||||
//console.log("Found it at ", frame);
|
||||
return frame;
|
||||
|
||||
|
@ -172,21 +172,18 @@ function getFrame(monId, time, last_Frame) {
|
|||
}
|
||||
}
|
||||
if (!Event) return;
|
||||
let Frame = null;
|
||||
|
||||
if (!Event.FramesById) {
|
||||
console.log('No FramesById for event ', Event.Id);
|
||||
load_Frames(Event).then(function() {
|
||||
load_Frames([Event]).then(function() {
|
||||
if (!Event.FramesById) {
|
||||
console.log("No FramesById after load_Frames!", Event);
|
||||
}
|
||||
let Frame = null;
|
||||
Frame = findFrameByTime(Event.FramesById, time);
|
||||
console.log('Frame', Frame, time);
|
||||
let Frame = findFrameByTime(Event.FramesById, time);
|
||||
return Frame;
|
||||
}, function(Error) {
|
||||
console.log(Error);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -194,7 +191,7 @@ function getFrame(monId, time, last_Frame) {
|
|||
// Frames are sorted in descreasing order (or not sorted).
|
||||
// This is likely not efficient. Would be better to start at the last frame viewed, see if it is still relevant
|
||||
// Then move forward or backwards as appropriate
|
||||
Frame = findFrameByTime(Event.FramesById, time);
|
||||
let Frame = findFrameByTime(Event.FramesById, time);
|
||||
if (!Frame) {
|
||||
console.log("Didn't find frame by binary search");
|
||||
for (const frame_id in Event.FramesById) {
|
||||
|
@ -223,30 +220,30 @@ function getFrame(monId, time, last_Frame) {
|
|||
|
||||
// time is seconds since epoch
|
||||
function getImageSource(monId, time) {
|
||||
if ( liveMode == 1 ) {
|
||||
var new_url = monitorImageObject[monId].src.replace(
|
||||
if (liveMode == 1) {
|
||||
let new_url = monitorImageObject[monId].src.replace(
|
||||
/rand=\d+/i,
|
||||
'rand='+Math.floor(Math.random() * 1000000)
|
||||
);
|
||||
if ( auth_hash ) {
|
||||
if (auth_hash) {
|
||||
// update auth hash
|
||||
new_url = new_url.replace(/auth=[a-z0-9]+/i, 'auth='+auth_hash);
|
||||
}
|
||||
return new_url;
|
||||
}
|
||||
var frame_id;
|
||||
let frame_id;
|
||||
|
||||
var Frame = getFrame(monId, time);
|
||||
if ( Frame ) {
|
||||
const Frame = getFrame(monId, time);
|
||||
if (Frame) {
|
||||
const e = events[Frame.EventId];
|
||||
// Adjust for bulk frames
|
||||
if ( Frame.NextFrameId ) {
|
||||
var e = events[Frame.EventId];
|
||||
var NextFrame = e.FramesById[Frame.NextFrameId];
|
||||
if ( !NextFrame ) {
|
||||
if (Frame.NextFrameId) {
|
||||
const NextFrame = e.FramesById[Frame.NextFrameId];
|
||||
if (!NextFrame) {
|
||||
console.log("No next frame for " + Frame.NextFrameId);
|
||||
} else if ( NextFrame.Type == 'Bulk' ) {
|
||||
} else if (NextFrame.Type == 'Bulk') {
|
||||
// There is time between this frame and a bulk frame
|
||||
var duration = Frame.NextTimeStampSecs - Frame.TimeStampSecs;
|
||||
const duration = Frame.NextTimeStampSecs - Frame.TimeStampSecs;
|
||||
frame_id = Frame.FrameId + parseInt( (NextFrame.FrameId-Frame.FrameId) * ( time-Frame.TimeStampSecs )/duration );
|
||||
//console.log("Have NextFrame: duration: " + duration + " frame_id = " + frame_id + " from " + NextFrame.FrameId + ' - ' + Frame.FrameId + " time: " + (time-Frame.TimeStampSecs) );
|
||||
} else {
|
||||
|
@ -255,24 +252,18 @@ function getImageSource(monId, time) {
|
|||
} else {
|
||||
frame_id = Frame.FrameId;
|
||||
}
|
||||
Event = events[Frame.EventId];
|
||||
|
||||
var storage = Storage[Event.StorageId];
|
||||
if ( !storage ) {
|
||||
// Storage[0] is guaranteed to exist as we make sure it is there in montagereview.js.php
|
||||
console.log("No storage area for id " + Event.StorageId);
|
||||
storage = Storage[0];
|
||||
}
|
||||
// Storage[0] is guaranteed to exist as we make sure it is there in montagereview.js.php
|
||||
const storage = Storage[e.StorageId] ? Storage[e.StorageId] : Storage[0];
|
||||
// monitorServerId may be 0, which gives us the default Server entry
|
||||
var server = storage.ServerId ? Servers[storage.ServerId] : Servers[monitorServerId[monId]];
|
||||
const server = storage.ServerId ? Servers[storage.ServerId] : Servers[monitorServerId[monId]];
|
||||
return server.PathToIndex +
|
||||
'?view=image&eid=' + Frame.EventId + '&fid='+frame_id +
|
||||
"&width=" + monitorCanvasObj[monId].width +
|
||||
"&height=" + monitorCanvasObj[monId].height;
|
||||
} // end found Frame
|
||||
return '';
|
||||
//return "no data";
|
||||
}
|
||||
} // end function getImageSource
|
||||
|
||||
// callback when loading an image. Will load itself to the canvas, or draw no data
|
||||
function imagedone( obj, monId, success ) {
|
||||
|
@ -536,7 +527,7 @@ function drawGraph() {
|
|||
var x1=parseInt( (Frame.TimeStampSecs - minTimeSecs) / rangeTimeSecs * cWidth); // round low end down
|
||||
var x2=parseInt( (Frame.TimeStampSecs - minTimeSecs) / rangeTimeSecs * cWidth + 0.5 ); // round up
|
||||
if (x2-x1 < 2) x2=x1+2; // So it is visible make them all at least this number of seconds wide
|
||||
ctx.fillStyle=monitorColour[Event.MonitorId];
|
||||
//ctx.fillStyle=monitorColour[Event.MonitorId];
|
||||
ctx.globalAlpha = 0.4 + 0.6 * (1 - Frame.Score/maxScore); // Background is scaled but even lowest is twice as dark as the background
|
||||
ctx.fillRect(x1, monitorIndex[Event.MonitorId]*rowHeight, x2-x1, rowHeight);
|
||||
} // end foreach frame
|
||||
|
@ -603,6 +594,7 @@ function redrawScreen() {
|
|||
scaleDiv.hide();
|
||||
fit.text('Scale');
|
||||
monitors.height(mh.toString() + 'px'); // leave a small gap at bottom
|
||||
|
||||
if (maxfit2(monitors.outerWidth(), monitors.outerHeight()) == 0) { /// if we fail to fix we back out of fit mode -- ??? This may need some better handling
|
||||
console.log("Failed to fit, dropping back to scaled mode");
|
||||
fitMode=1-fitMode;
|
||||
|
@ -610,17 +602,17 @@ function redrawScreen() {
|
|||
} else {
|
||||
// switch out of fit mode
|
||||
// if we fit, then monitors were absolutely positioned already (or will be) otherwise release them to float
|
||||
for ( var i=0; i<numMonitors; i++ ) {
|
||||
monitorCanvasObj[monitorPtr[i]].style.position="";
|
||||
for (let i=0; i<numMonitors; i++) {
|
||||
monitorCanvasObj[monitorPtr[i]].style.position = '';
|
||||
}
|
||||
monitors.height('auto');
|
||||
monitors.height('');
|
||||
scaleDiv.show();
|
||||
fit.text('fit');
|
||||
setScale(currentScale);
|
||||
}
|
||||
outputUpdate(currentTimeSecs);
|
||||
timerFire(); // force a fire in case it's not timing
|
||||
}
|
||||
} // end function redrawScreen
|
||||
|
||||
function outputUpdate(time) {
|
||||
drawSliderOnGraph(time);
|
||||
|
@ -864,7 +856,7 @@ function click_all_events() {
|
|||
function allnon() {
|
||||
clicknav(0, 0, 0);
|
||||
}
|
||||
/// >>>>>>>>>>>>>>>>> handles packing different size/aspect monitors on screen <<<<<<<<<<<<<<<<<<<<<<<<
|
||||
/// handles packing different size/aspect monitors on screen
|
||||
|
||||
function compSize(a, b) { // sort array by some size parameter - height seems to work best. A semi-greedy algorithm
|
||||
var a_value = monitorHeight[a] * monitorWidth[a] * monitorNormalizeScale[a] * monitorZoomScale[a] * monitorNormalizeScale[a] * monitorZoomScale[a];
|
||||
|
@ -1086,18 +1078,8 @@ function changeDateTime(e) {
|
|||
// >>>>>>>>> Initialization that runs on window load by being at the bottom
|
||||
|
||||
function initPage() {
|
||||
jQuery(document).ready(function() {
|
||||
jQuery("#hdrbutton").click(function() {
|
||||
jQuery("#flipMontageHeader").slideToggle("slow");
|
||||
jQuery("#hdrbutton").toggleClass('glyphicon-menu-down').toggleClass('glyphicon-menu-up');
|
||||
});
|
||||
});
|
||||
|
||||
for (const event_id in events) {
|
||||
load_Frames(events[event_id]);
|
||||
}
|
||||
|
||||
if ( !liveMode ) {
|
||||
if (!liveMode) {
|
||||
load_Frames(events);
|
||||
canvas = document.getElementById('timeline');
|
||||
|
||||
canvas.addEventListener('mousemove', mmove, false);
|
||||
|
@ -1106,7 +1088,7 @@ function initPage() {
|
|||
canvas.addEventListener('mouseup', mup, false);
|
||||
canvas.addEventListener('mouseout', mout, false);
|
||||
|
||||
ctx = canvas.getContext('2d');
|
||||
ctx = canvas.getContext('2d', { willReadFrequently: true });
|
||||
drawGraph();
|
||||
}
|
||||
|
||||
|
@ -1184,10 +1166,10 @@ function initPage() {
|
|||
el = $j(this);
|
||||
//el.on('change', changeDateTime());
|
||||
if (el.hasClass('datetimepicker')) {
|
||||
el.datetimepicker({timeFormat: "HH:mm:ss", dateFormat: "yy-mm-dd", maxDate: 0, constrainInput: false})
|
||||
el.datetimepicker({timeFormat: "HH:mm:ss", dateFormat: "yy-mm-dd", maxDate: 0, constrainInput: false});
|
||||
}
|
||||
if (el.hasClass('datepicker')) {
|
||||
el.datepicker({dateFormat: "yy-mm-dd", maxDate: 0, constrainInput: false})
|
||||
el.datepicker({dateFormat: "yy-mm-dd", maxDate: 0, constrainInput: false});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1204,7 +1186,7 @@ function takeSnapshot() {
|
|||
server = new Server(Servers[serverId]);
|
||||
$j.ajax({
|
||||
method: 'POST',
|
||||
url: server.UrlToApi()+'/snapshots.json' + (auth_relay ? '?' + auth_relay : ''),
|
||||
url: server.urlToApi()+'/snapshots.json' + (auth_relay ? '?' + auth_relay : ''),
|
||||
data: { 'monitor_ids[]': monitorIndex.keys()},
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
|
@ -1219,46 +1201,61 @@ window.addEventListener("resize", redrawScreen, {passive: true});
|
|||
// Kick everything off
|
||||
window.addEventListener('DOMContentLoaded', initPage);
|
||||
|
||||
function load_Frames(zm_event) {
|
||||
function load_Frames(zm_events) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
$j.getJSON(Servers[serverId].UrlToApi()+'/frames/index/EventId:'+zm_event.Id+'.json?'+auth_relay)
|
||||
.done(function(data) {
|
||||
if (data.frames.length) {
|
||||
/*
|
||||
const zm_event = events[data.frames[0].Frame.EventId];
|
||||
if (!zm_event) {
|
||||
console.error("No event object found for " + data.frames[0].Frame.EventId);
|
||||
reject(Error("There was an error"));
|
||||
return;
|
||||
}
|
||||
*/
|
||||
zm_event.FramesById = [];
|
||||
let last_frame = null;
|
||||
let url = Servers[serverId].urlToApi()+'/frames/index';
|
||||
|
||||
for (let i=0, len=data.frames.length; i<len; i++) {
|
||||
const frame = data.frames[i].Frame;
|
||||
// new Date uses browser TZ unless specified in string, so append the server offset
|
||||
date = new Date(frame.TimeStamp+(server_utc_offset/3600));
|
||||
frame.TimeStampSecs = new Date(date.getTime() + frame.Delta * 1000).getTime() / 1000;
|
||||
//console.log(date, frame.TimeStamp, frame.Delta, frame.TimeStampSecs);
|
||||
if (last_frame) {
|
||||
frame.PrevFrameId = last_frame.Id;
|
||||
last_frame.NextFrameId = frame.Id;
|
||||
last_frame.NextTimeStampSecs = frame.TimeStampSecs;
|
||||
let query = '';
|
||||
let ids = Object.keys(zm_events);
|
||||
|
||||
while (ids.length) {
|
||||
const event_id = ids.shift();
|
||||
const zm_event = zm_events[event_id];
|
||||
|
||||
query += '/EventId:'+zm_event.Id;
|
||||
if (!ids.length || (query.length > 1000)) {
|
||||
$j.ajax(url+query+'.json?'+auth_relay,
|
||||
{
|
||||
timeout: 0,
|
||||
success: function(data) {
|
||||
if (data.frames.length) {
|
||||
zm_event.FramesById = [];
|
||||
let last_frame = null;
|
||||
|
||||
for (let i=0, len=data.frames.length; i<len; i++) {
|
||||
const frame = data.frames[i].Frame;
|
||||
const zm_event = events[frame.EventId];
|
||||
if (!zm_event) {
|
||||
console.error("No event object found for " + data.frames[0].Frame.EventId);
|
||||
continue;
|
||||
}
|
||||
// new Date uses browser TZ unless specified in string, so append the server offset
|
||||
date = new Date(frame.TimeStamp+(server_utc_offset/3600));
|
||||
frame.TimeStampSecs = new Date(date.getTime() + frame.Delta * 1000).getTime() / 1000;
|
||||
//console.log(date, frame.TimeStamp, frame.Delta, frame.TimeStampSecs);
|
||||
if (last_frame) {
|
||||
frame.PrevFrameId = last_frame.Id;
|
||||
last_frame.NextFrameId = frame.Id;
|
||||
last_frame.NextTimeStampSecs = frame.TimeStampSecs;
|
||||
}
|
||||
last_frame = frame;
|
||||
|
||||
if (!zm_event.FramesById) zm_event.FramesById = [];
|
||||
zm_event.FramesById[frame.Id] = frame;
|
||||
} // end fireach frame
|
||||
} // end if there are frames
|
||||
drawGraph();
|
||||
resolve();
|
||||
},
|
||||
error: function() {
|
||||
logAjaxFail;
|
||||
reject(Error("There was an error"));
|
||||
}
|
||||
last_frame = frame;
|
||||
|
||||
zm_event.FramesById[frame.Id] = frame;
|
||||
} // end fireach frame
|
||||
} // end if there are frames
|
||||
drawGraph();
|
||||
resolve();
|
||||
})
|
||||
.fail(function() {
|
||||
logAjaxFail;
|
||||
reject(Error("There was an error"));
|
||||
}
|
||||
);
|
||||
}
|
||||
); // end ajax
|
||||
query = '';
|
||||
} // end if query string is too long
|
||||
} // end while zm_events.legtnh
|
||||
} // end Promise
|
||||
);
|
||||
} // end function load_Frames(Event)
|
||||
} // end function load_Frames(Event)
|
||||
|
|
|
@ -22,7 +22,6 @@ global $minTime;
|
|||
global $maxTime;
|
||||
global $monitors;
|
||||
global $eventsSql;
|
||||
global $framesSql;
|
||||
?>
|
||||
|
||||
var currentScale=<?php echo $defaultScale?>;
|
||||
|
@ -64,31 +63,8 @@ if (!$liveMode) {
|
|||
|
||||
$EventsById = array();
|
||||
while ( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
|
||||
$event_id = $event['Id'];
|
||||
$EventsById[$event_id] = $event;
|
||||
$EventsById[$event['Id']] = $event;
|
||||
}
|
||||
$next_frames = array();
|
||||
if ( 0 ) {
|
||||
if ( $result = dbQuery($framesSql) ) {
|
||||
$next_frame = null;
|
||||
while ( $frame = $result->fetch(PDO::FETCH_ASSOC) ) {
|
||||
$event_id = $frame['EventId'];
|
||||
$event = &$EventsById[$event_id];
|
||||
|
||||
$frame['TimeStampSecs'] = $event['StartTimeSecs'] + $frame['Delta'];
|
||||
if ( !isset($event['FramesById']) ) {
|
||||
// Please note that this is the last frame as we sort DESC
|
||||
$event['FramesById'] = array();
|
||||
$frame['NextTimeStampSecs'] = $event['EndTimeSecs'];
|
||||
} else {
|
||||
$frame['NextTimeStampSecs'] = $next_frames[$frame['EventId']]['TimeStampSecs'];
|
||||
$frame['NextFrameId'] = $next_frames[$frame['EventId']]['Id'];
|
||||
}
|
||||
$event['FramesById'] += array($frame['Id']=>$frame);
|
||||
$next_frames[$frame['EventId']] = &$event['FramesById'][$frame['Id']];
|
||||
}
|
||||
} // end if dbQuery
|
||||
}
|
||||
|
||||
$events_by_monitor_id = array();
|
||||
|
||||
|
@ -111,8 +87,8 @@ if ( 0 ) {
|
|||
$maxScore = $event['MaxScore'];
|
||||
$anyAlarms = true;
|
||||
}
|
||||
if ( !isset($events_by_monitor_id[$event['MonitorId']]) )
|
||||
$events_by_monitor_id[$event['MonitorId']] = array();
|
||||
if (!isset($events_by_monitor_id[$event['MonitorId']]))
|
||||
$events_by_monitor_id[$event['MonitorId']] = array();
|
||||
array_push($events_by_monitor_id[$event['MonitorId']], $event_id);
|
||||
} # end foreach Event
|
||||
echo ' };
|
||||
|
|
|
@ -24,10 +24,9 @@ if ( !canView('System') ) {
|
|||
}
|
||||
|
||||
xhtmlHeaders(__FILE__, translate('SystemLog'));
|
||||
?>
|
||||
<body>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="page" class="px-3 table-responsive-sm">
|
||||
getBodyTopHTML();
|
||||
echo getNavBarHTML() ?>
|
||||
<div id="content" class="px-3 table-responsive-sm">
|
||||
|
||||
<div id="logSummary" class="text-center">
|
||||
<?php echo translate('State') ?>: <span id="logState"></span> -
|
||||
|
@ -36,7 +35,7 @@ xhtmlHeaders(__FILE__, translate('SystemLog'));
|
|||
<?php echo translate('Displaying') ?>: <span id="displayLogs"></span> -
|
||||
<?php echo translate('Updated') ?>: <span id="lastUpdate"></span>
|
||||
</div>
|
||||
|
||||
<div id="logsTable">
|
||||
<div id="toolbar">
|
||||
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
|
||||
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
|
||||
|
@ -124,5 +123,6 @@ echo htmlSelect('filterLevel', $levels,
|
|||
</tbody>
|
||||
|
||||
</table>
|
||||
</div><!--page-->
|
||||
</div><!--logstable-->
|
||||
</div><!--content-->
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -364,7 +364,7 @@ getBodyTopHTML();
|
|||
echo getNavBarHTML();
|
||||
?>
|
||||
<div id="page" class="container-fluid">
|
||||
<div class="row flex-nowrap">
|
||||
<div id="content" class="row flex-nowrap">
|
||||
<nav> <!-- BEGIN PILL LIST -->
|
||||
<ul class="nav nav-pills flex-column h-100" id="pills-tab" role="tablist" aria-orientation="vertical">
|
||||
<?php
|
||||
|
@ -441,7 +441,7 @@ if (canEdit('Monitors')) {
|
|||
</div>
|
||||
|
||||
<!-- BEGIN ITEM LIST -->
|
||||
<div class="d-flex flex-row container-fluid pr-0">
|
||||
<div class="d-flex flex-row container-fluid pr-0" id="monitor">
|
||||
<form name="contentForm" id="contentForm" method="post" action="?view=monitor" autocomplete="off">
|
||||
<input type="hidden" name="tab" value="<?php echo $tab?>"/>
|
||||
<input type="hidden" name="mid" value="<?php echo $monitor->Id() ? $monitor->Id() : $mid ?>"/>
|
||||
|
|
|
@ -18,18 +18,11 @@
|
|||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
//
|
||||
|
||||
if ( !canEdit( 'Monitors' ) )
|
||||
{
|
||||
$view = "error";
|
||||
return;
|
||||
}
|
||||
$sql = "select Id,Name from MonitorPresets";
|
||||
$presets = array();
|
||||
$presets[0] = translate('ChoosePreset');
|
||||
foreach( dbFetchAll( $sql ) as $preset )
|
||||
{
|
||||
$presets[$preset['Id']] = htmlentities( $preset['Name'] );
|
||||
if (!canEdit('Monitors')) {
|
||||
$view = 'error';
|
||||
return;
|
||||
}
|
||||
$mid = isset($_REQUEST['mid']) ? validInt($_REQUEST['mid']) : 0;
|
||||
|
||||
$focusWindow = true;
|
||||
|
||||
|
@ -38,20 +31,27 @@ xhtmlHeaders(__FILE__, translate('MonitorPreset') );
|
|||
<body>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="page">
|
||||
<h2><?php echo translate('MonitorPreset') ?></h2>
|
||||
<h2><?php echo translate('MonitorPreset') ?></h2>
|
||||
<div id="content">
|
||||
<form name="contentForm" id="monitorPresetForm" method="post" action="?">
|
||||
<input type="hidden" name="view" value="none"/>
|
||||
<input type="hidden" name="mid" value="<?php echo validNum($_REQUEST['mid']) ?>"/>
|
||||
<input type="hidden" name="view" value="monitor"/>
|
||||
<input type="hidden" name="mid" value="<?php echo $mid ?>"/>
|
||||
<p>
|
||||
<?php echo translate('MonitorPresetIntro') ?>
|
||||
</p>
|
||||
<p>
|
||||
<label for="preset"><?php echo translate('Preset') ?></label><?php echo buildSelect( "preset", $presets ); ?>
|
||||
<label for="preset"><?php echo translate('Preset') ?></label>
|
||||
<?php
|
||||
$presets = array();
|
||||
$presets[0] = translate('ChoosePreset');
|
||||
foreach (dbFetchAll('SELECT Id,Name FROM MonitorPresets ORDER BY Name') as $preset) {
|
||||
$presets[$preset['Id']] = htmlentities( $preset['Name'] );
|
||||
}
|
||||
echo buildSelect('preset', $presets); ?>
|
||||
</p>
|
||||
<div id="contentButtons">
|
||||
<input type="submit" name="saveBtn" value="<?php echo translate('Save') ?>" data-on-click-this="submitPreset" disabled="disabled"/>
|
||||
<input type="button" value="<?php echo translate('Cancel') ?>" data-on-click="backWindow"/>
|
||||
<button type="submit" name="saveBtn" value="preset" disabled="disabled"><?php echo translate('Save') ?></button>
|
||||
<button type="button" data-on-click="backWindow"><?php echo translate('Cancel') ?></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -159,30 +159,15 @@ $eventsSql = 'SELECT
|
|||
WHERE 1 > 0
|
||||
';
|
||||
|
||||
// select E.Id,E.Name,UNIX_TIMESTAMP(E.StartDateTime) as StartTimeSecs,UNIX_TIMESTAMP(max(DATE_ADD(E.StartDateTime, Interval Delta+0.5 Second))) as CalcEndTimeSecs, E.Length,max(F.FrameId) as Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId
|
||||
// from Events as E
|
||||
// inner join Monitors as M on (E.MonitorId = M.Id)
|
||||
// inner join Frames F on F.EventId=E.Id
|
||||
// where not isnull(E.Frames) and not isnull(StartDateTime) ";
|
||||
|
||||
// Note that the delta value seems more accurate than the time stamp for some reason.
|
||||
$framesSql = '
|
||||
SELECT Id, FrameId, EventId, TimeStamp, UNIX_TIMESTAMP(TimeStamp) AS TimeStampSecs, Score, Delta, Type
|
||||
FROM Frames
|
||||
WHERE EventId IN (SELECT E.Id FROM Events AS E WHERE 1>0
|
||||
';
|
||||
|
||||
// This program only calls itself with the time range involved -- it does all monitors (the user can see, in the called group) all the time
|
||||
|
||||
$monitor_ids_sql = '';
|
||||
if ( !empty($user['MonitorIds']) ) {
|
||||
$eventsSql .= ' AND E.MonitorId IN ('.$user['MonitorIds'].')';
|
||||
$framesSql .= ' AND E.MonitorId IN ('.$user['MonitorIds'].')';
|
||||
}
|
||||
if ( count($selected_monitor_ids) ) {
|
||||
$monitor_ids_sql = ' IN (' . implode(',',$selected_monitor_ids).')';
|
||||
$eventsSql .= ' AND E.MonitorId '.$monitor_ids_sql;
|
||||
$framesSql .= ' AND E.MonitorId '.$monitor_ids_sql;
|
||||
}
|
||||
if ( isset($_REQUEST['archive_status']) ) {
|
||||
$_SESSION['archive_status'] = $_REQUEST['archive_status'];
|
||||
|
@ -190,14 +175,11 @@ if ( isset($_REQUEST['archive_status']) ) {
|
|||
if ( isset($_SESSION['archive_status']) ) {
|
||||
if ( $_SESSION['archive_status'] == 'Archived' ) {
|
||||
$eventsSql .= ' AND E.Archived=1';
|
||||
$framesSql .= ' AND E.Archived=1';
|
||||
} else if ( $_SESSION['archive_status'] == 'Unarchived' ) {
|
||||
$eventsSql .= ' AND E.Archived=0';
|
||||
$framesSql .= ' AND E.Archived=0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$fitMode = 1;
|
||||
if ( isset($_REQUEST['fit']) && ($_REQUEST['fit'] == '0') )
|
||||
$fitMode = 0;
|
||||
|
@ -222,7 +204,6 @@ for ( $i = 0; $i < count($speeds); $i++ ) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
$liveMode = 1; // default to live
|
||||
if ( isset($_REQUEST['live']) && ($_REQUEST['live'] == '0') )
|
||||
$liveMode = 0;
|
||||
|
@ -231,8 +212,6 @@ $initialDisplayInterval = 1000;
|
|||
if ( isset($_REQUEST['displayinterval']) )
|
||||
$initialDisplayInterval = validHtmlStr($_REQUEST['displayinterval']);
|
||||
|
||||
#$eventsSql .= ' GROUP BY E.Id,E.Name,E.StartDateTime,E.Length,E.Frames,E.MaxScore,E.Cause,E.Notes,E.Archived,E.MonitorId';
|
||||
|
||||
$minTimeSecs = $maxTimeSecs = 0;
|
||||
if ( isset($minTime) && isset($maxTime) ) {
|
||||
if ($minTime >= $maxTime) {
|
||||
|
@ -246,16 +225,8 @@ if ( isset($minTime) && isset($maxTime) ) {
|
|||
$minTimeSecs = strtotime($minTime);
|
||||
$maxTimeSecs = strtotime($maxTime);
|
||||
$eventsSql .= " AND EndDateTime > '" . $minTime . "' AND StartDateTime < '" . $maxTime . "'";
|
||||
$framesSql .= " AND EndDateTime > '" . $minTime . "' AND StartDateTime < '" . $maxTime . "'";
|
||||
$framesSql .= ") AND TimeStamp > '" . $minTime . "' AND TimeStamp < '" . $maxTime . "'";
|
||||
} else {
|
||||
$framesSql .= ')';
|
||||
}
|
||||
#$framesSql .= ' GROUP BY E.Id, E.MonitorId, F.TimeStamp, F.Delta ORDER BY E.MonitorId, F.TimeStamp ASC';
|
||||
#$framesSql .= ' GROUP BY E.Id, E.MonitorId, F.TimeStamp, F.Delta ORDER BY E.MonitorId, F.TimeStamp ASC';
|
||||
$eventsSql .= ' ORDER BY E.Id ASC';
|
||||
// DESC is intentional. We process them in reverse order so that we can point each frame to the next one in time.
|
||||
$framesSql .= ' ORDER BY Id DESC';
|
||||
|
||||
$monitors = array();
|
||||
foreach ($displayMonitors as $row) {
|
||||
|
@ -272,11 +243,17 @@ getBodyTopHTML();
|
|||
?>
|
||||
<div id="page">
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="content">
|
||||
<form id="montagereview_form" action="?" method="get">
|
||||
<input type="hidden" name="view" value="montagereview"/>
|
||||
<div id="header">
|
||||
<a href="#"><span id="hdrbutton" class="glyphicon glyphicon-menu-up pull-right"></span></a>
|
||||
<div id="flipMontageHeader">
|
||||
<div id="header">
|
||||
<?php
|
||||
$html = '';
|
||||
$flip = ( (!isset($_COOKIE['zmMonitorFilterBarFlip'])) or ($_COOKIE['zmMonitorFilterBarFlip'] == 'down')) ? 'up' : 'down';
|
||||
$html .= '<a class="flip" href="#"><i id="mfbflip" class="material-icons md-18">keyboard_arrow_' .$flip. '</i></a>'.PHP_EOL;
|
||||
$html .= '<div class="container-fluid" id="mfbpanel"'.( ( $flip == 'down' ) ? ' style="display:none;"' : '' ) .'>'.PHP_EOL;
|
||||
echo $html;
|
||||
?>
|
||||
<?php echo $filter_bar ?>
|
||||
<div id="DateTimeDiv">
|
||||
<input type="text" name="minTime" id="minTime" value="<?php echo preg_replace('/T/', ' ', $minTime ) ?>"/> to
|
||||
|
@ -351,6 +328,7 @@ getBodyTopHTML();
|
|||
?>
|
||||
</div>
|
||||
<p id="fps">evaluating fps</p>
|
||||
</div>
|
||||
</div><!--content-->
|
||||
</div><!--page-->
|
||||
<script src="<?php echo cache_bust('skins/classic/js/export.js') ?>"></script>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -56,10 +56,10 @@ xhtmlHeaders(__FILE__, translate('Options'));
|
|||
getBodyTopHTML();
|
||||
echo getNavBarHTML();
|
||||
?>
|
||||
<div class="container-fluid">
|
||||
<div class="row flex-nowrap">
|
||||
<div class="container-fluid" id="content">
|
||||
<div class="row flex-nowrap h-100">
|
||||
<nav id="sidebar">
|
||||
<ul class="nav nav-pills flex-column h-100">
|
||||
<ul class="nav nav-pills flex-column">
|
||||
<?php
|
||||
foreach ($tabs as $name=>$value) {
|
||||
?>
|
||||
|
@ -70,8 +70,6 @@ foreach ($tabs as $name=>$value) {
|
|||
</ul>
|
||||
</nav>
|
||||
<div class="container-fluid col-sm-offset-2 h-100 pr-0">
|
||||
<br/>
|
||||
<div id="options">
|
||||
<?php
|
||||
if ($tab == 'skins') {
|
||||
?>
|
||||
|
@ -332,79 +330,7 @@ foreach (array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as $
|
|||
</form>
|
||||
<?php
|
||||
} else if ($tab == 'API') {
|
||||
$apiEnabled = dbFetchOne('SELECT Value FROM Config WHERE Name=\'ZM_OPT_USE_API\'');
|
||||
if ($apiEnabled['Value'] != '1') {
|
||||
echo '<div class="errorText">APIs are disabled. To enable, please turn on OPT_USE_API in Options->System</div>';
|
||||
} else {
|
||||
?>
|
||||
|
||||
<form name="userForm" method="post" action="?">
|
||||
<button class="float-left" type="submit" name="updateSelected" id="updateSelected"><?php echo translate('Update')?></button>
|
||||
<button class="btn-danger float-right" type="submit" name="revokeAllTokens" id="revokeAllTokens"><?php echo translate('RevokeAllTokens')?></button>
|
||||
<br/>
|
||||
<?php
|
||||
function revokeAllTokens() {
|
||||
$minTokenTime = time();
|
||||
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=?', array($minTokenTime));
|
||||
echo '<span class="timedSuccessBox">'.translate('AllTokensRevoked').'</span>';
|
||||
}
|
||||
|
||||
function updateSelected() {
|
||||
# Turn them all off, then selectively turn the checked ones back on
|
||||
dbQuery('UPDATE `Users` SET `APIEnabled`=0');
|
||||
|
||||
if (isset($_REQUEST['tokenUids'])) {
|
||||
foreach ($_REQUEST['tokenUids'] as $markUid) {
|
||||
$minTime = time();
|
||||
dbQuery('UPDATE `Users` SET `TokenMinExpiry`=? WHERE `Id`=?', array($minTime, $markUid));
|
||||
}
|
||||
}
|
||||
if (isset($_REQUEST['apiUids'])) {
|
||||
foreach ($_REQUEST['apiUids'] as $markUid) {
|
||||
dbQuery('UPDATE `Users` SET `APIEnabled`=1 WHERE `Id`=?', array($markUid));
|
||||
}
|
||||
}
|
||||
echo '<span class="timedSuccessBox">'.translate('Updated').'</span>';
|
||||
}
|
||||
|
||||
if (array_key_exists('revokeAllTokens', $_POST)) {
|
||||
revokeAllTokens();
|
||||
}
|
||||
|
||||
if (array_key_exists('updateSelected', $_POST)) {
|
||||
updateSelected();
|
||||
}
|
||||
?>
|
||||
<br/><br/>
|
||||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
||||
<input type="hidden" name="action" value="delete"/>
|
||||
<table id="contentTable" class="table table-striped">
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
<th class="colUsername"><?php echo translate('Username') ?></th>
|
||||
<th class="colMark"><?php echo translate('Revoke Token') ?></th>
|
||||
<th class="colMark"><?php echo translate('API Enabled') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$sql = 'SELECT * FROM Users ORDER BY Username';
|
||||
foreach (dbFetchAll($sql) as $row) {
|
||||
?>
|
||||
<tr>
|
||||
<td class="colUsername"><?php echo validHtmlStr($row['Username']) ?></td>
|
||||
<td class="colMark"><input type="checkbox" name="tokenUids[]" value="<?php echo $row['Id'] ?>" /></td>
|
||||
<td class="colMark"><input type="checkbox" name="apiUids[]" value="<?php echo $row['Id']?>" <?php echo $row['APIEnabled']?'checked':''?> /></td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
<?php
|
||||
} // API enabled
|
||||
include('_options_api.php');
|
||||
} // $tab == API
|
||||
else {
|
||||
$config = array();
|
||||
|
@ -475,6 +401,10 @@ foreach (array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as $
|
|||
<input type="hidden" name="view" value="<?php echo $view ?>"/>
|
||||
<input type="hidden" name="tab" value="<?php echo $tab ?>"/>
|
||||
<input type="hidden" name="action" value="options"/>
|
||||
<div id="contentButtons">
|
||||
<button type="submit" <?php echo $canEdit?'':' disabled="disabled"' ?>><?php echo translate('Save') ?></button>
|
||||
</div>
|
||||
<div id="options">
|
||||
<?php
|
||||
if (!isset($configCats[$tab])) {
|
||||
echo 'There are no config entries for category '.$tab.'.<br/>';
|
||||
|
@ -548,15 +478,12 @@ foreach (array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as $
|
|||
} # end foreach config entry in the category
|
||||
} # end if category exists
|
||||
?>
|
||||
<div id="contentButtons">
|
||||
<button type="submit" <?php echo $canEdit?'':' disabled="disabled"' ?>><?php echo translate('Save') ?></button>
|
||||
</div>
|
||||
</div><!--options-->
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div><!-- end #options -->
|
||||
</div>
|
||||
</div> <!-- end row -->
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -24,8 +24,6 @@ include('_monitor_filters.php');
|
|||
$filterbar = ob_get_contents();
|
||||
ob_end_clean();
|
||||
|
||||
noCacheHeaders();
|
||||
xhtmlHeaders( __FILE__, translate('Console'));
|
||||
|
||||
if ( isset($_REQUEST['minTime']) ) {
|
||||
$minTime = validHtmlStr($_REQUEST['minTime']);
|
||||
|
@ -105,20 +103,25 @@ while ( $event = $result->fetch(PDO::FETCH_ASSOC) ) {
|
|||
$EventsByMonitor[$event['MonitorId']]['Events'][] = $Event;
|
||||
} # end foreach event
|
||||
|
||||
noCacheHeaders();
|
||||
xhtmlHeaders( __FILE__, translate('Report Event Audit'));
|
||||
getBodyTopHTML();
|
||||
echo $navbar;
|
||||
?>
|
||||
<body>
|
||||
<?php echo $navbar ?>
|
||||
<form name="monitorForm" method="post" action="?view=<?php echo $view ?>">
|
||||
<div class="filterBar">
|
||||
<?php echo $filterbar ?>
|
||||
<div id="DateTimeDiv">
|
||||
<label><?php echo translate('Event Start Time') ?></label>
|
||||
<input type="text" name="minTime" id="minTime" value="<?php echo preg_replace('/T/', ' ', $minTime) ?>"/> <?php echo translate('to') ?>
|
||||
<input type="text" name="maxTime" id="maxTime" value="<?php echo preg_replace('/T/', ' ', $maxTime) ?>"/>
|
||||
</div>
|
||||
</div><!--FilterBar-->
|
||||
<div id="page">
|
||||
<div id="content">
|
||||
<form name="monitorForm" method="post" action="?view=<?php echo $view ?>">
|
||||
<div class="filterBar">
|
||||
<?php echo $filterbar ?>
|
||||
<div id="DateTimeDiv">
|
||||
<label><?php echo translate('Event Start Time') ?></label>
|
||||
<input type="text" name="minTime" id="minTime" value="<?php echo preg_replace('/T/', ' ', $minTime) ?>"/> <?php echo translate('to') ?>
|
||||
<input type="text" name="maxTime" id="maxTime" value="<?php echo preg_replace('/T/', ' ', $maxTime) ?>"/>
|
||||
</div>
|
||||
</div><!--FilterBar-->
|
||||
</form>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid" id="results">
|
||||
<table class="table table-striped table-hover table-condensed" id="consoleTable">
|
||||
<thead class="thead-highlight">
|
||||
<tr>
|
||||
|
@ -205,5 +208,6 @@ for ( $monitor_i = 0; $monitor_i < count($displayMonitors); $monitor_i += 1 ) {
|
|||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -38,10 +38,11 @@ if ( $user['MonitorIds'] ) {
|
|||
$monitor_ids = explode(',', $user['MonitorIds']);
|
||||
}
|
||||
xhtmlHeaders(__FILE__, translate('Snapshot').' '.$snapshot->Id());
|
||||
getBodyTopHTML();
|
||||
echo getNavBarHTML();
|
||||
?>
|
||||
<body>
|
||||
<div id="page">
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="content">
|
||||
<?php
|
||||
if ( !$snapshot->Id() ) {
|
||||
echo '<div class="error">Snapshot was not found.</div>';
|
||||
|
@ -66,7 +67,7 @@ if ( !$snapshot->Id() ) {
|
|||
|
||||
<h2><?php echo translate('Snapshot').' '.$snapshot->Id() ?></h2>
|
||||
</div>
|
||||
<div class="d-flex flex-row justify-content-between py-1">
|
||||
<div class="d-flex flex-row justify-content-between py-1" id="snapshot">
|
||||
<!--
|
||||
<div class="form-group"><label><?php echo translate('Created By') ?></label>
|
||||
-->
|
||||
|
@ -81,9 +82,10 @@ if ( !$snapshot->Id() ) {
|
|||
<textarea name="snapshot[Description]"><?php echo validHtmlStr($snapshot->Description()); ?></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php if ( $snapshot->Id() ) { ?>
|
||||
<!-- BEGIN VIDEO CONTENT ROW -->
|
||||
<div id="content" class="justify-content-center">
|
||||
<div id="video" class="row justify-content-center">
|
||||
<?php
|
||||
$events = $snapshot->Events();
|
||||
$width = 100 / ( count($events) < 2 ? 1 : ( ( count($events) < 4 ) ? count($events) : 4 ) )-1;
|
||||
|
@ -94,7 +96,6 @@ if ( !$snapshot->Id() ) {
|
|||
?>
|
||||
</div><!--content-->
|
||||
<?php } // end if snapshot->Id() ?>
|
||||
</form>
|
||||
<h2 id="downloadProgress" class="<?php
|
||||
if ( isset($_REQUEST['generated']) ) {
|
||||
if ( $_REQUEST['generated'] )
|
||||
|
@ -116,5 +117,6 @@ if ( !$snapshot->Id() ) {
|
|||
?></span>
|
||||
<span id="downloadProgressTicker"></span>
|
||||
</h2>
|
||||
</div>
|
||||
</div><!--page-->
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -34,62 +34,66 @@ getBodyTopHTML();
|
|||
|
||||
?>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
<div id="page" class="container-fluid p-3">
|
||||
<!-- Toolbar button placement and styling handled by bootstrap-tables -->
|
||||
<div id="toolbar">
|
||||
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
|
||||
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
|
||||
<!--<button id="filterBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Filter') ?>"><i class="fa fa-filter"></i></button>-->
|
||||
<!--<button id="exportBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Export') ?>" disabled><i class="fa fa-external-link"></i></button>-->
|
||||
<button id="deleteBtn" class="btn btn-danger" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Delete') ?>" disabled><i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
<div id="page">
|
||||
<div id="content">
|
||||
<!-- Toolbar button placement and styling handled by bootstrap-tables -->
|
||||
<div id="toolbar">
|
||||
<button id="backBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Back') ?>" disabled><i class="fa fa-arrow-left"></i></button>
|
||||
<button id="refreshBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Refresh') ?>" ><i class="fa fa-refresh"></i></button>
|
||||
<!--<button id="filterBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Filter') ?>"><i class="fa fa-filter"></i></button>-->
|
||||
<!--<button id="exportBtn" class="btn btn-normal" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Export') ?>" disabled><i class="fa fa-external-link"></i></button>-->
|
||||
<button id="deleteBtn" class="btn btn-danger" data-toggle="tooltip" data-placement="top" title="<?php echo translate('Delete') ?>" disabled><i class="fa fa-trash"></i></button>
|
||||
</div>
|
||||
|
||||
<!-- Table styling handled by bootstrap-tables -->
|
||||
<div class="row justify-content-center table-responsive-sm">
|
||||
<table
|
||||
id="snapshotTable"
|
||||
data-locale="<?php echo i18n() ?>"
|
||||
data-side-pagination="server"
|
||||
data-ajax="ajaxRequest"
|
||||
data-pagination="true"
|
||||
data-show-pagination-switch="true"
|
||||
data-page-list="[10, 25, 50, 100, 200, All]"
|
||||
data-search="true"
|
||||
data-cookie="true"
|
||||
data-cookie-id-table="zmSnapshotsTable"
|
||||
data-cookie-expire="2y"
|
||||
data-click-to-select="true"
|
||||
data-remember-order="true"
|
||||
data-show-columns="true"
|
||||
data-show-export="true"
|
||||
data-uncheckAll="true"
|
||||
data-toolbar="#toolbar"
|
||||
data-show-fullscreen="true"
|
||||
data-click-to-select="true"
|
||||
data-maintain-meta-data="true"
|
||||
data-buttons-class="btn btn-normal"
|
||||
data-show-jump-to="true"
|
||||
data-show-refresh="true"
|
||||
class="table-sm table-borderless"
|
||||
style="display:none;"
|
||||
>
|
||||
<thead>
|
||||
<!-- Row styling is handled by bootstrap-tables -->
|
||||
<tr>
|
||||
<th data-sortable="false" data-field="toggleCheck" data-checkbox="true"></th>
|
||||
<th data-sortable="true" data-field="Id"><?php echo translate('Id') ?></th>
|
||||
<th data-sortable="true" data-field="Name"><?php echo translate('Reference') ?></th>
|
||||
<th data-sortable="false" data-field="Description"><?php echo translate('Notes') ?></th>
|
||||
<th data-sortable="true" data-field="CreatedOn"><?php echo translate('When') ?></th>
|
||||
<th data-sortable="false" data-field="Thumbnail"><?php echo translate('Thumbnail') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<div id="snapshots" class="container-fluid">
|
||||
<!-- Table styling handled by bootstrap-tables -->
|
||||
<div class="row justify-content-center table-responsive-sm">
|
||||
<table
|
||||
id="snapshotTable"
|
||||
data-locale="<?php echo i18n() ?>"
|
||||
data-side-pagination="server"
|
||||
data-ajax="ajaxRequest"
|
||||
data-pagination="true"
|
||||
data-show-pagination-switch="true"
|
||||
data-page-list="[10, 25, 50, 100, 200, All]"
|
||||
data-search="true"
|
||||
data-cookie="true"
|
||||
data-cookie-id-table="zmSnapshotsTable"
|
||||
data-cookie-expire="2y"
|
||||
data-click-to-select="true"
|
||||
data-remember-order="true"
|
||||
data-show-columns="true"
|
||||
data-show-export="true"
|
||||
data-uncheckAll="true"
|
||||
data-toolbar="#toolbar"
|
||||
data-show-fullscreen="true"
|
||||
data-click-to-select="true"
|
||||
data-maintain-meta-data="true"
|
||||
data-buttons-class="btn btn-normal"
|
||||
data-show-jump-to="true"
|
||||
data-show-refresh="true"
|
||||
class="table-sm table-borderless"
|
||||
style="display:none;"
|
||||
>
|
||||
<thead>
|
||||
<!-- Row styling is handled by bootstrap-tables -->
|
||||
<tr>
|
||||
<th data-sortable="false" data-field="toggleCheck" data-checkbox="true"></th>
|
||||
<th data-sortable="true" data-field="Id"><?php echo translate('Id') ?></th>
|
||||
<th data-sortable="true" data-field="Name"><?php echo translate('Reference') ?></th>
|
||||
<th data-sortable="false" data-field="Description"><?php echo translate('Notes') ?></th>
|
||||
<th data-sortable="true" data-field="CreatedOn"><?php echo translate('When') ?></th>
|
||||
<th data-sortable="false" data-field="Thumbnail"><?php echo translate('Thumbnail') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<!-- Row data populated via Ajax -->
|
||||
</tbody>
|
||||
<tbody>
|
||||
<!-- Row data populated via Ajax -->
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div><!--content-->
|
||||
</div>
|
||||
<?php xhtmlFooter() ?>
|
||||
|
|
|
@ -171,9 +171,9 @@ if ($monitor->JanusEnabled()) {
|
|||
|
||||
noCacheHeaders();
|
||||
xhtmlHeaders(__FILE__, $monitor->Name().' - '.translate('Feed'));
|
||||
?>
|
||||
<body>
|
||||
<?php echo getNavBarHTML() ?>
|
||||
getBodyTopHTML();
|
||||
echo getNavBarHTML() ?>
|
||||
<div id="page">
|
||||
<div id="header">
|
||||
<div class="controlHeader">
|
||||
<form method="get">
|
||||
|
@ -239,6 +239,7 @@ $seconds = translate('seconds');
|
|||
$minute = translate('minute');
|
||||
$minutes = translate('minutes');
|
||||
$cyclePeriodOptions = array(
|
||||
5 => '5 '.$seconds,
|
||||
10 => '10 '.$seconds,
|
||||
30 => '30 '.$seconds,
|
||||
60 => '1 '.$minute,
|
||||
|
|
Loading…
Reference in New Issue