Preserve multiselection during refresh

refs #5765
This commit is contained in:
Matthias Jentsch 2014-04-23 19:41:07 +02:00
parent b791883fa8
commit c641988233
12 changed files with 238 additions and 98 deletions

View File

@ -113,6 +113,7 @@ class Monitoring_ListController extends Controller
))->activate('hosts'); ))->activate('hosts');
$this->setAutorefreshInterval(10); $this->setAutorefreshInterval(10);
$this->view->query = $this->_request->getQuery();
$this->view->title = 'Host Status'; $this->view->title = 'Host Status';
$this->compactView = 'hosts-compact'; $this->compactView = 'hosts-compact';
$dataview = HostStatusView::fromRequest( $dataview = HostStatusView::fromRequest(
@ -176,6 +177,7 @@ class Monitoring_ListController extends Controller
} }
} }
$this->view->title = 'Service Status'; $this->view->title = 'Service Status';
$this->view->query = $this->_request->getQuery();
$this->setAutorefreshInterval(10); $this->setAutorefreshInterval(10);
$query = $this->fetchServices(); $query = $this->fetchServices();
$this->applyRestrictions($query); $this->applyRestrictions($query);

View File

@ -45,14 +45,13 @@ class Monitoring_MultiController extends ActionController
{ {
public function init() public function init()
{ {
$this->view->queries = $this->getAllParamsAsArray();
$this->backend = Backend::createBackend($this->_getParam('backend')); $this->backend = Backend::createBackend($this->_getParam('backend'));
$this->createTabs(); $this->createTabs();
} }
public function hostAction() public function hostAction()
{ {
$filters = $this->view->queries; $multiFilter = $this->getAllParamsAsArray();
$errors = array(); $errors = array();
// Fetch Hosts // Fetch Hosts
@ -68,18 +67,20 @@ class Monitoring_MultiController extends ActionController
'host_notifications_enabled', 'host_notifications_enabled',
'host_event_handler_enabled', 'host_event_handler_enabled',
'host_flap_detection_enabled', 'host_flap_detection_enabled',
'host_active_checks_enabled' 'host_active_checks_enabled',
// columns intended for filter-request
'host_problem',
'host_handled'
) )
)->getQuery(); )->getQuery();
if ($this->_getParam('host') !== '*') { $this->applyQueryFilter($hostQuery, $multiFilter);
$this->applyQueryFilter($hostQuery, $filters);
}
$hosts = $hostQuery->fetchAll(); $hosts = $hostQuery->fetchAll();
// Fetch comments // Fetch comments
$commentQuery = $this->applyQueryFilter( $commentQuery = $this->applyQueryFilter(
CommentView::fromRequest($this->_request)->getQuery(), CommentView::fromParams(array('backend' => $this->_request->getParam('backend')))->getQuery(),
$filters, $multiFilter,
'comment_host' 'comment_host'
); );
$comments = array_keys($this->getUniqueValues($commentQuery->fetchAll(), 'comment_internal_id')); $comments = array_keys($this->getUniqueValues($commentQuery->fetchAll(), 'comment_internal_id'));
@ -94,23 +95,25 @@ class Monitoring_MultiController extends ActionController
$this->view->states = $this->countStates($hosts, 'host', 'host_name'); $this->view->states = $this->countStates($hosts, 'host', 'host_name');
$this->view->pie = $this->createPie($this->view->states, $this->view->getHelper('MonitoringState')->getHostStateColors()); $this->view->pie = $this->createPie($this->view->states, $this->view->getHelper('MonitoringState')->getHostStateColors());
// need the query content to list all hosts
$this->view->query = $this->_request->getQuery();
// Handle configuration changes // Handle configuration changes
$this->handleConfigurationForm(array( $this->handleConfigurationForm(array(
'host_passive_checks_enabled' => 'Passive Checks', 'host_passive_checks_enabled' => 'Passive Checks',
'host_active_checks_enabled' => 'Active Checks', 'host_active_checks_enabled' => 'Active Checks',
'host_obsessing' => 'Obsessing',
'host_notifications_enabled' => 'Notifications', 'host_notifications_enabled' => 'Notifications',
'host_event_handler_enabled' => 'Event Handler', 'host_event_handler_enabled' => 'Event Handler',
'host_flap_detection_enabled' => 'Flap Detection' 'host_flap_detection_enabled' => 'Flap Detection',
'host_obsessing' => 'Obsessing'
)); ));
} }
public function serviceAction() public function serviceAction()
{ {
$filters = $this->view->queries; $multiFilter = $this->getAllParamsAsArray();
$errors = array(); $errors = array();
$backendQuery = ServiceStatusView::fromRequest( $backendQuery = ServiceStatusView::fromRequest(
$this->_request, $this->_request,
array( array(
@ -124,24 +127,33 @@ class Monitoring_MultiController extends ActionController
'service_notifications_enabled', 'service_notifications_enabled',
'service_event_handler_enabled', 'service_event_handler_enabled',
'service_flap_detection_enabled', 'service_flap_detection_enabled',
'service_active_checks_enabled' 'service_active_checks_enabled',
'service_obsessing',
// also accept all filter-requests from ListView
'service_problem',
'service_severity',
'service_last_check',
'service_state_type',
'host_severity',
'host_address',
'host_last_check'
) )
)->getQuery(); )->getQuery();
if ($this->_getParam('service') !== '*' && $this->_getParam('host') !== '*') {
$this->applyQueryFilter($backendQuery, $filters); $this->applyQueryFilter($backendQuery, $multiFilter);
$this->applyQueryFilter($backendQuery, $filters);
}
$services = $backendQuery->fetchAll(); $services = $backendQuery->fetchAll();
// Comments // Comments
$commentQuery = $this->applyQueryFilter( $commentQuery = $this->applyQueryFilter(
CommentView::fromRequest($this->_request)->getQuery(), CommentView::fromParams(array('backend' => $this->_request->getParam('backend')))->getQuery(),
$filters, $multiFilter,
'comment_host', 'comment_host',
'comment_service' 'comment_service'
); );
$comments = array_keys($this->getUniqueValues($commentQuery->fetchAll(), 'comment_internal_id')); $comments = array_keys($this->getUniqueValues($commentQuery->fetchAll(), 'comment_internal_id'));
// populate the view
$this->view->objects = $this->view->services = $services; $this->view->objects = $this->view->services = $services;
$this->view->problems = $this->getProblems($services); $this->view->problems = $this->getProblems($services);
$this->view->comments = isset($comments) ? $comments : $this->getComments($services); $this->view->comments = isset($comments) ? $comments : $this->getComments($services);
@ -154,12 +166,16 @@ class Monitoring_MultiController extends ActionController
$this->view->host_pie = $this->createPie($this->view->host_states, $this->view->getHelper('MonitoringState')->getHostStateColors()); $this->view->host_pie = $this->createPie($this->view->host_states, $this->view->getHelper('MonitoringState')->getHostStateColors());
$this->view->errors = $errors; $this->view->errors = $errors;
// need the query content to list all hosts
$this->view->query = $this->_request->getQuery();
$this->handleConfigurationForm(array( $this->handleConfigurationForm(array(
'service_passive_checks_enabled' => 'Passive Checks', 'service_passive_checks_enabled' => 'Passive Checks',
'service_active_checks_enabled' => 'Active Checks', 'service_active_checks_enabled' => 'Active Checks',
'service_notifications_enabled' => 'Notifications', 'service_notifications_enabled' => 'Notifications',
'service_event_handler_enabled' => 'Event Handler', 'service_event_handler_enabled' => 'Event Handler',
'service_flap_detection_enabled' => 'Flap Detection' 'service_flap_detection_enabled' => 'Flap Detection',
'service_obsessing' => 'Obsessing',
)); ));
} }
@ -265,13 +281,8 @@ class Monitoring_MultiController extends ActionController
private function createPie($states, $colors) private function createPie($states, $colors)
{ {
$chart = new InlinePie( $chart = new InlinePie(array_values($states), $colors);
array_values($states), $chart->setLabels(array_keys($states))->setHeight(100)->setWidth(100);
$colors
);
$chart->setLabels(array_keys($states))
->setHeight(100)
->setWidth(100);
return $chart; return $chart;
} }

