inception/redis-cache/assets/js/admin.js

489 lines
17 KiB
JavaScript
Raw Normal View History

2023-08-13 23:40:17 +02:00
( function ( $, root, undefined ) {
root.rediscache = root.rediscache || {};
var rediscache = root.rediscache;
$.extend( rediscache, {
metrics: {
computed: null,
},
chart: null,
chart_defaults: {
noData: {
text: root.rediscache_metrics
? rediscache.l10n.no_data
: rediscache.l10n.no_cache,
align: 'center',
verticalAlign: 'middle',
offsetY: -25,
style: {
color: '#72777c',
fontSize: '14px',
fontFamily: 'inherit',
}
},
stroke: {
width: [2, 2],
curve: 'smooth',
dashArray: [0, 8],
},
colors: [
'#0096dd',
'#72777c',
],
annotations: {
texts: [{
x: '15%',
y: '30%',
fontSize: '20px',
fontWeight: 600,
fontFamily: 'inherit',
foreColor: '#72777c',
}],
},
chart: {
type: 'line',
height: $( '#metrics-pane #widget-redis-stats' ).length ? '300px' : '100%',
toolbar: { show: false },
zoom: { enabled: false },
animations: { enabled: false },
},
dataLabels: {
enabled: false,
},
legend: {
show: false,
},
fill: {
opacity: [0.25, 1],
},
xaxis: {
type: 'datetime',
labels: {
format: 'HH:mm',
datetimeUTC: false,
style: { colors: '#72777c', fontSize: '13px', fontFamily: 'inherit' },
},
tooltip: { enabled: false },
},
yaxis: {
type: 'numeric',
tickAmount: 4,
min: 0,
labels: {
style: { colors: '#72777c', fontSize: '13px', fontFamily: 'inherit' },
formatter: function ( value ) {
return Math.round( value );
},
},
},
tooltip: {
fixed: {
enabled: true,
position: 'bottomLeft',
offsetY: 15,
offsetX: 0,
},
}
},
templates: {
tooltip_title: _.template(
'<div class="apexcharts-tooltip-title"><%- title %></div>'
),
series_group: _.template(
'<div class="apexcharts-tooltip-series-group">' +
' <span class="apexcharts-tooltip-marker" style="background-color: <%- color %>;"></span>' +
' <div class="apexcharts-tooltip-text">' +
' <div class="apexcharts-tooltip-y-group">' +
' <span class="apexcharts-tooltip-text-label"><%- name %>:</span>' +
' <span class="apexcharts-tooltip-text-value"><%- value %></span>' +
' </div>' +
' </div>' +
'</div>'
),
series_pro: _.template(
'<div class="apexcharts-tooltip-series-group">' +
' <span class="apexcharts-tooltip-marker" style="background-color: <%- color %>;"></span>' +
' <div class="apexcharts-tooltip-text">' +
' <div class="apexcharts-tooltip-y-group">' +
' <span class="apexcharts-tooltip-text-label"><%- name %></span>' +
' </div>' +
' </div>' +
'</div>'
),
}
} );
// Build the charts by deep extending the chart defaults
$.extend( rediscache, {
charts: {
time: $.extend( true, {}, rediscache.chart_defaults, {
yaxis: {
labels: {
formatter: function ( value ) {
return Math.round( value ) + ' ms';
},
},
},
tooltip: {
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
return [
rediscache.templates.tooltip_title({
title: new Date( w.globals.seriesX[ seriesIndex ][ dataPointIndex ] )
.toTimeString().slice( 0, 5 ),
}),
rediscache.templates.series_group({
color: rediscache.chart_defaults.colors[0],
name: w.globals.seriesNames[0],
value: series[0][ dataPointIndex ].toFixed(2) + ' ms',
}),
rediscache.templates.series_pro({
color: rediscache.chart_defaults.colors[1],
name: rediscache.l10n.pro,
}),
].join('');
},
},
} ),
bytes: $.extend( true, {}, rediscache.chart_defaults, {
yaxis: {
labels: {
formatter: function ( value ) {
var i = value === 0 ? 0 : Math.floor( Math.log( value ) / Math.log( 1024 ) );
return parseFloat( (value / Math.pow( 1024, i ) ).toFixed( i ? 2 : 0 ) ) + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];
},
},
},
tooltip: {
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
var value = series[0][ dataPointIndex ];
var i = value === 0 ? 0 : Math.floor( Math.log( value ) / Math.log( 1024 ) );
var bytes = parseFloat( (value / Math.pow( 1024, i ) ).toFixed( i ? 2 : 0 ) ) + ' ' + ['B', 'KB', 'MB', 'GB', 'TB'][i];
return [
rediscache.templates.tooltip_title({
title: new Date( w.globals.seriesX[ seriesIndex ][ dataPointIndex ] ).toTimeString().slice( 0, 5 ),
}),
rediscache.templates.series_group({
color: rediscache.chart_defaults.colors[0],
name: w.globals.seriesNames[0],
value: bytes,
}),
rediscache.templates.series_pro({
color: rediscache.chart_defaults.colors[1],
name: rediscache.l10n.pro,
}),
].join('');
},
},
} ),
ratio: $.extend( true, {}, rediscache.chart_defaults, {
yaxis: {
max: 100,
labels: {
formatter: function ( value ) {
return Math.round( value ) + '%';
},
},
},
tooltip: {
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
return [
rediscache.templates.tooltip_title({
title: new Date( w.globals.seriesX[ seriesIndex ][ dataPointIndex ] )
.toTimeString().slice( 0, 5 ),
}),
rediscache.templates.series_group({
color: rediscache.chart_defaults.colors[0],
name: w.globals.seriesNames[0],
value: Math.round( series[0][ dataPointIndex ] * 100 ) / 100 + '%',
}),
].join('');
},
},
} ),
calls: $.extend( true, {}, rediscache.chart_defaults, {
tooltip: {
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
return [
rediscache.templates.tooltip_title({
title: new Date( w.globals.seriesX[ seriesIndex ][ dataPointIndex ] )
.toTimeString().slice( 0, 5 ),
}),
rediscache.templates.series_group({
color: rediscache.chart_defaults.colors[0],
name: w.globals.seriesNames[0],
value: Math.round( series[0][ dataPointIndex ] ),
}),
rediscache.templates.series_pro({
color: rediscache.chart_defaults.colors[1],
name: rediscache.l10n.pro,
}),
].join('');
},
},
} ),
},
} );
var compute_metrics = function ( raw_metrics ) {
var metrics = {};
// parse raw metrics in blocks of minutes
for ( var entry in raw_metrics ) {
var values = {};
var timestamp = raw_metrics[ entry ].timestamp;
var minute = ( timestamp - timestamp % 60 ) * 1000;
for ( var key in raw_metrics[ entry ] ) {
if ( raw_metrics[ entry ].hasOwnProperty( key ) ) {
values[ key ] = Number( raw_metrics[ entry ][ key ] );
}
}
if ( ! metrics[ minute ] ) {
metrics[ minute ] = [];
}
metrics[ minute ].push( values );
}
// calculate median value for each block
for ( var entry in metrics ) {
if ( metrics[ entry ].length === 1 ) {
metrics[ entry ] = metrics[ entry ].shift();
continue;
}
var medians = {};
for ( var key in metrics[ entry ][0] ) {
medians[ key ] = compute_median(
metrics[ entry ].map(
function ( metric ) {
return metric[ key ];
}
)
);
}
metrics[ entry ] = medians;
}
var computed = [];
for ( var timestamp in metrics ) {
var entry = metrics[ timestamp ];
entry.date = Number( timestamp );
entry.time = entry.time * 1000;
computed.push( entry );
}
computed.sort(
function( a, b ) {
return a.date - b.date;
}
);
return computed.length < 2 ? [] : computed;
};
var compute_median = function ( numbers ) {
var median = 0;
var numsLen = numbers.length;
numbers.sort();
if ( numsLen % 2 === 0 ) {
median = ( numbers[ numsLen / 2 - 1 ] + numbers[ numsLen / 2 ] ) / 2;
} else {
median = numbers[ ( numsLen - 1 ) / 2 ];
}
return median;
};
var render_chart = function ( id ) {
if ( rediscache.chart ) {
rediscache.chart.updateOptions( rediscache.charts[ id ] );
return;
}
var chart = new ApexCharts(
document.querySelector( '#redis-stats-chart' ),
rediscache.charts[ id ]
);
chart.render();
root.rediscache.chart = chart;
};
var setup_charts = function () {
var metrics = {};
for ( var type in rediscache.charts ) {
if ( ! rediscache.charts.hasOwnProperty( type ) ) {
continue;
}
metrics[type] = rediscache.metrics.computed.map(
function ( entry ) {
return [ entry.date, entry[type] ];
}
);
rediscache.charts[type].series = [{
name: rediscache.l10n[type],
type: 'area',
data: metrics[type],
}];
}
if ( ! rediscache.disable_pro ) {
var pro_charts = {
time: function ( entry ) {
return [ entry[0], entry[1] * 0.5 ]
},
bytes: function ( entry ) {
return [ entry[0], entry[1] * 0.3 ]
},
calls: function ( entry ) {
return [ entry[0], Math.round( entry[1] / 50 ) + 5 ]
},
};
for ( var type in pro_charts ) {
if ( ! rediscache.charts[type] ) {
continue;
}
rediscache.charts[type].series.push({
name: rediscache.l10n.pro,
type: 'line',
data: metrics[type].map( pro_charts[type] ),
});
}
}
};
// executed on page load
$(function () {
var $tabs = $( '#rediscache .nav-tab-wrapper' );
var $panes = $( '#rediscache .content-column .tab-content' );
$tabs.find( 'a' ).on(
'click.redis-cache',
function ( event ) {
var toggle = $( this ).data( 'toggle' );
$( this ).blur();
show_tab( toggle );
if ( history.pushState ) {
history.pushState( null, null, '#' + toggle );
}
return false;
}
);
var firstRender = window.location.hash.indexOf('metrics') === -1;
var show_tab = function ( name ) {
$tabs.find( '.nav-tab-active' ).removeClass( 'nav-tab-active' );
$panes.find( '.tab-pane.active' ).removeClass( 'active' );
$( '#' + name + '-tab' ).addClass( 'nav-tab-active' );
$( '#' + name + '-pane' ).addClass( 'active' );
if (name === 'metrics' && firstRender) {
firstRender = false;
render_chart( 'time' );
}
};
var show_current_tab = function () {
var tabHash = window.location.hash.replace( '#', '' );
if ( tabHash !== '' && $( '#' + tabHash + '-tab' ) ) {
show_tab( tabHash );
}
};
show_current_tab();
$( window ).on( 'hashchange', show_current_tab );
if ( $( '#widget-redis-stats' ).length ) {
rediscache.metrics.computed = compute_metrics( root.rediscache_metrics );
setup_charts();
render_chart( 'time' );
}
$( '#widget-redis-stats ul a[data-chart]' ).on(
'click.redis-cache',
function ( event ) {
event.preventDefault();
$( '#widget-redis-stats .active' ).removeClass( 'active' );
$( this ).blur().addClass( 'active' );
render_chart(
$( event.target ).data( 'chart' )
);
}
);
$( '.notice.is-dismissible[data-dismissible]' ).on(
'click.roc-dismiss-notice',
'.notice-dismiss',
function ( event ) {
event.preventDefault();
var $parent = $( this ).parent();
$.post( ajaxurl, {
notice: $parent.data( 'dismissible' ),
action: 'roc_dismiss_notice',
_ajax_nonce: $parent.data( 'nonce' ),
} );
}
);
if ( $( '#redis-cache-copy-button' ).length ) {
if ( typeof ClipboardJS === 'undefined' ) {
$( '#redis-cache-copy-button' ).remove();
} else {
var successTimeout;
var clipboard = new ClipboardJS( '#redis-cache-copy-button .copy-button' );
clipboard.on( 'success', function( e ) {
var triggerElement = $( e.trigger ),
successElement = $( '.success', triggerElement.closest( 'div' ) );
e.clearSelection();
triggerElement.trigger( 'focus' );
clearTimeout( successTimeout );
successElement.removeClass( 'hidden' );
successTimeout = setTimeout( function() {
successElement.addClass( 'hidden' );
if ( clipboard.clipboardAction.fakeElem && clipboard.clipboardAction.removeFake ) {
clipboard.clipboardAction.removeFake();
}
}, 3000 );
} );
}
}
});
} ( window[ rediscache.jQuery ], window ) );