Merge pull request #107 from roccivic/improved-server-variables

Improved server variables page
This commit is contained in:
Michal Čihař 2012-11-09 07:46:13 -08:00
commit 5ff82b3e1a
7 changed files with 281 additions and 254 deletions

View File

@ -70,6 +70,7 @@ VerboseMultiSubmit, ReplaceHelpImg
+ Renamed configuration directive: LeftDisplayDatabaseFilterMinimum => NavigationTreeDisplayDbFilterMinimum
+ Removed the "Mark row on click" feature; must now click the checkbox to mark
+ Removed the "Synchronize" feature
+ Improved layout of server variables page
3.5.5.0 (not yet released)

View File

@ -4,204 +4,151 @@
* Unbind all event handlers before tearing down a page
*/
AJAX.registerTeardown('server_variables.js', function() {
$('table.data tbody tr td:nth-child(2).editable').unbind('hover');
$('#serverVariables .var-row').unbind('hover');
$('#filterText').unbind('keyup');
$('a.editLink').die('click');
});
AJAX.registerOnload('server_variables.js', function() {
var textFilter = null, odd_row = false;
var testString = 'abcdefghijklmnopqrstuvwxyz0123456789,ABCEFGHIJKLMOPQRSTUVWXYZ';
var $tmpDiv, charWidth;
var $editLink = $('a.editLink');
var $saveLink = $('a.saveLink');
var $cancelLink = $('a.cancelLink');
// Global vars
$editLink = $('a.editLink');
$saveLink = $('a.saveLink');
$cancelLink = $('a.cancelLink');
/* Variable editing */
$('table.data tbody tr td:nth-child(2).editable').hover(
function() {
// Only add edit element if it is the global value, not session value and not when the element is being edited
if ($(this).parent().children('th').length > 0 && ! $(this).hasClass('edit')) {
$(this).prepend($editLink.clone().show());
/* Show edit link on hover */
$('#serverVariables').delegate('.var-row', 'hover', function(event) {
if (event.type === 'mouseenter') {
var $elm = $(this).find('.var-value');
// Only add edit element if the element is not being edited
if ($elm.hasClass('editable') && ! $elm.hasClass('edit')) {
$elm.prepend($editLink.clone().show());
}
},
function() {
} else {
$(this).find('a.editLink').remove();
}
);
$('#filterText').keyup(function(e) {
if ($(this).val().length == 0) {
textFilter=null;
} else {
textFilter = new RegExp("(^| )"+$(this).val().replace(/_/g,' '),'i');
}
filterVariables();
});
if (location.hash.substr(1).split('=')[0] == 'filter') {
var name = location.hash.substr(1).split('=')[1];
// Only allow variable names
if (! name.match(/[^0-9a-zA-Z_]+/)) {
$('#filterText').val(name).trigger('keyup');
/* Launches the variable editor */
$('a.editLink').live('click', function (event) {
event.preventDefault();
editVariable(this);
});
/* Event handler for variables filter */
$('#filterText').keyup(function() {
var textFilter = null, val = $(this).val();
if (val.length !== 0) {
textFilter = new RegExp("(^| )"+val.replace(/_/g,' '),'i');
}
}
filterVariables(textFilter);
});
/* Table width limiting */
$('table.data').after($tmpDiv=$('<span>'+testString+'</span>'));
charWidth = $tmpDiv.width() / testString.length;
$tmpDiv.remove();
$(window).resize(limitTableWidth); // FIXME: this doesn't work that well and binding anything to the window resize event is a bad idea
limitTableWidth();
/* This function chops of long variable values to keep the table from overflowing horizontally
* It does so by taking a test string and calculating an average font width and removing 'excess width / average font width'
* chars, so it is not very accurate.
*/
function limitTableWidth() {
var fulltext;
var charDiff;
var maxTableWidth;
var $tmpTable;
$('table.data').after($tmpTable = $('<table id="testTable" style="width:100%;"><tr><td>' + testString + '</td></tr></table>'));
maxTableWidth = $('#testTable').width();
$tmpTable.remove();
charDiff = ($('table.data').width() - maxTableWidth) / charWidth;
if ($('body').innerWidth() < $('table.data').width() + 10 || $('body').innerWidth() > $('table.data').width() + 20) {
var maxChars = 0;
$('table.data tbody tr td:nth-child(2)').each(function() {
maxChars = Math.max($(this).text().length, maxChars);
});
// Do not resize smaller if there's only 50 chars displayed already
if (charDiff > 0 && maxChars < 50) { return; }
$('table.data tbody tr td:nth-child(2)').each(function() {
if ((charDiff > 0 && $(this).text().length > maxChars - charDiff) || (charDiff < 0 && $(this).find('abbr.cutoff').length > 0)) {
if ($(this).find('abbr.cutoff').length > 0) {
fulltext = $(this).find('abbr.cutoff').attr('title');
} else {
fulltext = $(this).text();
// Do not cut off elements with html in it and hope they are not too long
if (fulltext.length != $(this).html().length) { return 0; }
}
if (fulltext.length < maxChars - charDiff) {
$(this).html(fulltext);
} else {
$(this).html('<abbr class="cutoff" title="' + fulltext + '">' + fulltext.substr(0, maxChars - charDiff - 3) + '...</abbr>');
}
}
});
}
/* Trigger filtering of the list based on incoming variable name */
if ($('#filterText').val()) {
$('#filterText').trigger('keyup').select();
}
/* Filters the rows by the user given regexp */
function filterVariables() {
var mark_next = false, firstCell;
odd_row = false;
$('table.filteredData tbody tr').each(function() {
firstCell = $(this).children(':first');
if (mark_next || textFilter == null || textFilter.exec(firstCell.text())) {
// If current global value is different from session value (=has class diffSession), then display that one too
mark_next = $(this).hasClass('diffSession') && ! mark_next;
function filterVariables(textFilter) {
var mark_next = false, $row, odd_row = false;
$('#serverVariables .var-row').not('.var-header').each(function() {
$row = $(this);
if ( mark_next
|| textFilter === null
|| textFilter.exec($row.find('.var-name').text())
) {
// If current global value is different from session value
// (has class diffSession), then display that one too
mark_next = $row.hasClass('diffSession') && ! mark_next;
odd_row = ! odd_row;
$(this).css('display','');
$row.css('display', '');
if (odd_row) {
$(this).addClass('odd');
$(this).removeClass('even');
$row.addClass('odd').removeClass('even');
} else {
$(this).addClass('even');
$(this).removeClass('odd');
$row.addClass('even').removeClass('odd');
}
} else {
$(this).css('display','none');
$row.css('display', 'none');
}
});
}
});
/* Called by inline js. Allows the user to edit a server variable */
function editVariable(link)
{
var varName = $(link).parent().parent().find('th:first').first().text().replace(/ /g,'_');
var $mySaveLink = $saveLink.clone().show();
var $myCancelLink = $cancelLink.clone().show();
var $cell = $(link).parent();
var $msgbox = PMA_ajaxShowMessage();
/* Allows the user to edit a server variable */
function editVariable(link) {
var $cell = $(link).parent();
var varName = $cell.parent().find('.var-name').text().replace(/ /g,'_');
var $mySaveLink = $saveLink.clone().show();
var $myCancelLink = $cancelLink.clone().show();
var $msgbox = PMA_ajaxShowMessage();
$cell.addClass('edit');
// remove edit link
$cell.find('a.editLink').remove();
$cell
.addClass('edit') // variable is being edited
.find('a.editLink')
.remove(); // remove edit link
$mySaveLink.click(function() {
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
$.get($(this).attr('href'), {
ajax_request: true,
type: 'setval',
varName: varName,
varValue: $cell.find('input').val()
}, function(data) {
if (data.success) {
$cell.html(data.variable);
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(data.error, false);
$cell.html($cell.find('span.oldContent').html());
}
$cell.removeClass('edit');
}, 'json');
return false;
});
$myCancelLink.click(function() {
$cell.html($cell.find('span.oldContent').html());
$cell.removeClass('edit');
return false;
});
$.get($mySaveLink.attr('href'), {
ajax_request: true,
type: 'getval',
varName: varName
}, function(data) {
if (data.success == true) {
// hide original content
$cell.html('<span class="oldContent" style="display:none;">' + $cell.html() + '</span>');
// put edit field and save/cancel link
$cell.prepend('<table class="serverVariableEditTable" border="0"><tr><td></td><td style="width:100%;">' +
'<input type="text" id="variableEditArea" value="' + data.message + '" /></td></tr></table>');
$cell.find('table td:first').append($mySaveLink);
$cell.find('table td:first').append(' ');
$cell.find('table td:first').append($myCancelLink);
// Keyboard shortcuts to the rescue
$('input#variableEditArea').focus();
$('input#variableEditArea').keydown(function(event) {
// Enter key
if (event.keyCode == 13) {
$mySaveLink.trigger('click');
}
// Escape key
if (event.keyCode == 27) {
$myCancelLink.trigger('click');
$mySaveLink.click(function() {
var $msgbox = PMA_ajaxShowMessage(PMA_messages.strProcessingRequest);
$.get($(this).attr('href'), {
ajax_request: true,
type: 'setval',
varName: varName,
varValue: $cell.find('input').val()
}, function(data) {
if (data.success) {
$cell
.html(data.variable)
.data('content', data.variable);
PMA_ajaxRemoveMessage($msgbox);
} else {
PMA_ajaxShowMessage(data.error, false);
$cell.html($cell.data('content'));
}
$cell.removeClass('edit');
});
PMA_ajaxRemoveMessage($msgbox);
} else {
$cell.removeClass('edit');
PMA_ajaxShowMessage(data.error);
}
return false;
});
return false;
}
$myCancelLink.click(function() {
$cell
.html($cell.data('content'))
.removeClass('edit');
return false;
});
$.get($mySaveLink.attr('href'), {
ajax_request: true,
type: 'getval',
varName: varName
}, function(data) {
if (data.success === true) {
var $editor = $('<div />', {'class':'serverVariableEditor'})
.append($myCancelLink)
.append(' ')
.append($mySaveLink)
.append(' ')
.append(
$('<div/>').append(
$('<input />', {type: 'text'}).val(data.message)
)
);
// Save and replace content
$cell
.data('content', $cell.html())
.html($editor)
.find('input')
.focus()
.keydown(function(event) { // Keyboard shortcuts
if (event.keyCode === 13) { // Enter key
$mySaveLink.trigger('click');
} else if (event.keyCode === 27) { // Escape key
$myCancelLink.trigger('click');
}
});
PMA_ajaxRemoveMessage($msgbox);
} else {
$cell.removeClass('edit');
PMA_ajaxShowMessage(data.error);
}
});
}
});

View File

@ -239,7 +239,7 @@ class Advisor
// linking to server_variables.php
$rule['recommendation'] = preg_replace(
'/\{([a-z_0-9]+)\}/Ui',
'<a href="server_variables.php?' . PMA_generate_common_url() . '#filter=\1">\1</a>',
'<a href="server_variables.php?' . PMA_generate_common_url() . '&filter=\1">\1</a>',
$this->translate($rule['recommendation'])
);

View File

@ -123,8 +123,8 @@ $output = '<h2>' . PMA_Util::getImage('s_vars.png')
/**
* Link templates
*/
$url = htmlspecialchars('server_variables.php?' . PMA_generate_common_url($db));
$output .= '<a style="display: none;" href="#" class="editLink" onclick="return editVariable(this);">';
$url = htmlspecialchars('server_variables.php?' . PMA_generate_common_url());
$output .= '<a style="display: none;" href="#" class="editLink">';
$output .= PMA_Util::getIcon('b_edit.png', __('Edit')) . '</a>';
$output .= '<a style="display: none;" href="' . $url . '" class="ajax saveLink">';
$output .= PMA_Util::getIcon('b_save.png', __('Save')) . '</a> ';
@ -142,66 +142,71 @@ $serverVars = PMA_DBI_fetch_result('SHOW GLOBAL VARIABLES;', 0, 1);
/**
* Displays the page
*/
$value = ! empty($_REQUEST['filter']) ? htmlspecialchars($_REQUEST['filter']) : '';
$output .= '<fieldset id="tableFilter">'
. '<legend>' . __('Filters') . '</legend>'
. '<div class="formelement">'
. '<label for="filterText">' . __('Containing the word:') . '</label>'
. '<input name="filterText" type="text" id="filterText"'
. ' style="vertical-align: baseline;" />'
. ' style="vertical-align: baseline;" value="' . $value . '" />'
. '</div>'
. '</fieldset>';
$output .= '<table id="serverVariables" class="data filteredData noclick">'
. '<thead>'
. '<tr><th>' . __('Variable') . '</th>'
. '<th class="valueHeader">'
$output .= '<div id="serverVariables" class="data filteredData noclick">'
. '<div class="var-header var-row">'
. '<div class="var-name">' . __('Variable') . '</div>'
. '<div class="var-value valueHeader">'
. __('Session value') . ' / ' . __('Global value')
. '</th>'
. '<th>' . __('Documentation') . '</th>'
. '</tr>'
. '</thead>'
. '<tbody>';
. '</div>'
. '<div style="clear:both"></div>'
. '</div>';
$odd_row = true;
foreach ($serverVars as $name => $value) {
$has_session_value = isset($serverVarsSession[$name])
&& $serverVarsSession[$name] != $value;
$row_class = ($odd_row ? 'odd' : 'even') . ' '
. ($has_session_value ? 'diffSession' : '');
$row_class = ($odd_row ? ' odd' : ' even')
. ($has_session_value ? ' diffSession' : '');
$output .= '<tr class="' . $row_class . '">'
. '<th class="nowrap">' . htmlspecialchars(str_replace('_', ' ', $name))
. '</th>'
. '<td class="value' . (PMA_isSuperuser() ? ' editable' : '') . '">'
. formatVariable($name, $value)
. '</td>'
. '<td class="value">';
$output .= '<div class="var-row ' . $row_class . '">'
. '<div class="var-name">';
// To display variable documentation link
if (isset($VARIABLE_DOC_LINKS[$name])) {
$output .= '<span title="' . htmlspecialchars(str_replace('_', ' ', $name)) . '">';
$output .= PMA_Util::showMySQLDocu(
$VARIABLE_DOC_LINKS[$name][1],
$VARIABLE_DOC_LINKS[$name][1],
false,
$VARIABLE_DOC_LINKS[$name][2] . '_' . $VARIABLE_DOC_LINKS[$name][0]
$VARIABLE_DOC_LINKS[$name][2] . '_' . $VARIABLE_DOC_LINKS[$name][0],
true
);
$output .= htmlspecialchars(str_replace('_', ' ', $name));
$output .= PMA_Util::getImage('b_help.png', __('Documentation'));
$output .= '</a>';
$output .= '</span>';
} else {
$output .= htmlspecialchars(str_replace('_', ' ', $name));
}
$output .= '</td>';
$output .= '</div>'
. '<div class="var-value value' . (PMA_isSuperuser() ? ' editable' : '') . '">&nbsp;'
. formatVariable($name, $value)
. '</div>'
. '<div style="clear:both"></div>'
. '</div>';
if ($has_session_value) {
$output .= '</tr>'
. '<tr class="' . ($odd_row ? 'odd' : 'even') . '">'
. '<td>(' . __('Session value') . ')</td>'
. '<td class="value">' . formatVariable($name, $serverVarsSession[$name]) . '</td>'
. '<td class="value"></td>';
$output .= '<div class="var-row ' . ($odd_row ? ' odd' : ' even') . '">'
. '<div class="var-name session">(' . __('Session value') . ')</div>'
. '<div class="var-value value">&nbsp;' . formatVariable($name, $serverVarsSession[$name]) . '</div>'
. '<div class="var-doc value"></div>'
. '<div style="clear:both"></div>'
. '</div>';
}
$output .= '</tr>';
$odd_row = ! $odd_row;
}
$output .= '</tbody>'
. '</table>';
$output .= '</div>';
$response->addHtml($output);

View File

@ -116,7 +116,7 @@ class Advisor_test extends PHPUnit_Framework_TestCase
'id' => 'Variable',
'name' => 'Variable',
'issue' => 'issue',
'recommendation' => 'Recommend <a href="server_variables.php?lang=en&amp;token=token#filter=status_var">status_var</a>'
'recommendation' => 'Recommend <a href="server_variables.php?lang=en&amp;token=token&filter=status_var">status_var</a>'
),
null,
),

View File

@ -1161,36 +1161,71 @@ div#logTable table {
/* end serverstatus */
/* server variables */
#serverVariables {
min-width: 30em;
}
#serverVariables .var-row > div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
a.editLink {
#serverVariables .var-header {
font-weight: bold;
color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
background: <?php echo $GLOBALS['cfg']['ThBackground']; ?>;
}
#serverVariables .var-header .var-value {
text-align: <?php echo $left; ?>;
}
#serverVariables .var-row {
padding: 0.5em;
min-height: 18px;
}
#serverVariables .var-name {
width: 45%;
float: <?php echo $left; ?>;
font-weight: bold;
}
#serverVariables .var-name.session {
font-weight: normal;
font-style: italic;
}
#serverVariables .var-value {
width: 50%;
float: <?php echo $right; ?>;
text-align: <?php echo $right; ?>;
}
/* server variables editor */
#serverVariables .editLink {
padding-<?php echo $right; ?>: 1em;
float: <?php echo $left; ?>;
font-family: sans-serif;
}
table.serverVariableEditTable {
border: 0;
margin: 0;
padding: 0;
#serverVariables .serverVariableEditor {
width: 100%;
overflow: hidden;
}
table.serverVariableEditTable td {
border: 0;
margin: 0;
padding: 0;
#serverVariables .serverVariableEditor input {
width: 100%;
margin: 0 0.5em;
box-sizing: border-box;
-ms-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
height: 2.2em;
}
table.serverVariableEditTable td:first-child {
white-space: nowrap;
vertical-align: middle;
#serverVariables .serverVariableEditor div {
display: block;
overflow: hidden;
padding-<?php echo $right; ?>: 1em;
}
table.serverVariableEditTable input {
width: 95%;
#serverVariables .serverVariableEditor a {
float: <?php echo $right; ?>;
margin: 0 0.5em;
line-height: 2em;
}
table#serverVariables td {
height: 18px;
}
/* end server variables */
/* querywindow */
@ -2450,12 +2485,12 @@ body .ui-widget {
}
.jqplot-yaxis-tick.jqplot-breakTick {
right: -20px;
margin-right: 0px;
padding:1px 5px 1px 5px;
/* background-color: white;*/
z-index: 2;
font-size: 1.5em;
right: -20px;
margin-right: 0px;
padding:1px 5px 1px 5px;
/* background-color: white;*/
z-index: 2;
font-size: 1.5em;
}
.jqplot-y2axis-tick, .jqplot-y3axis-tick, .jqplot-y4axis-tick, .jqplot-y5axis-tick, .jqplot-y6axis-tick, .jqplot-y7axis-tick, .jqplot-y8axis-tick, .jqplot-y9axis-tick {
@ -2642,6 +2677,6 @@ div.jqplot-bubble-label.jqplot-bubble-label-highlight {
}
div.jqplot-noData-container {
text-align: center;
background-color: rgba(96%, 96%, 96%, 0.3);
text-align: center;
background-color: rgba(96%, 96%, 96%, 0.3);
}

View File

@ -1429,36 +1429,75 @@ div#queryAnalyzerDialog table.queryNums {
/* end serverstatus */
/* server variables */
#serverVariables {
min-width: 30em;
}
#serverVariables .var-row > div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#serverVariables .var-header {
color: <?php echo $GLOBALS['cfg']['ThColor']; ?>;
background: #f3f3f3;
<?php echo $_SESSION['PMA_Theme']->getCssGradient('ffffff', 'cccccc'); ?>
font-weight: bold;
}
#serverVariables .var-header .var-value {
text-align: <?php echo $left; ?>;
}
#serverVariables .var-row {
padding: 0.5em;
min-height: 18px;
}
#serverVariables .var-name {
width: 45%;
float: <?php echo $left; ?>;
font-weight: bold;
}
#serverVariables .var-name.session {
font-weight: normal;
font-style: italic;
}
#serverVariables .var-value {
width: 50%;
float: <?php echo $right; ?>;
text-align: <?php echo $right; ?>;
}
#serverVariables .var-doc {
overflow:visible;
float: <?php echo $right; ?>;
}
a.editLink {
/* server variables editor */
#serverVariables .editLink {
padding-<?php echo $right; ?>: 1em;
float: <?php echo $left; ?>;
font-family: sans-serif;
}
table.serverVariableEditTable {
border: 0;
margin: 0;
padding: 0;
#serverVariables .serverVariableEditor {
width: 100%;
overflow: hidden;
}
table.serverVariableEditTable td {
border: 0;
margin: 0;
padding: 0;
#serverVariables .serverVariableEditor input {
width: 100%;
margin: 0 0.5em;
box-sizing: border-box;
-ms-box-sizing: border-box;
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
height: 2.2em;
}
table.serverVariableEditTable td:first-child {
white-space: nowrap;
vertical-align: middle;
#serverVariables .serverVariableEditor div {
display: block;
overflow: hidden;
padding-<?php echo $right; ?>: 1em;
}
table.serverVariableEditTable input {
width: 95%;
#serverVariables .serverVariableEditor a {
float: <?php echo $right; ?>;
margin: 0 0.5em;
line-height: 2em;
}
table#serverVariables td {
height: 18px;
}
/* end server variables */