View File

@ -14,7 +14,7 @@ class Zend_View_Helper_SelectionToolbar extends Zend_View_Helper_Abstract
{ {
if ($type == 'multi') { if ($type == 'multi') {
return '<div class="selection-toolbar">' return '<div class="selection-toolbar">'
. '<a href="' . $target . '" data-base-target="_next"> Select All </a> </div>'; . '<a href="' . $target . '" data-base-target="_next"> Show All </a> </div>';
} else { } else {
return ''; return '';
} }

View File

@ -8,7 +8,7 @@ $helper = $this->getHelper('MonitoringState');
</div> </div>
<?= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?> <?= $this->paginationControl($hosts, null, null, array('preserve' => $this->preserve)); ?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/multi/host',array( 'host' => '*' ))); ?> <?= $this->selectionToolbar('multi', $this->href('monitoring/multi/host', $query)); ?>
</div> </div>
<div class="content"> <div class="content">

View File

@ -2,7 +2,8 @@
<?= $this->tabs ?> <?= $this->tabs ?>
<div style="margin: 1em" class="dontprint"> <div style="margin: 1em" class="dontprint">
Sort by <?= $this->sortControl->render($this) ?> Sort by <?= $this->sortControl->render($this) ?>
<!--<?= $this->selectionToolbar('single') ?>-->
<?= $this->selectionToolbar('single') ?>
</div> </div>
<?= $this->paginationControl($notifications, null, null, array('preserve' => $this->preserve)) ?> <?= $this->paginationControl($notifications, null, null, array('preserve' => $this->preserve)) ?>
</div> </div>

View File

@ -9,7 +9,10 @@ if (!$this->compact): ?>
Sort by <?= $this->sortControl ?> Sort by <?= $this->sortControl ?>
</div> </div>
<?= $this->paginationControl($services, null, null, array('preserve' => $this->preserve)); ?> <?= $this->paginationControl($services, null, null, array('preserve' => $this->preserve));?>
<?= $this->selectionToolbar('multi', $this->href('monitoring/multi/service', $query)); ?>
</div> </div>
<div class="content"> <div class="content">

View File

@ -24,10 +24,10 @@
<?= $this->icon('acknowledgement_petrol.png') ?> Acknowledge <?= $this->icon('acknowledgement_petrol.png') ?> Acknowledge
</a> </a>
</td> </td>
<td>Change <a href=" <?= $this->href( <td>Change <a data-base-target='_next' href=" <?= $this->href(
'monitoring/list/comments', 'monitoring/list/comments',
array('comment_id' => implode(',', $this->comments)) array('comment_internal_id' => implode(',', $this->comments))
); );
?>"> <?= count($comments) ?> </a> comments. ?>"> <?= count($comments) ?> comments </a>.
</td> </td>
</tr> </tr>

View File

@ -18,8 +18,8 @@
</a> </a>
</td> </td>
<td> <td>
Change <a href="<?= $this->href('') ?>" Change <a data-base-target='_next' href="<?= $this->href('') ?>"
> <?= count($downtimes) ?> > <?= count($downtimes) ?> downtimes
</a> downtimes. </a>.
</td> </td>
</tr> </tr>

View File

@ -1,6 +1,6 @@
<?php for ($i = 0; $i < count($objects) && $i < 5; $i++) { <?php for ($i = 0; $i < count($objects) && $i < 5; $i++) {
$object = $objects[$i]; ?> $object = $objects[$i]; ?>
<a href="<?php <a data-base-target='_next' href="<?php
if ($this->is_service) { if ($this->is_service) {
echo $this->href( echo $this->href(
'monitoring/show/service', 'monitoring/show/service',
@ -16,10 +16,9 @@
}?>, }?>,
<?php } ?> <?php <?php } ?> <?php
if (count($objects) > 5) { if (count($objects) > 5) {
$text = ' ' . (count($objects) - 5) . ' more ...'; echo '<i> ... ' . (count($objects) - 5) . ' more ... </i>';
} else {
$text = ' show all ... ';
} }
if (!$this->is_service) { if (!$this->is_service) {
$link = 'monitoring/list/hosts'; $link = 'monitoring/list/hosts';
$target = array( $target = array(
@ -27,10 +26,9 @@
); );
} else { } else {
$link = 'monitoring/list/services'; $link = 'monitoring/list/services';
// TODO: Show multiple targets for services
$target = array( $target = array(
'host' => $this->hostquery, 'host' => $this->hostquery,
'service' => $this->servicequery 'service' => $this->servicequery
); );
} }
?> <a href="<?= $this->href($link, $target); ?>"> <?= $text ?></a> ?> <a data-base-target='_next' href='<?= $this->href($link, $this->query); ?>'><b> list all </b></a>

View File

@ -113,8 +113,8 @@
$(document).on('click', 'a', { self: this }, this.linkClicked); $(document).on('click', 'a', { self: this }, this.linkClicked);
// Select a table row // Select a table row
$(document).on('click', 'table tr[href]', { self: this }, this.rowSelected); $(document).on('click', 'table.action tr[href]', { self: this }, this.rowSelected);
$(document).on('click', 'table tr a', { self: this }, this.rowSelected); $(document).on('click', 'table.action tr a', { self: this }, this.rowSelected);
$(document).on('click', 'button', { self: this }, this.submitForm); $(document).on('click', 'button', { self: this }, this.submitForm);
@ -256,7 +256,7 @@
var triState = parseInt($tristate.data('icinga-tristate'), 10); var triState = parseInt($tristate.data('icinga-tristate'), 10);
// load current values // load current values
var old = $tristate.data('icinga-old'); var old = $tristate.data('icinga-old').toString();
var value = $tristate.parent().find('input:radio:checked').first().prop('checked', false).val(); var value = $tristate.parent().find('input:radio:checked').first().prop('checked', false).val();
// calculate the new value // calculate the new value
@ -270,15 +270,15 @@
// 0 => 1 // 0 => 1
value = value === '1' ? '0' : '1'; value = value === '1' ? '0' : '1';
} }
// update form value // update form value
$tristate.parent().find('input:radio[value="' + value + '"]').prop('checked', true); $tristate.parent().find('input:radio[value="' + value + '"]').prop('checked', true);
// update dummy // update dummy
console.log(value + ' === ' + old + ' ?');
if (value !== old) { if (value !== old) {
$tristate.parent().find('b.tristate-changed').css('visibility', 'visible'); $tristate.parent().find('b.tristate-changed').css('visibility', 'visible');
} else { } else {
$tristate.parent().find('b.tristate-changed').hide(); $tristate.parent().find('b.tristate-changed').css('visibility', 'hidden');
} }
self.icinga.ui.setTriState(value.toString(), $tristate); self.icinga.ui.setTriState(value.toString(), $tristate);
}, },
@ -356,7 +356,7 @@
var icinga = self.icinga; var icinga = self.icinga;
var $tr = $(this); var $tr = $(this);
var $table = $tr.closest('table.multiselect'); var $table = $tr.closest('table.multiselect');
var data = $table.data('icinga-multiselect-data') && $table.data('icinga-multiselect-data').split(','); var data = self.icinga.ui.getSelectionKeys($table);
var multisel = $table.hasClass('multiselect'); var multisel = $table.hasClass('multiselect');
var url = $table.data('icinga-multiselect-url'); var url = $table.data('icinga-multiselect-url');
@ -381,7 +381,7 @@
return; return;
} }
// Update selection // update selection
if (event.ctrlKey && multisel) { if (event.ctrlKey && multisel) {
icinga.ui.toogleTableRowSelection($tr); icinga.ui.toogleTableRowSelection($tr);
// multi selection // multi selection
@ -392,23 +392,27 @@
// single selection // single selection
icinga.ui.setTableRowSelection($tr); icinga.ui.setTableRowSelection($tr);
} }
// focuse only the current table. // focus only the current table.
icinga.ui.focusTable($table[0]); icinga.ui.focusTable($table[0]);
// Update url // update url
var $target = self.getLinkTargetFor($tr); var $target = self.getLinkTargetFor($tr);
if (multisel) { if (multisel) {
var $trs = $table.find('tr[href].active'); var $trs = $table.find('tr[href].active');
if ($trs.length > 1) { if ($trs.length > 1) {
// display multiple rows var queries = [];
var query = icinga.events.selectionToQuery($trs, data, icinga); var selectionData = icinga.ui.getSelectionSetData($trs, data);
var query = icinga.ui.selectionDataToQuery(selectionData, data, icinga);
icinga.loader.loadUrl(url + '?' + query, $target); icinga.loader.loadUrl(url + '?' + query, $target);
icinga.ui.storeSelectionData(selectionData);
} else if ($trs.length === 1) { } else if ($trs.length === 1) {
// display a single row // display a single row
icinga.loader.loadUrl($tr.attr('href'), $target); icinga.loader.loadUrl($tr.attr('href'), $target);
icinga.ui.storeSelectionData($tr.attr('href'));
} else { } else {
// display nothing // display nothing
icinga.loader.loadUrl('#'); icinga.loader.loadUrl('#');
icinga.ui.storeSelectionData(null);
} }
} else { } else {
icinga.loader.loadUrl($tr.attr('href'), $target); icinga.loader.loadUrl($tr.attr('href'), $target);
@ -416,42 +420,6 @@
return false; return false;
}, },
selectionToQuery: function ($selection, data, icinga) {
var selections = [], queries = [];
if ($selection.length === 0) {
return '';
}
// read all current selections
$selection.each(function(ind, selected) {
var url = $(selected).attr('href');
var params = icinga.utils.parseUrl(url).params;
var tuple = {};
for (var i = 0; i < data.length; i++) {
var key = data[i];
if (params[key]) {
tuple[key] = params[key];
}
}
selections.push(tuple);
});
// create new url
if (selections.length < 2) {
// single-selection
$.each(selections[0], function(key, value){
queries.push(key + '=' + encodeURIComponent(value));
});
} else {
// multi-selection
$.each(selections, function(i, el){
$.each(el, function(key, value) {
queries.push(key + '[' + i + ']=' + encodeURIComponent(value));
});
});
}
return queries.join('&');
},
/** /**
* Someone clicked a link or tr[href] * Someone clicked a link or tr[href]
@ -590,8 +558,8 @@
$(window).off('beforeunload', this.onUnload); $(window).off('beforeunload', this.onUnload);
$(document).off('scroll', '.container', this.onContainerScroll); $(document).off('scroll', '.container', this.onContainerScroll);
$(document).off('click', 'a', this.linkClicked); $(document).off('click', 'a', this.linkClicked);
$(document).off('click', 'table tr[href]', this.rowSelected); $(document).off('click', 'table.action tr[href]', this.rowSelected);
$(document).off('click', 'table tr a', this.rowSelected); $(document).off('click', 'table.action tr a', this.rowSelected);
$(document).off('submit', 'form', this.submitForm); $(document).off('submit', 'form', this.submitForm);
$(document).off('click', 'button', this.submitForm); $(document).off('click', 'button', this.submitForm);
$(document).off('change', 'form select.autosubmit', this.submitForm); $(document).off('change', 'form select.autosubmit', this.submitForm);

View File

@ -248,8 +248,8 @@
// TODO: Hook for response/url? // TODO: Hook for response/url?
var $forms = $('[action="' + this.icinga.utils.parseUrl(url).path + '"]'); var $forms = $('[action="' + this.icinga.utils.parseUrl(url).path + '"]');
console.log('Old URL: ' + url);
var $matches = $.merge($('[href="' + url + '"]'), $forms); var $matches = $.merge($('[href="' + url + '"]'), $forms);
$matches.each(function (idx, el) { $matches.each(function (idx, el) {
if ($(el).closest('#menu').length) { if ($(el).closest('#menu').length) {
$('#menu .active').removeClass('active'); $('#menu .active').removeClass('active');
@ -432,7 +432,39 @@
} }
if (active) { if (active) {
$('[href="' + active + '"]', req.$target).addClass('active'); var focusedUrl = this.icinga.ui.getFocusedContainerDataUrl();
var oldSelectionData = this.icinga.ui.loadSelectionData();
if (typeof oldSelectionData === 'string') {
$('[href="' + oldSelectionData + '"]', req.$target).addClass('active');
} else if (oldSelectionData !== null) {
var $container;
if (!focusedUrl) {
$container = $('document').first();
} else {
$container = $('.container[data-icinga-url="' + focusedUrl + '"]');;
}
var $table = $container.find('table.action').first();
var keys = self.icinga.ui.getSelectionKeys($table);
// build map of selected queries
var oldSelectionQueries = {};
$.each(oldSelectionData, function(i, query){
oldSelectionQueries[self.icinga.ui.selectionDataToQueryComp(query)] = true;
});
// set all new selections to active
$table.find('tr[href]').filter(function(){
var $tr = $(this);
var rowData = self.icinga.ui.getSelectionData($tr, keys, self.icinga);
var newSelectionQuery = self.icinga.ui.selectionDataToQueryComp(rowData);
if (oldSelectionQueries[newSelectionQuery]) {
return true;
}
return false;
}).addClass('active');
}
} }
req.$target.trigger('rendered'); req.$target.trigger('rendered');
}, },

View File

@ -7,6 +7,13 @@
'use strict'; 'use strict';
// Stores the icinga-data-url of the last focused table.
var focusedTableDataUrl = null;
// The stored selection data, useful for preserving selections over
// multiple reload-cycles.
var selectionData = null;
Icinga.UI = function (icinga) { Icinga.UI = function (icinga) {
this.icinga = icinga; this.icinga = icinga;
@ -291,9 +298,6 @@
*/ */
setTableRowSelection: function ($tr) { setTableRowSelection: function ($tr) {
var $table = $tr.closest('table.multiselect'); var $table = $tr.closest('table.multiselect');
if ($tr.hasClass('active')) {
return false;
}
$table.find('tr[href].active').removeClass('active'); $table.find('tr[href].active').removeClass('active');
$tr.addClass('active'); $tr.addClass('active');
return true; return true;
@ -351,6 +355,116 @@
return false; return false;
}, },
/**
* Read the data from a whole set of selections.
*
* @param $selections {jQuery} All selected rows in a jQuery-selector.
* @param keys {Array} An array containing all valid keys.
* @returns {Array} An array containing an object with the data for each selection.
*/
getSelectionSetData: function($selections, keys) {
var selections = [];
var icinga = this.icinga;
// read all current selections
$selections.each(function(ind, selected) {
selections.push(icinga.ui.getSelectionData($(selected), keys, icinga));
});
return selections;
},
getSelectionKeys: function($selection)
{
var d = $selection.data('icinga-multiselect-data') && $selection.data('icinga-multiselect-data').split(',');
return d || [];
},
/**
* Read the data from the given selected object.
*
* @param $selection {jQuery} The selected object.
* @param keys {Array} An array containing all valid keys.
* @param icinga {Icinga} The main icinga object.
* @returns {Object} An object containing all key-value pairs associated with this selection.
*/
getSelectionData: function($selection, keys, icinga)
{
var url = $selection.attr('href');
var params = this.icinga.utils.parseUrl(url).params;
var tuple = {};
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (params[key]) {
tuple[key] = params[key];
}
}
return tuple;
},
/**
* Convert a set of selection data to a single query.
*
* @param selectionData {Array} The selection data generated from getSelectionData
* @returns {String} The formatted and uri-encoded query-string.
*/
selectionDataToQuery: function (selectionData) {
var queries = [];
// create new url
if (selectionData.length < 2) {
// single-selection
$.each(selectionData[0], function(key, value){
queries.push(key + '=' + encodeURIComponent(value));
});
} else {
// multi-selection
$.each(selectionData, function(i, el){
$.each(el, function(key, value) {
queries.push(key + '[' + i + ']=' + encodeURIComponent(value));
});
});
}
return queries.join('&');
},
/**
* Create a single query-argument (not compatible to selectionDataToQuery)
*
* @param data
* @returns {string}
*/
selectionDataToQueryComp: function(data) {
var queries = [];
$.each(data, function(key, value){
queries.push(key + '=' + encodeURIComponent(value));
});
return queries.join('&');
},
/**
* Store a set of selection-data to preserve it accross page-reloads
*
* @param data {Array|String|Null} The selection-data be an Array of Objects,
* containing the selection data (when multiple rows where selected), a
* String containing a single url (when only a single row was selected) or
* Null when nothing was selected.
*/
storeSelectionData: function(data) {
selectionData = data;
},
/**
* Load the last stored set of selection-data
*
* @returns {Array|String|Null} May be an Array of Objects, containing the selection data
* (when multiple rows where selected), a String containing a single url
* (when only a single row was selected) or Null when nothing was selected.
*/
loadSelectionData: function() {
return selectionData;
},
/** /**
* Focus the given table by deselecting all selections on all other tables. * Focus the given table by deselecting all selections on all other tables.
* *
@ -363,6 +477,17 @@
*/ */
focusTable: function (table) { focusTable: function (table) {
$('table').filter(function(){ return this !== table; }).find('tr[href]').removeClass('active'); $('table').filter(function(){ return this !== table; }).find('tr[href]').removeClass('active');
var n = $(table).closest('.container').data('icinga-url');
focusedTableDataUrl = n;
},
/**
* Return the URL of the last focused table container.
*
* @returns {String} The data-icinga-url of the last focused table, which should be unique in each site.
*/
getFocusedContainerDataUrl: function() {
return focusedTableDataUrl;
}, },
refreshDebug: function () { refreshDebug: function () {
@ -473,7 +598,7 @@
// hide input boxess and remove text nodes // hide input boxess and remove text nodes
$target.find("input").hide(); $target.find("input").hide();
$target.contents().filter(function() { return this.nodeType == 3; }).remove(); $target.contents().filter(function() { return this.nodeType === 3; }).remove();
// has three states? // has three states?
var triState = $target.find('input[value="unchanged"]').size() > 0 ? 1 : 0; var triState = $target.find('input[value="unchanged"]').size() > 0 ? 1 : 0;