From 2ee70442c0ad245fabddca4dfe7c3a091c6e60b2 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Fri, 11 Sep 2020 14:30:36 -0500 Subject: [PATCH 01/18] use done() and fail() callbacks for getJSON --- web/skins/classic/js/skin.js | 9 +++++++-- web/skins/classic/views/js/console.js | 9 ++++++--- web/skins/classic/views/js/event.js | 6 +++++- web/skins/classic/views/js/events.js | 23 ++++++++++++++++++----- 4 files changed, 36 insertions(+), 11 deletions(-) diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index 92e264831..669d56c70 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -416,6 +416,7 @@ if ( currentView != 'none' && currentView != 'login' ) { .done(setNavBar) .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); if ( textStatus != "timeout" ) { // The idea is that this should only fail due to auth, so reload the page // which should go to login if it can't stay logged in. @@ -711,7 +712,11 @@ function bwClickFunction() { function reminderClickFunction() { $j("#dropdown_reminder a").click(function() { var option = $j(this).data('pdsa-dropdown-val'); - $j.getJSON(thisUrl + '?view=version&action=version&option=' + option); - window.location.reload(true); //Do a full refresh to update ZM_DYN_LAST_VERSION + $j.getJSON(thisUrl + '?view=version&action=version&option=' + option) + .done(window.location.reload(true)) //Do a full refresh to update ZM_DYN_LAST_VERSION + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); }); } diff --git a/web/skins/classic/views/js/console.js b/web/skins/classic/views/js/console.js index 850703bb7..87976ca66 100644 --- a/web/skins/classic/views/js/console.js +++ b/web/skins/classic/views/js/console.js @@ -186,9 +186,12 @@ function initPage() { var mid = form.elements['mid'].value; var newFunc = $j('#newFunction').val(); var newEnabled = $j('#newEnabled').is(':checked') ? 1 : 0; - $j.getJSON(thisUrl + '?view=function&action=function&mid='+mid+'&newFunction='+newFunc+'&newEnabled='+newEnabled, function() { - window.location.reload(true); - }); + $j.getJSON(thisUrl + '?view=function&action=function&mid='+mid+'&newFunction='+newFunc+'&newEnabled='+newEnabled) + .done(window.location.reload(true)) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); }); } diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index 18eefb725..29c8c821f 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -49,7 +49,11 @@ $j.ajaxSetup({timeout: AJAX_TIMEOUT}); //sets timeout for all getJSON. var cueFrames = null; //make cueFrames available even if we don't send another ajax query function initialAlarmCues(eventId) { - $j.getJSON(thisUrl + '?view=request&request=status&entity=frames&id=' + eventId, setAlarmCues); //get frames data for alarmCues and inserts into html + $j.getJSON(thisUrl + '?view=request&request=status&entity=frames&id=' + eventId, setAlarmCues) //get frames data for alarmCues and inserts into html + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); } function setAlarmCues(data) { diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index 17df864d1..e9880d264 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -125,8 +125,12 @@ function initPage() { var selections = getIdSelections(); evt.preventDefault(); - $j.getJSON(thisUrl + '?view=events&action=archive&eids[]='+selections.join('&eids[]=')); - window.location.reload(true); + $j.getJSON(thisUrl + '?request=events&action=archive&eids[]='+selections.join('&eids[]=')) + .done(window.location.reload(true)) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); }); // Manage the UNARCHIVE button @@ -140,7 +144,12 @@ function initPage() { console.log(selections); evt.preventDefault(); - $j.getJSON(thisUrl + '?view=events&action=unarchive&eids[]='+selections.join('&eids[]=')); + $j.getJSON(thisUrl + '?request=events&action=unarchive&eids[]='+selections.join('&eids[]=')) + .done(window.location.reload(true)) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); if ( openFilterWindow ) { //opener.location.reload(true); @@ -201,8 +210,12 @@ function initPage() { var selections = getIdSelections(); evt.preventDefault(); - $j.getJSON(thisUrl + '?request=events&action=delete&eids[]='+selections.join('&eids[]=')); - window.location.reload(true); + $j.getJSON(thisUrl + '?request=events&action=delete&eids[]='+selections.join('&eids[]=')) + .done(window.location.reload(true)) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); }); // Manage the CANCEL modal button From 0c8bb2588990cd9cb39defc22d64ca76edd04bdd Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Fri, 11 Sep 2020 16:49:36 -0500 Subject: [PATCH 02/18] eslint --- web/skins/classic/views/js/event.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/event.js b/web/skins/classic/views/js/event.js index 29c8c821f..6781949d1 100644 --- a/web/skins/classic/views/js/event.js +++ b/web/skins/classic/views/js/event.js @@ -53,7 +53,7 @@ function initialAlarmCues(eventId) { .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); console.log("Response Text: " + jqxhr.responseText); - }); + }); } function setAlarmCues(data) { From 0557d847f07003421cd30807ec210d0298768611 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Fri, 11 Sep 2020 17:01:56 -0500 Subject: [PATCH 03/18] fix ajax archive/unarchive --- web/ajax/events.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/ajax/events.php b/web/ajax/events.php index 7b852c559..16c777ebf 100644 --- a/web/ajax/events.php +++ b/web/ajax/events.php @@ -16,10 +16,10 @@ if ( canEdit('Events') ) { switch ( $_REQUEST['action'] ) { case 'archive' : case 'unarchive' : - $archiveVal = ($_REQUEST['action'] == 'archive')?1:0; + $archiveVal = ($_REQUEST['action'] == 'archive') ? 1 : 0; dbQuery( 'UPDATE Events SET Archived = ? WHERE Id = ?', - array($archiveVal, $_REQUEST['id']) + array($archiveVal, $eid) ); break; case 'delete' : From 547e1d6cc45919c4d05561c1bbb40b14eb31cc0f Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 12 Sep 2020 08:36:19 -0500 Subject: [PATCH 04/18] rough in error no permisson modal --- web/ajax/modal.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/ajax/modal.php b/web/ajax/modal.php index 3b204495c..de7432c93 100644 --- a/web/ajax/modal.php +++ b/web/ajax/modal.php @@ -25,6 +25,9 @@ switch ( $modal ) { if ( empty($_REQUEST['ohndx']) ) ajaxError('Option Help Index Not Provided'); $data['html'] = getOptionHelpHTML($_REQUEST['ohndx'], $OLANG); break; + case 'enoperm' : + $data['html'] = getENoPermHTML(); + break; default : // Maybe don't need both ZM\Warning('Unknown modal '.$modal); From 0ad41fc8d43e2a74d3bcbc3722e84ffc16514afd Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 12 Sep 2020 08:37:57 -0500 Subject: [PATCH 05/18] rough in error no permisson modal --- web/skins/classic/includes/functions.php | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index c2fc0c93a..a04a37755 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -790,6 +790,33 @@ function getOptionHelpHTML($optionHelpIndex, $OLANG) { return $result; } +// Return an Error No Permissions Modal +function getENoPermHTML() { + $result = ''; + + $result .= ''.PHP_EOL; + + return $result; +} + function xhtmlFooter() { global $css; global $cspNonce; From f31b3bfc596be25f569b9a5a71a3494dd6eadc9b Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 12 Sep 2020 11:48:33 -0500 Subject: [PATCH 06/18] add xhtmlFooter to stats view --- web/skins/classic/views/stats.php | 1 + 1 file changed, 1 insertion(+) diff --git a/web/skins/classic/views/stats.php b/web/skins/classic/views/stats.php index f6373151c..01def0b74 100644 --- a/web/skins/classic/views/stats.php +++ b/web/skins/classic/views/stats.php @@ -50,3 +50,4 @@ xhtmlHeaders(__FILE__, translate('Stats')." - ".$eid." - ".$fid ); + From 5d914d8b01f408d57ecd5af08d51ffcba7e5f546 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 12 Sep 2020 11:53:53 -0500 Subject: [PATCH 07/18] convert stats table to a function --- web/skins/classic/includes/functions.php | 61 ++++++++++++++++ web/skins/classic/views/_stats_table.php | 90 ------------------------ web/skins/classic/views/stats.php | 2 +- 3 files changed, 62 insertions(+), 91 deletions(-) delete mode 100644 web/skins/classic/views/_stats_table.php diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index a04a37755..61ebc9d44 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -817,6 +817,67 @@ function getENoPermHTML() { return $result; } +function getStatsTableHTML($eid, $fid, $row='') { + if ( !canView('Events') ) return; + $result = ''; + + $sql = 'SELECT S.*,E.*,Z.Name AS ZoneName,Z.Units,Z.Area,M.Name AS MonitorName FROM Stats AS S LEFT JOIN Events AS E ON S.EventId = E.Id LEFT JOIN Zones AS Z ON S.ZoneId = Z.Id LEFT JOIN Monitors AS M ON E.MonitorId = M.Id WHERE S.EventId = ? AND S.FrameId = ? ORDER BY S.ZoneId'; + $stats = dbFetchAll( $sql, NULL, array( $eid, $fid ) ); + + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + + $result .= ''.PHP_EOL; + + if ( count($stats) ) { + foreach ( $stats as $stat ) { + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + + if ( $stat['Blobs'] > 1 ) { + $result .= ''.PHP_EOL; + } else { + $result .= ''.PHP_EOL; + } + + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + } + } else { + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + $result .= ''.PHP_EOL; + } + + $result .= ''.PHP_EOL; + $result .= '
' .translate('Zone'). '' .translate('PixelDiff'). '' .translate('AlarmPx'). '' .translate('FilterPx'). '' .translate('BlobPx'). '' .translate('Blobs'). '' .translate('BlobSizes'). '' .translate('AlarmLimits'). '' .translate('Score'). '
' .validHtmlStr($stat['ZoneName']). '' .validHtmlStr($stat['PixelDiff']). '' .sprintf( "%d (%d%%)", $stat['AlarmPixels'], (100*$stat['AlarmPixels']/$stat['Area']) ). '' .sprintf( "%d (%d%%)", $stat['FilterPixels'], (100*$stat['FilterPixels']/$stat['Area']) ).'' .sprintf( "%d (%d%%)", $stat['BlobPixels'], (100*$stat['BlobPixels']/$stat['Area']) ). '' .validHtmlStr($stat['Blobs']). '' .sprintf( "%d-%d (%d%%-%d%%)", $stat['MinBlobSize'], $stat['MaxBlobSize'], (100*$stat['MinBlobSize']/$stat['Area']), (100*$stat['MaxBlobSize']/$stat['Area']) ). '' .sprintf( "%d (%d%%)", $stat['MinBlobSize'], 100*$stat['MinBlobSize']/$stat['Area'] ). '' .validHtmlStr($stat['MinX'].",".$stat['MinY']."-".$stat['MaxX'].",".$stat['MaxY']). '' .$stat['Score']. '
' .translate('NoStatisticsRecorded'). '
'.PHP_EOL; + + return $result; +} + function xhtmlFooter() { global $css; global $cspNonce; diff --git a/web/skins/classic/views/_stats_table.php b/web/skins/classic/views/_stats_table.php deleted file mode 100644 index bf4bd14a6..000000000 --- a/web/skins/classic/views/_stats_table.php +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 ) { -?> - - - - - - - - - - - - - -
- -
diff --git a/web/skins/classic/views/stats.php b/web/skins/classic/views/stats.php index 01def0b74..2cd5c69e4 100644 --- a/web/skins/classic/views/stats.php +++ b/web/skins/classic/views/stats.php @@ -44,7 +44,7 @@ xhtmlHeaders(__FILE__, translate('Stats')." - ".$eid." - ".$fid );
- +
From 56aa906dd820b708b54a7a3186f5163905b3f046 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sat, 12 Sep 2020 11:55:24 -0500 Subject: [PATCH 08/18] call getStatsTableHTML in frames view --- web/skins/classic/views/frames.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/frames.php b/web/skins/classic/views/frames.php index c29160549..9f86866e7 100644 --- a/web/skins/classic/views/frames.php +++ b/web/skins/classic/views/frames.php @@ -213,7 +213,7 @@ $row = 0; if ( count($frames) ) foreach ( $frames as $frame ) { $eid = $frame['EventId']; $fid = $frame['FrameId']; - include('_stats_table.php'); + echo getStatsTableHTML($eid, $fid, $row); $row++; } ?> From 1599bc4c1457d80448a95552f75f714560de5053 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 07:32:49 -0500 Subject: [PATCH 09/18] load stats on deman via ajax --- web/ajax/stats.php | 24 ++++++++++++++++++++++++ web/skins/classic/views/frames.php | 11 ----------- web/skins/classic/views/js/frames.js | 12 +++++++++--- 3 files changed, 33 insertions(+), 14 deletions(-) create mode 100644 web/ajax/stats.php diff --git a/web/ajax/stats.php b/web/ajax/stats.php new file mode 100644 index 000000000..3789ff448 --- /dev/null +++ b/web/ajax/stats.php @@ -0,0 +1,24 @@ + diff --git a/web/skins/classic/views/frames.php b/web/skins/classic/views/frames.php index 9f86866e7..3c2ad9277 100644 --- a/web/skins/classic/views/frames.php +++ b/web/skins/classic/views/frames.php @@ -206,15 +206,4 @@ if ( count($frames) ) { - - - diff --git a/web/skins/classic/views/js/frames.js b/web/skins/classic/views/js/frames.js index 8b3ff28ec..2fd96b8d4 100644 --- a/web/skins/classic/views/js/frames.js +++ b/web/skins/classic/views/js/frames.js @@ -25,10 +25,16 @@ function processClicks(event, field, value, row, $element) { } } -function detailFormatter(index, row, element) { - return $j(element).html($j('#contentStatsTable'+index).clone(true).show()); +// This function handles when the user clicks a "+" link to retrieve stats for a frame +function detailFormatter(index, row, $detail) { + $detail.html('Please wait. Loading from ajax request...'); + $j.get(thisUrl + '?request=stats&eid=' + row.EventId + '&fid=' + row.FrameId + '&row=' + index) + .done(function(data){ $detail.html(data.html) }) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); } - function initPage() { var backBtn = $j('#backBtn'); var table = $j('#framesTable'); From 951afc669fb455b484080f14681bb18849f71470 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 08:33:47 -0500 Subject: [PATCH 10/18] eslint --- web/skins/classic/views/js/frames.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/web/skins/classic/views/js/frames.js b/web/skins/classic/views/js/frames.js index 2fd96b8d4..52e539c14 100644 --- a/web/skins/classic/views/js/frames.js +++ b/web/skins/classic/views/js/frames.js @@ -29,11 +29,13 @@ function processClicks(event, field, value, row, $element) { function detailFormatter(index, row, $detail) { $detail.html('Please wait. Loading from ajax request...'); $j.get(thisUrl + '?request=stats&eid=' + row.EventId + '&fid=' + row.FrameId + '&row=' + index) - .done(function(data){ $detail.html(data.html) }) - .fail(function(jqxhr, textStatus, error) { - console.log("Request Failed: " + textStatus + ", " + error); - console.log("Response Text: " + jqxhr.responseText); - }); + .done(function(data) { + $detail.html(data.html) + }) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); } function initPage() { var backBtn = $j('#backBtn'); From 7e55dd14a24e3fbcab73c24087e142cb5d110489 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 08:52:52 -0500 Subject: [PATCH 11/18] eslint --- web/skins/classic/views/js/frames.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/frames.js b/web/skins/classic/views/js/frames.js index 52e539c14..a94e76c71 100644 --- a/web/skins/classic/views/js/frames.js +++ b/web/skins/classic/views/js/frames.js @@ -30,7 +30,7 @@ function detailFormatter(index, row, $detail) { $detail.html('Please wait. Loading from ajax request...'); $j.get(thisUrl + '?request=stats&eid=' + row.EventId + '&fid=' + row.FrameId + '&row=' + index) .done(function(data) { - $detail.html(data.html) + $detail.html(data.html); }) .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); From 096f4a446f87d9ca768ff48e746be74db61d7492 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 10:39:51 -0500 Subject: [PATCH 12/18] Use Ajax to load delete confirm modal --- web/ajax/modal.php | 3 ++ web/skins/classic/includes/functions.php | 27 ++++++++++ web/skins/classic/views/events.php | 21 -------- web/skins/classic/views/js/events.js | 68 ++++++++++++++++-------- 4 files changed, 75 insertions(+), 44 deletions(-) diff --git a/web/ajax/modal.php b/web/ajax/modal.php index de7432c93..5693c1d4f 100644 --- a/web/ajax/modal.php +++ b/web/ajax/modal.php @@ -28,6 +28,9 @@ switch ( $modal ) { case 'enoperm' : $data['html'] = getENoPermHTML(); break; + case 'delconfirm' : + $data['html'] = getDelConfirmHTML(); + break; default : // Maybe don't need both ZM\Warning('Unknown modal '.$modal); diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index 61ebc9d44..b120450fb 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -878,6 +878,33 @@ function getStatsTableHTML($eid, $fid, $row='') { return $result; } +// This is the HTML representing the Delete confirmation modal on the Events page +function getDelConfirmHTML() { + $result = ''; + + $result .= ''.PHP_EOL; + + return $result; +} + function xhtmlFooter() { global $css; global $cspNonce; diff --git a/web/skins/classic/views/events.php b/web/skins/classic/views/events.php index 1d0507b4a..29bfb18c7 100644 --- a/web/skins/classic/views/events.php +++ b/web/skins/classic/views/events.php @@ -322,25 +322,4 @@ if ( $results ) { - - - diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index e9880d264..68f362a71 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -35,6 +35,48 @@ function getArchivedSelections() { return selection.includes("Yes"); } +// Load the Delete Confirmation Modal HTML via Ajax call +function getDelConfirmModal() { + $j.getJSON(thisUrl + '?request=modal&modal=delconfirm') + .done(function(data) { + if ( $j('#deleteConfirm').length ) { + $j('#deleteConfirm').replaceWith(data.html); + } else { + $j("body").append(data.html); + } + manageDelConfirmModalBtns(); + }) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); +} + +function manageDelConfirmModalBtns() { + // Manage the DELETE CONFIRMATION modal button + document.getElementById("delConfirmBtn").addEventListener("click", function onDelConfirmClick(evt) { + if ( ! canEditEvents ) { + alert("You do not have permission to delete events."); + return; + } + + var selections = getIdSelections(); + + evt.preventDefault(); + $j.getJSON(thisUrl + '?request=events&action=delete&eids[]='+selections.join('&eids[]=')) + .done(window.location.reload(true)) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); + }); + + // Manage the CANCEL modal button + document.getElementById("delCancelBtn").addEventListener("click", function onDelCancelClick(evt) { + $j('#deleteConfirm').modal('hide'); + }); +} + function initPage() { var backBtn = $j('#backBtn'); var viewBtn = $j('#viewBtn'); @@ -46,6 +88,9 @@ function initPage() { var deleteBtn = $j('#deleteBtn'); var table = $j('#eventTable'); + // Load the delete confirmation modal into the DOM + getDelConfirmModal(); + // Define the icons used in the bootstrap-table top-right toolbar var icons = { paginationSwitchDown: 'fa-caret-square-o-down', @@ -200,29 +245,6 @@ function initPage() { $j('#deleteConfirm').modal('show'); }); - // Manage the DELETE CONFIRMATION modal button - document.getElementById("delConfirmBtn").addEventListener("click", function onDelConfirmClick(evt) { - if ( ! canEditEvents ) { - alert("You do not have permission to delete events."); - return; - } - - var selections = getIdSelections(); - - evt.preventDefault(); - $j.getJSON(thisUrl + '?request=events&action=delete&eids[]='+selections.join('&eids[]=')) - .done(window.location.reload(true)) - .fail(function(jqxhr, textStatus, error) { - console.log("Request Failed: " + textStatus + ", " + error); - console.log("Response Text: " + jqxhr.responseText); - }); - }); - - // Manage the CANCEL modal button - document.getElementById("delCancelBtn").addEventListener("click", function onDelCancelClick(evt) { - $j('#deleteConfirm').modal('hide'); - }); - // The table is initially given a hidden style, so now that we are done rendering, show it table.show(); } From 54e8d1352a3a18494b294601fcc2da2dcc79e641 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 11:04:04 -0500 Subject: [PATCH 13/18] add enoperm js function --- web/skins/classic/includes/functions.php | 2 +- web/skins/classic/js/skin.js | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index b120450fb..8f5703015 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -808,7 +808,7 @@ function getENoPermHTML() { $result .= '

' .translate('ContactAdmin'). '

'.PHP_EOL; $result .= ''.PHP_EOL; $result .= ''.PHP_EOL; $result .= ''.PHP_EOL; $result .= ''.PHP_EOL; diff --git a/web/skins/classic/js/skin.js b/web/skins/classic/js/skin.js index 669d56c70..bdeeb6a63 100644 --- a/web/skins/classic/js/skin.js +++ b/web/skins/classic/js/skin.js @@ -720,3 +720,25 @@ function reminderClickFunction() { }); }); } + +// Load then show the "You No Permission" error modal +function enoperm() { + $j.getJSON(thisUrl + '?request=modal&modal=enoperm') + .done(function(data) { + if ( $j('#ENoPerm').length ) { + $j('#ENoPerm').replaceWith(data.html); + } else { + $j("body").append(data.html); + } + $j('#ENoPerm').modal('show'); + + // Manage the CLOSE optionhelp modal button + document.getElementById("enpCloseBtn").addEventListener("click", function onENPCloseClick(evt) { + $j('#ENoPerm').modal('hide'); + }); + }) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); +} From c4c455143645629d3aab25e2ed0ac8a31a105cb2 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 11:09:15 -0500 Subject: [PATCH 14/18] replace no permission alerts with enoperm() --- web/skins/classic/views/js/console.js | 2 +- web/skins/classic/views/js/events.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/skins/classic/views/js/console.js b/web/skins/classic/views/js/console.js index 87976ca66..522a6910e 100644 --- a/web/skins/classic/views/js/console.js +++ b/web/skins/classic/views/js/console.js @@ -151,7 +151,7 @@ function initPage() { $j('.functionLnk').click(function(evt) { evt.preventDefault(); if ( !canEditEvents ) { - alert('You do not have permission to change monitor function.'); + enoperm(); return; } var mid = evt.currentTarget.getAttribute('data-mid'); diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index 68f362a71..26f70aeea 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -56,7 +56,7 @@ function manageDelConfirmModalBtns() { // Manage the DELETE CONFIRMATION modal button document.getElementById("delConfirmBtn").addEventListener("click", function onDelConfirmClick(evt) { if ( ! canEditEvents ) { - alert("You do not have permission to delete events."); + enoperm(); return; } @@ -181,7 +181,7 @@ function initPage() { // Manage the UNARCHIVE button document.getElementById("unarchiveBtn").addEventListener("click", function onUnarchiveClick(evt) { if ( ! canEditEvents ) { - alert("You do not have permission to Unarchive events."); + enoperm(); return; } @@ -208,7 +208,7 @@ function initPage() { // Manage the EDIT button document.getElementById("editBtn").addEventListener("click", function onEditClick(evt) { if ( ! canEditEvents ) { - alert("You do not have permission to edit events."); + enoperm(); return; } @@ -237,7 +237,7 @@ function initPage() { // Manage the DELETE button document.getElementById("deleteBtn").addEventListener("click", function onDeleteClick(evt) { if ( ! canEditEvents ) { - alert("You do not have permission to delete events."); + enoperm(); return; } From 29710f67ac4f38fc875cd32605ebb91167bc4066 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 11:25:31 -0500 Subject: [PATCH 15/18] fix table refresh after delete --- web/skins/classic/views/js/events.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index 26f70aeea..404e73c50 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -64,7 +64,9 @@ function manageDelConfirmModalBtns() { evt.preventDefault(); $j.getJSON(thisUrl + '?request=events&action=delete&eids[]='+selections.join('&eids[]=')) - .done(window.location.reload(true)) + .done( function(data) { + $j('#eventTable').bootstrapTable('refresh'); + }) .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); console.log("Response Text: " + jqxhr.responseText); From 0a0b555c4c8600fcec4f7a298252ef32ce907b17 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Sun, 13 Sep 2020 11:32:28 -0500 Subject: [PATCH 16/18] refresh table after archive or unarchive --- web/skins/classic/views/js/events.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/events.js b/web/skins/classic/views/js/events.js index 404e73c50..908be8c12 100644 --- a/web/skins/classic/views/js/events.js +++ b/web/skins/classic/views/js/events.js @@ -173,7 +173,10 @@ function initPage() { evt.preventDefault(); $j.getJSON(thisUrl + '?request=events&action=archive&eids[]='+selections.join('&eids[]=')) - .done(window.location.reload(true)) + .done( function(data) { + $j('#eventTable').bootstrapTable('refresh'); + window.location.reload(true); + }) .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); console.log("Response Text: " + jqxhr.responseText); @@ -192,7 +195,10 @@ function initPage() { evt.preventDefault(); $j.getJSON(thisUrl + '?request=events&action=unarchive&eids[]='+selections.join('&eids[]=')) - .done(window.location.reload(true)) + .done( function(data) { + $j('#eventTable').bootstrapTable('refresh'); + window.location.reload(true); + }) .fail(function(jqxhr, textStatus, error) { console.log("Request Failed: " + textStatus + ", " + error); console.log("Response Text: " + jqxhr.responseText); From d2bc39f65fae53b13779bfcc68deab3456881529 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 14 Sep 2020 09:50:04 -0500 Subject: [PATCH 17/18] replace storage popup with modal --- web/ajax/modal.php | 4 + web/includes/actions/storage.php | 4 +- web/skins/classic/includes/functions.php | 111 +++++++++++++++++++++ web/skins/classic/views/js/options.js | 45 +++++++++ web/skins/classic/views/js/options.js.php | 2 + web/skins/classic/views/options.php | 14 +-- web/skins/classic/views/storage.php | 114 ---------------------- 7 files changed, 171 insertions(+), 123 deletions(-) create mode 100644 web/skins/classic/views/js/options.js delete mode 100644 web/skins/classic/views/storage.php diff --git a/web/ajax/modal.php b/web/ajax/modal.php index 5693c1d4f..8f5cb8ac9 100644 --- a/web/ajax/modal.php +++ b/web/ajax/modal.php @@ -31,6 +31,10 @@ switch ( $modal ) { case 'delconfirm' : $data['html'] = getDelConfirmHTML(); break; + case 'storage' : + if ( !isset($_REQUEST['id']) ) ajaxError('Storage Id Not Provided'); + $data['html'] = getStorageModalHTML($_REQUEST['id']); + break; default : // Maybe don't need both ZM\Warning('Unknown modal '.$modal); diff --git a/web/includes/actions/storage.php b/web/includes/actions/storage.php index 49b5de3de..69ebfae0b 100644 --- a/web/includes/actions/storage.php +++ b/web/includes/actions/storage.php @@ -24,7 +24,7 @@ if ( !canEdit('System') ) { return; } -if ( $action == 'Save' ) { +if ( $action == 'save' ) { $storage = new ZM\Storage($_REQUEST['id']); $changes = $storage->changes($_REQUEST['newStorage']); @@ -33,7 +33,7 @@ if ( $action == 'Save' ) { $storage->save($changes); $refreshParent = true; } - $view = 'none'; + $redirect = '?view=options&tab=storage'; } else { ZM\Error("Unknown action $action in saving Storage"); } diff --git a/web/skins/classic/includes/functions.php b/web/skins/classic/includes/functions.php index 8f5703015..8facb1f80 100644 --- a/web/skins/classic/includes/functions.php +++ b/web/skins/classic/includes/functions.php @@ -905,6 +905,117 @@ function getDelConfirmHTML() { return $result; } +function getStorageModalHTML($sid) { + $result = ''; + $null = ''; + $checked = 'checked="checked"'; + + if ( !canEdit('System') ) return; + + require_once('includes/Server.php'); + require_once('includes/Storage.php'); + + if ( $_REQUEST['id'] ) { + if ( !($newStorage = ZM\Storage::find_one(array('Id'=>$sid)) ) ) { + // Perhaps do something different here, rather than return nothing + return; + } + } else { + $newStorage = new ZM\Storage(); + $newStorage->Name(translate('NewStorage')); + } + + $type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') ); + $scheme_options = array( + 'Deep' => translate('Deep'), + 'Medium' => translate('Medium'), + 'Shallow' => translate('Shallow'), + ); + + $servers = ZM\Server::find( null, array('order'=>'lower(Name)') ); + $ServersById = array(); + foreach ( $servers as $S ) { + $ServersById[$S->Id()] = $S; + } + + // We have to manually insert the csrf key into the form when using a modal generated via ajax call + if ( isset($GLOBALS['csrf']['key']) ) { + $csrf_input = ''.PHP_EOL; + } else { + $csrf_input = ''; + } + + $result .= ''.PHP_EOL; + + return $result; +} + function xhtmlFooter() { global $css; global $cspNonce; diff --git a/web/skins/classic/views/js/options.js b/web/skins/classic/views/js/options.js new file mode 100644 index 000000000..690da7744 --- /dev/null +++ b/web/skins/classic/views/js/options.js @@ -0,0 +1,45 @@ +// Load the Storage Modal HTML via Ajax call +function getStorageModal(sid) { + $j.getJSON(thisUrl + '?request=modal&modal=storage&id=' + sid) + .done(function(data) { + if ( $j('#storageModal').length ) { + $j('#storageModal').replaceWith(data.html); + } else { + $j("body").append(data.html); + } + $j('#storageModal').modal('show'); + // Manage the Save button + $j('#storageSubmitBtn').click(function(evt) { + evt.preventDefault(); + $j('#storageModalForm').submit(); + }); + }) + .fail(function(jqxhr, textStatus, error) { + console.log("Request Failed: " + textStatus + ", " + error); + console.log("Response Text: " + jqxhr.responseText); + }); +} + +function enableStorageModal() { + $j(".storageCol").click(function(evt) { + evt.preventDefault(); + var sid = $j(this).data('sid'); + getStorageModal(sid); + }); + $j('#NewStorageBtn').click(function(evt) { + evt.preventDefault(); + getStorageModal(0); + }); +} + +function initPage() { + var NewStorageBtn = $j('#NewStorageBtn'); + + if ( canEditSystem ) enableStorageModal(); + + NewStorageBtn.prop('disabled', !canEditSystem); +} + +$j(document).ready(function() { + initPage(); +}); diff --git a/web/skins/classic/views/js/options.js.php b/web/skins/classic/views/js/options.js.php index 6947f8da8..5281cde8c 100644 --- a/web/skins/classic/views/js/options.js.php +++ b/web/skins/classic/views/js/options.js.php @@ -3,3 +3,5 @@ var restartWarning = ; if ( restartWarning ) { alert( "" ); } + +var canEditSystem = ; diff --git a/web/skins/classic/views/options.php b/web/skins/classic/views/options.php index 0fb5cb6e4..e1e6f4f78 100644 --- a/web/skins/classic/views/options.php +++ b/web/skins/classic/views/options.php @@ -272,12 +272,12 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as 'lower(Name)') ) as $Storage ) { ?> - Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Id()), $canEdit ) ?> - Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Name()), $canEdit ) ?> - Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Path()), $canEdit ) ?> - Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Type()), $canEdit ) ?> - Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Scheme()), $canEdit ) ?> - Id(), 'zmStorage', 'storage', validHtmlStr($Storage->Server()->Name()), $canEdit ) ?> + Id()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?> + Name()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?> + Path()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?> + Type()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?> + Scheme()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?> + Server()->Name()), $canEdit, 'class="storageCol" data-sid="'.$Storage->Id().'"' ) ?> disk_used_space()) . ' of ' . human_filesize($Storage->disk_total_space()) ?> EventCount().' using '.human_filesize($Storage->event_disk_space()) ?> EventCount() or !$canEdit ) { ?> disabled="disabled"EventCount() ? ' title="Can\'t delete as long as there are events stored here."' : ''?>/> @@ -286,7 +286,7 @@ foreach ( array_map('basename', glob('skins/'.$skin.'/css/*', GLOB_ONLYDIR)) as
- +
diff --git a/web/skins/classic/views/storage.php b/web/skins/classic/views/storage.php deleted file mode 100644 index b25d12a21..000000000 --- a/web/skins/classic/views/storage.php +++ /dev/null @@ -1,114 +0,0 @@ -$_REQUEST['id'])) ) ) { - $view = 'error'; - return; - } -} else { - $newStorage = new ZM\Storage(); - $newStorage->Name(translate('NewStorage')); -} - -$type_options = array( 'local' => translate('Local'), 's3fs' => translate('s3fs') ); -$scheme_options = array( - 'Deep' => translate('Deep'), - 'Medium' => translate('Medium'), - 'Shallow' => translate('Shallow'), -); - -$servers = ZM\Server::find( null, array('order'=>'lower(Name)') ); -$ServersById = array(); -foreach ( $servers as $S ) { - $ServersById[$S->Id()] = $S; -} -$focusWindow = true; - -xhtmlHeaders(__FILE__, translate('Storage').' - '.$newStorage->Name()); -?> - -
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
'Remote / No Specific Server') + $ServersById, $newStorage->ServerId()); ?>
Type()); ?>
Scheme()); ?>
- DoDelete() ? 'checked="checked"' : '' ?>/>Yes - DoDelete() ? '' : 'checked="checked"' ?>/>No -
- Enabled() ? 'checked="checked"' : '' ?>/>Yes - Enabled() ? '' : 'checked="checked"' ?>/>No -
-
- - -
-
-
-
- From cc7b65e8aa0f3a10799c833868ae034b64dddc31 Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Mon, 14 Sep 2020 10:31:44 -0500 Subject: [PATCH 18/18] eslint --- web/skins/classic/views/js/options.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/options.js b/web/skins/classic/views/js/options.js index 690da7744..330a0e73b 100644 --- a/web/skins/classic/views/js/options.js +++ b/web/skins/classic/views/js/options.js @@ -34,9 +34,9 @@ function enableStorageModal() { function initPage() { var NewStorageBtn = $j('#NewStorageBtn'); - + if ( canEditSystem ) enableStorageModal(); - + NewStorageBtn.prop('disabled', !canEditSystem); }