Replace jqPlot with Chart.js in /server/status/queries
Signed-off-by: Maurício Meneghini Fauth <mauricio@fauth.dev>
This commit is contained in:
parent
35874a1172
commit
62d16a07ee
@ -42,11 +42,11 @@ ChartFactory.prototype = {
|
||||
* @param elementId
|
||||
* id of the div element the chart is drawn in
|
||||
*/
|
||||
var Chart = function (elementId = undefined) {
|
||||
var AbstractChart = function (elementId = undefined) {
|
||||
this.elementId = elementId;
|
||||
};
|
||||
|
||||
Chart.prototype = {
|
||||
AbstractChart.prototype = {
|
||||
draw: function () {
|
||||
throw new Error('draw must be implemented by a subclass');
|
||||
},
|
||||
@ -74,10 +74,10 @@ Chart.prototype = {
|
||||
* id of the div element the chart is drawn in
|
||||
*/
|
||||
var BaseChart = function (elementId = undefined) {
|
||||
Chart.call(this, elementId);
|
||||
AbstractChart.call(this, elementId);
|
||||
};
|
||||
|
||||
BaseChart.prototype = new Chart();
|
||||
BaseChart.prototype = new AbstractChart();
|
||||
BaseChart.prototype.constructor = BaseChart;
|
||||
BaseChart.prototype.validateColumns = function (dataTable) {
|
||||
var columns = dataTable.getColumns();
|
||||
@ -220,12 +220,12 @@ var DataTable = function () {
|
||||
* id of the div element the chart is drawn in
|
||||
*/
|
||||
var JQPlotChart = function (elementId = undefined) {
|
||||
Chart.call(this, elementId);
|
||||
AbstractChart.call(this, elementId);
|
||||
this.plot = null;
|
||||
this.validator = null;
|
||||
};
|
||||
|
||||
JQPlotChart.prototype = new Chart();
|
||||
JQPlotChart.prototype = new AbstractChart();
|
||||
JQPlotChart.prototype.constructor = JQPlotChart;
|
||||
JQPlotChart.prototype.draw = function (data, options) {
|
||||
if (this.validator.validateColumns(data)) {
|
||||
|
||||
@ -1,43 +1,37 @@
|
||||
import $ from 'jquery';
|
||||
import { AJAX } from '../../modules/ajax.ts';
|
||||
import createProfilingChart from '../../modules/functions/createProfilingChart.ts';
|
||||
|
||||
/**
|
||||
* @fileoverview Javascript functions used in server status query page
|
||||
* @name Server Status Query
|
||||
*
|
||||
* @requires jQueryUI
|
||||
*/
|
||||
|
||||
/**
|
||||
* Unbind all event handlers before tearing down a page
|
||||
*/
|
||||
AJAX.registerTeardown('server/status/queries.js', function () {
|
||||
if (document.getElementById('serverstatusquerieschart') !== null) {
|
||||
var queryPieChart = $('#serverstatusquerieschart').data('queryPieChart');
|
||||
if (queryPieChart) {
|
||||
queryPieChart.destroy();
|
||||
}
|
||||
function buildQueryStatsChart (): void {
|
||||
const queryStatisticsChartCanvas = document.getElementById('query-statistics-chart') as HTMLCanvasElement;
|
||||
if (! queryStatisticsChartCanvas) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
AJAX.registerOnload('server/status/queries.js', function () {
|
||||
// Build query statistics chart
|
||||
var cdata = [];
|
||||
const chartDataJson = queryStatisticsChartCanvas.getAttribute('data-chart-data');
|
||||
let chartData = null;
|
||||
try {
|
||||
if (document.getElementById('serverstatusquerieschart') !== null) {
|
||||
$.each($('#serverstatusquerieschart').data('chart'), function (key, value) {
|
||||
cdata.push([key, parseInt(value, 10)]);
|
||||
});
|
||||
|
||||
$('#serverstatusquerieschart').data(
|
||||
'queryPieChart',
|
||||
createProfilingChart('serverstatusquerieschart', cdata)
|
||||
);
|
||||
}
|
||||
} catch (exception) {
|
||||
// Could not load chart, no big deal...
|
||||
chartData = JSON.parse(chartDataJson);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.initTableSorter('statustabs_queries');
|
||||
if (! (chartData && 'labels' in chartData && 'data' in chartData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
new window.Chart(queryStatisticsChartCanvas, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: chartData.labels,
|
||||
datasets: [
|
||||
{
|
||||
label: window.Messages.numberOfStatements,
|
||||
data: chartData.data,
|
||||
}
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
AJAX.registerOnload('server/status/queries.js', function (): void {
|
||||
buildQueryStatsChart();
|
||||
});
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
import $ from 'jquery';
|
||||
|
||||
// TODO: tablesorter shouldn't sort already sorted columns
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function initTableSorter (tabid) {
|
||||
var $table;
|
||||
var opts;
|
||||
switch (tabid) {
|
||||
case 'statustabs_queries':
|
||||
$table = $('#serverStatusQueriesDetails');
|
||||
opts = {
|
||||
sortList: [[3, 1]],
|
||||
headers: {
|
||||
1: { sorter: 'fancyNumber' },
|
||||
2: { sorter: 'fancyNumber' }
|
||||
}
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$table.tablesorter(opts);
|
||||
$table.find('tr').first().find('th')
|
||||
.append('<div class="sorticon"></div>');
|
||||
}
|
||||
|
||||
window.initTableSorter = initTableSorter;
|
||||
|
||||
$(function () {
|
||||
$.tablesorter.addParser({
|
||||
id: 'fancyNumber',
|
||||
is: function (s) {
|
||||
return (/^[0-9]?[0-9,\\.]*\s?(k|M|G|T|%)?$/).test(s);
|
||||
},
|
||||
format: function (s) {
|
||||
var num = $.tablesorter.formatFloat(
|
||||
s.replace(window.Messages.strThousandsSeparator, '')
|
||||
.replace(window.Messages.strDecimalSeparator, '.')
|
||||
);
|
||||
|
||||
var factor = 1;
|
||||
switch (s.charAt(s.length - 1)) {
|
||||
case '%':
|
||||
factor = -2;
|
||||
break;
|
||||
// Todo: Complete this list (as well as in the regexp a few lines up)
|
||||
case 'k':
|
||||
factor = 3;
|
||||
break;
|
||||
case 'M':
|
||||
factor = 6;
|
||||
break;
|
||||
case 'G':
|
||||
factor = 9;
|
||||
break;
|
||||
case 'T':
|
||||
factor = 12;
|
||||
break;
|
||||
}
|
||||
|
||||
return num * Math.pow(10, factor);
|
||||
},
|
||||
type: 'numeric'
|
||||
});
|
||||
|
||||
$.tablesorter.addParser({
|
||||
id: 'withinSpanNumber',
|
||||
is: function (s) {
|
||||
return (/<span class="original"/).test(s);
|
||||
},
|
||||
format: function (s, table, html) {
|
||||
var res = html.innerHTML.match(/<span(\s*style="display:none;"\s*)?\s*class="original">(.*)?<\/span>/);
|
||||
|
||||
return (res && res.length >= 3) ? res[2] : 0;
|
||||
},
|
||||
type: 'numeric'
|
||||
});
|
||||
});
|
||||
@ -170,6 +170,8 @@ final class JavaScriptMessagesController
|
||||
|
||||
'strChartConnectionsTitle' => __('Connections / Processes'),
|
||||
|
||||
'numberOfStatements' => __('Number of statements'),
|
||||
|
||||
/* server status monitor */
|
||||
'strIncompatibleMonitorConfig' => __('Local monitor configuration incompatible!'),
|
||||
'strIncompatibleMonitorConfigDescription' => __(
|
||||
|
||||
@ -47,7 +47,6 @@ class MonitorController extends AbstractController
|
||||
'vendor/jqplot/plugins/jqplot.cursor.js',
|
||||
'jqplot/plugins/jqplot.byteFormatter.js',
|
||||
'server/status/monitor.js',
|
||||
'server/status/sorter.js',
|
||||
'chart.js',// Needed by createProfilingChart in server/status/monitor.js
|
||||
]);
|
||||
|
||||
|
||||
@ -15,11 +15,16 @@ use PhpMyAdmin\Template;
|
||||
use PhpMyAdmin\Url;
|
||||
|
||||
use function __;
|
||||
use function array_keys;
|
||||
use function array_sum;
|
||||
use function array_values;
|
||||
use function arsort;
|
||||
use function count;
|
||||
use function mb_convert_case;
|
||||
use function str_replace;
|
||||
|
||||
use const MB_CASE_TITLE;
|
||||
|
||||
class QueriesController extends AbstractController
|
||||
{
|
||||
public function __construct(
|
||||
@ -39,17 +44,9 @@ class QueriesController extends AbstractController
|
||||
$this->dbi->selectDb('mysql');
|
||||
}
|
||||
|
||||
$this->addScriptFiles([
|
||||
'chart.js',
|
||||
'vendor/jqplot/jquery.jqplot.js',
|
||||
'vendor/jqplot/plugins/jqplot.pieRenderer.js',
|
||||
'vendor/jqplot/plugins/jqplot.highlighter.js',
|
||||
'vendor/jqplot/plugins/jqplot.enhancedPieLegendRenderer.js',
|
||||
'vendor/jquery/jquery.tablesorter.js',
|
||||
'server/status/sorter.js',
|
||||
'server/status/queries.js',
|
||||
]);
|
||||
$this->addScriptFiles(['vendor/chart.umd.js', 'server/status/queries.js']);
|
||||
|
||||
$chart = [];
|
||||
if ($this->data->dataLoaded) {
|
||||
$hourFactor = 3600 / $this->data->status['Uptime'];
|
||||
$usedQueries = $this->data->usedQueries;
|
||||
@ -65,7 +62,6 @@ class QueriesController extends AbstractController
|
||||
// reverse sort by value to show most used statements first
|
||||
arsort($usedQueries);
|
||||
|
||||
$chart = [];
|
||||
$querySum = array_sum($usedQueries);
|
||||
$otherSum = 0;
|
||||
$queries = [];
|
||||
@ -73,13 +69,13 @@ class QueriesController extends AbstractController
|
||||
// For the percentage column, use Questions - Connections, because
|
||||
// the number of connections is not an item of the Query types
|
||||
// but is included in Questions. Then the total of the percentages is 100.
|
||||
$name = str_replace(['Com_', '_'], ['', ' '], $key);
|
||||
$name = mb_convert_case(str_replace(['Com_', '_'], ['', ' '], $key), MB_CASE_TITLE);
|
||||
// Group together values that make out less than 2% into "Other", but only
|
||||
// if we have more than 6 fractions already
|
||||
if ($value < $querySum * 0.02 && count($chart) > 6) {
|
||||
$otherSum += $value;
|
||||
} else {
|
||||
$chart[$name] = $value;
|
||||
$chart[$name] = (int) $value;
|
||||
}
|
||||
|
||||
$queries[$key] = [
|
||||
@ -91,15 +87,17 @@ class QueriesController extends AbstractController
|
||||
}
|
||||
|
||||
if ($otherSum > 0) {
|
||||
$chart[__('Other')] = $otherSum;
|
||||
$chart[__('Other statements')] = $otherSum;
|
||||
}
|
||||
}
|
||||
|
||||
$chartData = ['labels' => array_keys($chart), 'data' => array_values($chart)];
|
||||
|
||||
$this->render('server/status/queries/index', [
|
||||
'is_data_loaded' => $this->data->dataLoaded,
|
||||
'stats' => $stats ?? null,
|
||||
'queries' => $queries ?? [],
|
||||
'chart' => $chart ?? [],
|
||||
'chart_data' => $chartData,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,6 @@ class VariablesController extends AbstractController
|
||||
$this->addScriptFiles([
|
||||
'server/status/variables.js',
|
||||
'vendor/jquery/jquery.tablesorter.js',
|
||||
'server/status/sorter.js',
|
||||
]);
|
||||
|
||||
$flush = $request->getParsedBodyParam('flush');
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
"@babel/preset-typescript": "^7.21.0",
|
||||
"@popperjs/core": "^2.11.7",
|
||||
"@types/bootstrap": "^5.2.6",
|
||||
"@types/chart.js": "^2.9.37",
|
||||
"@types/codemirror": "^5.60.7",
|
||||
"@types/jquery": "^3.5.16",
|
||||
"@types/jquery.ui.datetimepicker": "^0.3.30",
|
||||
@ -27,6 +28,7 @@
|
||||
"autoprefixer": "^10.4.14",
|
||||
"babel-loader": "^9.1.2",
|
||||
"bootstrap": "5.3.0-alpha2",
|
||||
"chart.js": "^4.2.1",
|
||||
"codemirror": "5.65.12",
|
||||
"copy-webpack-plugin": "^11.0.0",
|
||||
"css-loader": "^6.6.0",
|
||||
|
||||
@ -1950,6 +1950,11 @@ parameters:
|
||||
count: 2
|
||||
path: libraries/classes/Controllers/Server/Status/ProcessesController.php
|
||||
|
||||
-
|
||||
message: "#^Cannot cast mixed to int\\.$#"
|
||||
count: 1
|
||||
path: libraries/classes/Controllers/Server/Status/QueriesController.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, \\(int\\|string\\) given\\.$#"
|
||||
count: 1
|
||||
|
||||
@ -2987,8 +2987,7 @@
|
||||
<code>$key</code>
|
||||
</MixedArgumentTypeCoercion>
|
||||
<MixedAssignment>
|
||||
<code>$chart[$name]</code>
|
||||
<code><![CDATA[$chart[__('Other')]]]></code>
|
||||
<code><![CDATA[$chart[__('Other statements')]]]></code>
|
||||
<code>$hourFactor</code>
|
||||
<code>$otherSum</code>
|
||||
<code>$value</code>
|
||||
|
||||
@ -607,11 +607,6 @@ div#tablestatistics table {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h3#serverstatusqueries span {
|
||||
font-size: 60%;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div#serverStatusTabs {
|
||||
margin-top: 1em;
|
||||
}
|
||||
@ -620,13 +615,6 @@ caption a.top {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div#serverstatusquerieschart {
|
||||
float: left;
|
||||
width: 500px;
|
||||
height: 350px;
|
||||
margin-right: 50px;
|
||||
}
|
||||
|
||||
div {
|
||||
&#serverstatus table {
|
||||
tbody td.descr a,
|
||||
@ -2666,11 +2654,6 @@ body .ui-dialog {
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
div#serverstatusquerieschart {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.ui-dialog {
|
||||
margin: 1%;
|
||||
width: 95% !important;
|
||||
|
||||
@ -817,11 +817,6 @@ div#tablestatistics table {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h3#serverstatusqueries span {
|
||||
font-size: 60%;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div#serverStatusTabs {
|
||||
margin-top: 1em;
|
||||
}
|
||||
@ -830,13 +825,6 @@ caption a.top {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div#serverstatusquerieschart {
|
||||
float: left;
|
||||
width: 500px;
|
||||
height: 350px;
|
||||
padding-left: 30px;
|
||||
}
|
||||
|
||||
div {
|
||||
&#serverstatus table {
|
||||
tbody td.descr a,
|
||||
|
||||
@ -638,11 +638,6 @@ div#tablestatistics table {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h3#serverstatusqueries span {
|
||||
font-size: 60%;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div#serverStatusTabs {
|
||||
margin-top: 1em;
|
||||
}
|
||||
@ -651,15 +646,6 @@ caption a.top {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div {
|
||||
&#serverstatusquerieschart {
|
||||
float: left;
|
||||
width: 500px;
|
||||
height: 350px;
|
||||
margin-right: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
div {
|
||||
&#serverstatus table {
|
||||
tbody td.descr a,
|
||||
@ -2672,11 +2658,6 @@ body {
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
div#serverstatusquerieschart {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.ui-dialog {
|
||||
margin: 1%;
|
||||
width: 95% !important;
|
||||
|
||||
@ -780,11 +780,6 @@ div#tablestatistics table {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
h3#serverstatusqueries span {
|
||||
font-size: 60%;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div#serverStatusTabs {
|
||||
margin-top: 1em;
|
||||
}
|
||||
@ -793,13 +788,6 @@ caption a.top {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div#serverstatusquerieschart {
|
||||
float: left;
|
||||
width: 500px;
|
||||
height: 350px;
|
||||
margin-right: 50px;
|
||||
}
|
||||
|
||||
div {
|
||||
&#serverstatus table {
|
||||
tbody td.descr a,
|
||||
@ -2802,11 +2790,6 @@ body .ui-dialog {
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
div#serverstatusquerieschart {
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.ui-dialog {
|
||||
margin: 1%;
|
||||
width: 95% !important;
|
||||
|
||||
@ -1,62 +1,57 @@
|
||||
{% extends 'server/status/base.twig' %}
|
||||
{% set active = 'queries' %}
|
||||
{% block content %}
|
||||
<div class="container">
|
||||
{% if not is_data_loaded %}
|
||||
{{ 'Not enough privilege to view query statistics.'|trans|error }}
|
||||
{% else %}
|
||||
<h3>
|
||||
{% trans %}Questions since startup:{% notes %}Questions is the name of a MySQL Status variable{% endtrans %} {{ format_number(stats.total, 0) }}
|
||||
{{ show_mysql_docu('server-status-variables', false, null, null, 'statvar_Questions') }}
|
||||
</h3>
|
||||
|
||||
{% if is_data_loaded %}
|
||||
<div class="row">
|
||||
<h3 id="serverstatusqueries">
|
||||
{% trans %}
|
||||
Questions since startup:
|
||||
{% notes %}
|
||||
Questions is the name of a MySQL Status variable
|
||||
{% endtrans %}
|
||||
{{ format_number(stats.total, 0) }}
|
||||
{{ show_mysql_docu('server-status-variables', false, null, null, 'statvar_Questions') }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<ul>
|
||||
<li>ø {% trans 'per hour:' %} {{ format_number(stats.per_hour, 0) }}</li>
|
||||
<li>ø {% trans 'per minute:' %} {{ format_number(stats.per_minute, 0) }}</li>
|
||||
{% if stats.per_second >= 1 %}
|
||||
<li>ø {% trans 'per second:' %} {{ format_number(stats.per_second, 0) }}</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<ul>
|
||||
<li>ø {% trans 'per hour:' %} {{ format_number(stats.per_hour, 0) }}</li>
|
||||
<li>ø {% trans 'per minute:' %} {{ format_number(stats.per_minute, 0) }}</li>
|
||||
{% if stats.per_second >= 1 %}
|
||||
<li>ø {% trans 'per second:' %} {{ format_number(stats.per_second, 0) }}</li>
|
||||
<div class="row">
|
||||
<table id="serverStatusQueriesDetails" class="table table-striped table-hover col">
|
||||
<colgroup>
|
||||
<col class="namecol">
|
||||
<col class="valuecol" span="3">
|
||||
</colgroup>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Statements' %}</th>
|
||||
<th class="text-end" scope="col">{% trans %}#{% notes %}# = Amount of queries{% endtrans %}</th>
|
||||
<th class="text-end" scope="col">{% trans 'ø per hour' %}</th>
|
||||
<th class="text-end" scope="col">%</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for query in queries %}
|
||||
<tr>
|
||||
<th scope="row">{{ query.name }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(query.value, 5, 0, true) }}</td>
|
||||
<td class="font-monospace text-end">{{ format_number(query.per_hour, 4, 1, true) }}</td>
|
||||
<td class="font-monospace text-end">{{ format_number(query.percentage, 0, 2) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="col">
|
||||
<canvas id="query-statistics-chart" data-chart-data="{{ chart_data|json_encode|e('html_attr') }}" aria-label="{{ 'Pie chart with the most frequent statements.'|trans }}" role="img"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<table id="serverStatusQueriesDetails" class="table table-striped table-hover sortable col-md-4 col-12 w-auto">
|
||||
<colgroup>
|
||||
<col class="namecol">
|
||||
<col class="valuecol" span="3">
|
||||
</colgroup>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{% trans 'Statements' %}</th>
|
||||
<th class="text-end" scope="col">{% trans %}#{% notes %}# = Amount of queries{% endtrans %}</th>
|
||||
<th class="text-end" scope="col">{% trans 'ø per hour' %}</th>
|
||||
<th class="text-end" scope="col">%</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for query in queries %}
|
||||
<tr>
|
||||
<th scope="row">{{ query.name }}</th>
|
||||
<td class="font-monospace text-end">{{ format_number(query.value, 5, 0, true) }}</td>
|
||||
<td class="font-monospace text-end">{{ format_number(query.per_hour, 4, 1, true) }}</td>
|
||||
<td class="font-monospace text-end">{{ format_number(query.percentage, 0, 2) }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div id="serverstatusquerieschart" class="w-100 col-12 col-md-6" data-chart="{{ chart|json_encode }}"></div>
|
||||
</div>
|
||||
{% else %}
|
||||
{{ 'Not enough privilege to view query statistics.'|trans|error }}
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@ -74,65 +74,28 @@ class QueriesControllerTest extends AbstractTestCase
|
||||
$usedQueries = $this->data->usedQueries;
|
||||
$totalQueries = array_sum($usedQueries);
|
||||
|
||||
$questionsFromStart = __('Questions since startup:')
|
||||
. ' ' . Util::formatNumber($totalQueries, 0);
|
||||
$questionsFromStart = __('Questions since startup:') . ' ' . Util::formatNumber($totalQueries, 0);
|
||||
|
||||
$this->assertStringContainsString('<h3 id="serverstatusqueries">', $html);
|
||||
$this->assertStringContainsString('<h3>', $html);
|
||||
$this->assertStringContainsString($questionsFromStart, $html);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
__('per hour:'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
Util::formatNumber($totalQueries * $hourFactor, 0),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString('per hour:', $html);
|
||||
$this->assertStringContainsString(Util::formatNumber($totalQueries * $hourFactor, 0), $html);
|
||||
|
||||
$valuePerMinute = Util::formatNumber($totalQueries * 60 / $this->data->status['Uptime'], 0);
|
||||
$this->assertStringContainsString(
|
||||
__('per minute:'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars($valuePerMinute),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString('per minute:', $html);
|
||||
$this->assertStringContainsString(htmlspecialchars($valuePerMinute), $html);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
__('Statements'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString('Statements', $html);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars('change db'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString('Change Db', $html);
|
||||
$this->assertStringContainsString('54', $html);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars('select'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars('set option'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars('show databases'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars('show status'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString(
|
||||
htmlspecialchars('show tables'),
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString('Select', $html);
|
||||
$this->assertStringContainsString('Set Option', $html);
|
||||
$this->assertStringContainsString('Show Databases', $html);
|
||||
$this->assertStringContainsString('Show Status', $html);
|
||||
$this->assertStringContainsString('Show Tables', $html);
|
||||
|
||||
$this->assertStringContainsString(
|
||||
'<div id="serverstatusquerieschart" class="w-100 col-12 col-md-6" data-chart="',
|
||||
$html,
|
||||
);
|
||||
$this->assertStringContainsString('<canvas id="query-statistics-chart" data-chart-data="', $html);
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +68,6 @@ module.exports = [
|
||||
'server/status/monitor': rootPath + '/js/src/server/status/monitor.ts',
|
||||
'server/status/processes': rootPath + '/js/src/server/status/processes.ts',
|
||||
'server/status/queries': rootPath + '/js/src/server/status/queries.ts',
|
||||
'server/status/sorter': rootPath + '/js/src/server/status/sorter.ts',
|
||||
'server/status/variables': rootPath + '/js/src/server/status/variables.ts',
|
||||
'server/user_groups': rootPath + '/js/src/server/user_groups.ts',
|
||||
'server/variables': rootPath + '/js/src/server/variables.ts',
|
||||
@ -173,6 +172,7 @@ module.exports = [
|
||||
{ from: rootPath + '/node_modules/updated-jqplot/build/plugins/jqplot.canvasAxisLabelRenderer.js', to: publicPath + '/js/vendor/jqplot/plugins/jqplot.canvasAxisLabelRenderer.js' },
|
||||
{ from: rootPath + '/node_modules/updated-jqplot/build/plugins/jqplot.cursor.js', to: publicPath + '/js/vendor/jqplot/plugins/jqplot.cursor.js' },
|
||||
{ from: rootPath + '/node_modules/updated-jqplot/build/plugins/jqplot.highlighter.js', to: publicPath + '/js/vendor/jqplot/plugins/jqplot.highlighter.js' },
|
||||
{ from: rootPath + '/node_modules/chart.js/dist/chart.umd.js', to: publicPath + '/js/vendor/chart.umd.js' },
|
||||
],
|
||||
}),
|
||||
new WebpackConcatPlugin({
|
||||
|
||||
24
yarn.lock
24
yarn.lock
@ -1310,6 +1310,11 @@
|
||||
"@jridgewell/resolve-uri" "3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||
|
||||
"@kurkle/color@^0.3.0":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@kurkle/color/-/color-0.3.2.tgz#5acd38242e8bde4f9986e7913c8fdf49d3aa199f"
|
||||
integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==
|
||||
|
||||
"@mapbox/jsonlint-lines-primitives@~2.0.2":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234"
|
||||
@ -1449,6 +1454,13 @@
|
||||
dependencies:
|
||||
"@popperjs/core" "^2.9.2"
|
||||
|
||||
"@types/chart.js@^2.9.37":
|
||||
version "2.9.37"
|
||||
resolved "https://registry.yarnpkg.com/@types/chart.js/-/chart.js-2.9.37.tgz#8af70862b154fedf938b5b87debdb3a70f6e3208"
|
||||
integrity sha512-9bosRfHhkXxKYfrw94EmyDQcdjMaQPkU1fH2tDxu8DWXxf1mjzWQAV4laJF51ZbC2ycYwNDvIm1rGez8Bug0vg==
|
||||
dependencies:
|
||||
moment "^2.10.2"
|
||||
|
||||
"@types/codemirror@^5.60.7":
|
||||
version "5.60.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/codemirror/-/codemirror-5.60.7.tgz#efbb78e5e79f90c6762c2127c02096648e600808"
|
||||
@ -2250,6 +2262,13 @@ char-regex@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf"
|
||||
integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==
|
||||
|
||||
chart.js@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-4.2.1.tgz#d2bd5c98e9a0ae35408975b638f40513b067ba1d"
|
||||
integrity sha512-6YbpQ0nt3NovAgOzbkSSeeAQu/3za1319dPUQTXn9WcOpywM8rGKxJHrhS8V8xEkAlk8YhEfjbuAPfUyp6jIsw==
|
||||
dependencies:
|
||||
"@kurkle/color" "^0.3.0"
|
||||
|
||||
"chokidar@>=3.0.0 <4.0.0", chokidar@^3.3.0, chokidar@^3.4.0:
|
||||
version "3.5.3"
|
||||
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
|
||||
@ -4175,6 +4194,11 @@ minimist@^1.2.6:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
|
||||
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
|
||||
|
||||
moment@^2.10.2:
|
||||
version "2.29.4"
|
||||
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
|
||||
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==
|
||||
|
||||
ms@2.1.2:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user