Redesign the server status advisor page
Uses an accordion instead of a table to show the issues. Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
parent
1a3416da8d
commit
e656f341ef
@ -322,16 +322,6 @@ $javascriptMessages = [
|
||||
|
||||
'strAnalyzeQuery' => __('Analyse query'),
|
||||
|
||||
/* Server status advisor */
|
||||
|
||||
'strPerformanceIssues' => __('Possible performance issues'),
|
||||
'strIssuse' => __('Issue'),
|
||||
'strRecommendation' => __('Recommendation'),
|
||||
'strRuleDetails' => __('Rule details'),
|
||||
'strJustification' => __('Justification'),
|
||||
'strFormula' => __('Used variable / formula'),
|
||||
'strTest' => __('Test'),
|
||||
|
||||
/* For query editor */
|
||||
'strFormatting' => __('Formatting SQL…'),
|
||||
'strNoParam' => __('No parameters found!'),
|
||||
|
||||
@ -1,82 +0,0 @@
|
||||
/**
|
||||
* Server Status Advisor
|
||||
*
|
||||
* @package PhpMyAdmin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
AJAX.registerTeardown('server/status/advisor.js', function () {
|
||||
$('#statustabs_advisor').html('');
|
||||
$('#advisorDialog').remove();
|
||||
});
|
||||
|
||||
AJAX.registerOnload('server/status/advisor.js', function () {
|
||||
// if no advisor is loaded
|
||||
if ($('#advisorData').length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/** ** Server config advisor ****/
|
||||
var $dialog = $('<div></div>').attr('id', 'advisorDialog');
|
||||
|
||||
var $cnt = $('#statustabs_advisor');
|
||||
var $tbody;
|
||||
var $tr;
|
||||
var even = true;
|
||||
|
||||
var data = JSON.parse($('#advisorData').text());
|
||||
$cnt.html('');
|
||||
|
||||
if (data.parse.errors.length > 0) {
|
||||
$cnt.append('<b>Rules file not well formed, following errors were found:</b><br>- ');
|
||||
$cnt.append(data.parse.errors.join('<br>- '));
|
||||
$cnt.append('<p></p>');
|
||||
}
|
||||
|
||||
if (data.run.errors.length > 0) {
|
||||
$cnt.append('<b>Errors occurred while executing rule expressions:</b><br>- ');
|
||||
$cnt.append(data.run.errors.join('<br>- '));
|
||||
$cnt.append('<p></p>');
|
||||
}
|
||||
|
||||
if (data.run.fired.length > 0) {
|
||||
$cnt.append('<p><b>' + Messages.strPerformanceIssues + '</b></p>');
|
||||
$cnt.append('<table class="data" id="rulesFired" border="0"><thead><tr>' +
|
||||
'<th>' + Messages.strIssuse + '</th><th>' + Messages.strRecommendation +
|
||||
'</th></tr></thead><tbody></tbody></table>');
|
||||
$tbody = $cnt.find('table#rulesFired');
|
||||
|
||||
var rcStripped;
|
||||
|
||||
$.each(data.run.fired, function (key, value) {
|
||||
// recommendation may contain links, don't show those in overview table (clicking on them redirects the user)
|
||||
rcStripped = $.trim($('<div>').html(value.recommendation).text());
|
||||
$tbody.append($tr = $('<tr class="linkElem noclick"><td>' +
|
||||
value.issue + '</td><td>' + rcStripped + ' </td></tr>'));
|
||||
even = !even;
|
||||
$tr.data('rule', value);
|
||||
|
||||
$tr.on('click', function () {
|
||||
var rule = $(this).data('rule');
|
||||
$dialog
|
||||
.dialog({ title: Messages.strRuleDetails })
|
||||
.html(
|
||||
'<p><b>' + Messages.strIssuse + ':</b><br>' + rule.issue + '</p>' +
|
||||
'<p><b>' + Messages.strRecommendation + ':</b><br>' + rule.recommendation + '</p>' +
|
||||
'<p><b>' + Messages.strJustification + ':</b><br>' + rule.justification + '</p>' +
|
||||
'<p><b>' + Messages.strFormula + ':</b><br>' + rule.formula + '</p>' +
|
||||
'<p><b>' + Messages.strTest + ':</b><br>' + rule.test + '</p>'
|
||||
);
|
||||
|
||||
var dlgBtns = {};
|
||||
dlgBtns[Messages.strClose] = function () {
|
||||
$(this).dialog('close');
|
||||
};
|
||||
|
||||
$dialog.dialog({ width: 600, buttons: dlgBtns });
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -1,7 +1,5 @@
|
||||
<?php
|
||||
/**
|
||||
* Holds the PhpMyAdmin\Controllers\Server\Status\AdvisorController
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin\Controllers\Server\Status;
|
||||
@ -11,7 +9,6 @@ use PhpMyAdmin\DatabaseInterface;
|
||||
use PhpMyAdmin\Response;
|
||||
use PhpMyAdmin\Server\Status\Data;
|
||||
use PhpMyAdmin\Template;
|
||||
use function json_encode;
|
||||
|
||||
/**
|
||||
* Displays the advisor feature
|
||||
@ -36,12 +33,9 @@ class AdvisorController extends AbstractController
|
||||
|
||||
public function index(): void
|
||||
{
|
||||
$scripts = $this->response->getHeader()->getScripts();
|
||||
$scripts->addFile('server/status/advisor.js');
|
||||
|
||||
$data = '';
|
||||
$data = [];
|
||||
if ($this->data->dataLoaded) {
|
||||
$data = json_encode($this->advisor->run());
|
||||
$data = $this->advisor->run();
|
||||
}
|
||||
|
||||
$this->response->addHTML($this->template->render('server/status/advisor/index', [
|
||||
|
||||
@ -5,9 +5,10 @@
|
||||
|
||||
<h2>{% trans 'Advisor system' %}</h2>
|
||||
|
||||
{% if data is not empty %}
|
||||
|
||||
<button type="button" class="btn btn-secondary" data-toggle="modal" data-target="#advisorInstructionsModal">
|
||||
{% if data is empty %}
|
||||
{{ 'Not enough privilege to view the advisor.'|trans|error }}
|
||||
{% else %}
|
||||
<button type="button" class="btn btn-secondary mb-4" data-toggle="modal" data-target="#advisorInstructionsModal">
|
||||
{{ get_icon('b_help', 'Instructions'|trans) }}
|
||||
</button>
|
||||
|
||||
@ -49,11 +50,63 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="statustabs_advisor" class="row"></div>
|
||||
{% if data.parse.errors|length > 0 %}
|
||||
<div class="alert alert-danger mt-2 mb-2" role="alert">
|
||||
<h4 class="alert-heading">{% trans 'Rules file not well formed, following errors were found:' %}</h4>
|
||||
<ul>
|
||||
{% for error in data.parse.errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="advisorData" class="hide">{{ data }}</div>
|
||||
{% else %}
|
||||
{{ 'Not enough privilege to view the advisor.'|trans|error }}
|
||||
{% if data.run.errors|length > 0 %}
|
||||
<div class="alert alert-danger mt-2 mb-2" role="alert">
|
||||
<h4 class="alert-heading">{% trans 'Errors occurred while executing rule expressions:' %}</h4>
|
||||
<ul>
|
||||
{% for error in data.run.errors %}
|
||||
<li>{{ error }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if data.run.fired|length > 0 %}
|
||||
<h4>{% trans 'Possible performance issues' %}</h4>
|
||||
|
||||
<div class="accordion mb-4" id="rulesAccordion">
|
||||
{% for rule in data.run.fired %}
|
||||
<div class="card">
|
||||
<div class="card-header" id="heading{{ loop.index }}">
|
||||
<button class="btn btn-link{{ not loop.first ? ' collapsed' }}" type="button" data-toggle="collapse" data-target="#collapse{{ loop.index }}" aria-expanded="{{ loop.first ? 'true' : 'false' }}" aria-controls="collapse{{ loop.index }}">
|
||||
{{ rule.issue }}
|
||||
</button>
|
||||
</div>
|
||||
<div id="collapse{{ loop.index }}" class="collapse{{ loop.first ? ' show' }}" aria-labelledby="heading{{ loop.index }}" data-parent="#rulesAccordion">
|
||||
<div class="card-body">
|
||||
<dl>
|
||||
<dt>{% trans 'Issue:' %}</dt>
|
||||
<dd>{{ rule.issue }}</dd>
|
||||
|
||||
<dt>{% trans 'Recommendation:' %}</dt>
|
||||
<dd>{{ rule.recommendation|raw }}</dd>
|
||||
|
||||
<dt>{% trans 'Justification:' %}</dt>
|
||||
<dd>{{ rule.justification }}</dd>
|
||||
|
||||
<dt>{% trans 'Used variable / formula:' %}</dt>
|
||||
<dd>{{ rule.formula }}</dd>
|
||||
|
||||
<dt>{% trans 'Test:' %}</dt>
|
||||
<dd>{{ rule.test }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@ -120,21 +120,5 @@ class AdvisorControllerTest extends TestCase
|
||||
'Do note however that this system provides recommendations',
|
||||
$html
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
'<div id="advisorData" class="hide">',
|
||||
$html
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars(json_encode('parse')),
|
||||
$html
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars(json_encode('errors')),
|
||||
$html
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars(json_encode('run')),
|
||||
$html
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,3 +7,22 @@
|
||||
.card-body ul {
|
||||
padding-#{$left}: 0;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
> .card {
|
||||
border-radius: 0;
|
||||
|
||||
> .card-header {
|
||||
background-color: $button-background;
|
||||
|
||||
.btn {
|
||||
color: $button-color;
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,3 +19,24 @@
|
||||
-webkit-box-shadow: 1px 1px 15px #999 inset;
|
||||
box-shadow: 1px 1px 15px #999 inset;
|
||||
}
|
||||
|
||||
.accordion {
|
||||
> .card {
|
||||
> .card-header {
|
||||
background-color: inherit;
|
||||
box-shadow: none;
|
||||
|
||||
.btn {
|
||||
color: #235a81;
|
||||
|
||||
&:active {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-body {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user