mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-20 11:48:31 -06:00
Add optional data point markers and mouse-over tooltips to display values on graphs. Fixes #3514
Ensure queries are no longer executed when dashboards are closed. Fixes #3576
This commit is contained in:
parent
0e59be237b
commit
a74b9c96c1
@ -11,7 +11,10 @@ Features
|
||||
********
|
||||
|
||||
| `Feature #2927 <https://redmine.postgresql.org/issues/2927>`_ - Move all CSS into SCSS files for consistency and ease of colour maintenance etc.
|
||||
| `Feature #3514 <https://redmine.postgresql.org/issues/3514>`_ - Add optional data point markers and mouse-over tooltips to display values on graphs.
|
||||
|
||||
Bug fixes
|
||||
*********
|
||||
|
||||
| `Bug #3576 <https://redmine.postgresql.org/issues/3576>`_ - Ensure queries are no longer executed when dashboards are closed.
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
"axios-mock-adapter": "^1.14.1",
|
||||
"babel-core": "~6.24.0",
|
||||
"babel-loader": "~7.1.2",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-preset-airbnb": "^2.4.0",
|
||||
"babel-preset-es2015": "~6.24.0",
|
||||
"babel-preset-react": "~6.23.0",
|
||||
@ -66,7 +67,7 @@
|
||||
"dropzone": "^5.1.1",
|
||||
"eonasdan-bootstrap-datetimepicker": "^4.17.47",
|
||||
"exports-loader": "~0.6.4",
|
||||
"flotr2": "^0.1.0",
|
||||
"flotr2": "git+https://github.com/EnterpriseDB/Flotr2.git",
|
||||
"font-awesome": "^4.7.0",
|
||||
"hard-source-webpack-plugin": "^0.4.9",
|
||||
"immutability-helper": "^2.2.0",
|
||||
|
@ -165,7 +165,8 @@ define(
|
||||
|
||||
if (eventName == 'panelClosed') {
|
||||
pgBrowser.save_current_layout(pgBrowser);
|
||||
pgAdmin.Dashboard.toggleVisibility(false);
|
||||
/* Pass the closed flag also */
|
||||
pgAdmin.Dashboard.toggleVisibility(false, true);
|
||||
} else if (eventName == 'panelVisibilityChanged') {
|
||||
if (pgBrowser.tree) {
|
||||
pgBrowser.save_current_layout(pgBrowser);
|
||||
@ -174,8 +175,10 @@ define(
|
||||
pgAdmin.Dashboard.toggleVisibility(pgBrowser.panels.dashboard.panel.isVisible());
|
||||
}
|
||||
// Explicitly trigger tree selected event when we add the tab.
|
||||
pgBrowser.Events.trigger('pgadmin-browser:tree:selected', selectedNode,
|
||||
pgBrowser.tree.itemData(selectedNode), pgBrowser.Node);
|
||||
if(selectedNode.length) {
|
||||
pgBrowser.Events.trigger('pgadmin-browser:tree:selected', selectedNode,
|
||||
pgBrowser.tree.itemData(selectedNode), pgBrowser.Node);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -81,7 +81,7 @@ class DashboardModule(PgAdminModule):
|
||||
help_str=gettext('The number of seconds between graph samples.')
|
||||
)
|
||||
|
||||
self.session_stats_refresh = self.dashboard_preference.register(
|
||||
self.tps_stats_refresh = self.dashboard_preference.register(
|
||||
'dashboards', 'tps_stats_refresh',
|
||||
gettext("Transaction throughput refresh rate"), 'integer',
|
||||
1, min_val=1, max_val=999999,
|
||||
@ -89,7 +89,7 @@ class DashboardModule(PgAdminModule):
|
||||
help_str=gettext('The number of seconds between graph samples.')
|
||||
)
|
||||
|
||||
self.session_stats_refresh = self.dashboard_preference.register(
|
||||
self.ti_stats_refresh = self.dashboard_preference.register(
|
||||
'dashboards', 'ti_stats_refresh',
|
||||
gettext("Tuples in refresh rate"), 'integer',
|
||||
1, min_val=1, max_val=999999,
|
||||
@ -97,7 +97,7 @@ class DashboardModule(PgAdminModule):
|
||||
help_str=gettext('The number of seconds between graph samples.')
|
||||
)
|
||||
|
||||
self.session_stats_refresh = self.dashboard_preference.register(
|
||||
self.to_stats_refresh = self.dashboard_preference.register(
|
||||
'dashboards', 'to_stats_refresh',
|
||||
gettext("Tuples out refresh rate"), 'integer',
|
||||
1, min_val=1, max_val=999999,
|
||||
@ -105,7 +105,7 @@ class DashboardModule(PgAdminModule):
|
||||
help_str=gettext('The number of seconds between graph samples.')
|
||||
)
|
||||
|
||||
self.session_stats_refresh = self.dashboard_preference.register(
|
||||
self.bio_stats_refresh = self.dashboard_preference.register(
|
||||
'dashboards', 'bio_stats_refresh',
|
||||
gettext("Block I/O statistics refresh rate"), 'integer',
|
||||
1, min_val=1, max_val=999999,
|
||||
@ -129,6 +129,23 @@ class DashboardModule(PgAdminModule):
|
||||
'will be displayed on dashboards.')
|
||||
)
|
||||
|
||||
self.graph_data_points = self.dashboard_preference.register(
|
||||
'display', 'graph_data_points',
|
||||
gettext("Show graph data points?"), 'boolean', False,
|
||||
category_label=gettext('Display'),
|
||||
help_str=gettext('If set to True, data points will be '
|
||||
'visible on graph lines.')
|
||||
)
|
||||
|
||||
self.graph_mouse_track = self.dashboard_preference.register(
|
||||
'display', 'graph_mouse_track',
|
||||
gettext("Show mouse hover tooltip?"), 'boolean', True,
|
||||
category_label=gettext('Display'),
|
||||
help_str=gettext('If set to True, tooltip will appear on mouse '
|
||||
'hover on the graph lines giving the data point '
|
||||
'details')
|
||||
)
|
||||
|
||||
def get_exposed_url_endpoints(self):
|
||||
"""
|
||||
Returns:
|
||||
|
99
web/pgadmin/dashboard/static/js/charting.js
Normal file
99
web/pgadmin/dashboard/static/js/charting.js
Normal file
@ -0,0 +1,99 @@
|
||||
import Flotr from 'flotr2';
|
||||
|
||||
export class Chart {
|
||||
constructor(container, options) {
|
||||
this.chartApi = Flotr;
|
||||
/* Html Node where the graph goes */
|
||||
this._container = container;
|
||||
/* Graph library options */
|
||||
this._options = {};
|
||||
this._defaultOptions = {
|
||||
legend: {
|
||||
position: 'nw',
|
||||
backgroundColor: '#D2E8FF',
|
||||
},
|
||||
lines: {
|
||||
show: true,
|
||||
lineWidth: 2,
|
||||
},
|
||||
shadowSize: 0,
|
||||
resolution : 3,
|
||||
};
|
||||
|
||||
this._dataset = null;
|
||||
this._tooltipFormatter = null;
|
||||
/* Just to store other data related to charts. Used nowhere here in the module */
|
||||
this._otherData = {};
|
||||
this.setOptions(options);
|
||||
}
|
||||
|
||||
getContainer() {
|
||||
return this._container;
|
||||
}
|
||||
|
||||
getContainerDimensions() {
|
||||
return {
|
||||
height: this._container.clientHeight,
|
||||
width: this._container.clientWidth,
|
||||
};
|
||||
}
|
||||
|
||||
getOptions() {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
/* This should be changed if library changed */
|
||||
setOptions(options, mergeOptions=true) {
|
||||
/* If mergeOptions then merge the options, else replace existing options */
|
||||
if(mergeOptions) {
|
||||
this._options = {...this._defaultOptions, ...this._options, ...options};
|
||||
} else {
|
||||
this._options = {...this._defaultOptions, ...options};
|
||||
}
|
||||
}
|
||||
|
||||
removeOptions(optionKey) {
|
||||
if(this._options[optionKey]) {
|
||||
delete this._options[optionKey];
|
||||
}
|
||||
}
|
||||
|
||||
getOtherData(key) {
|
||||
return this._otherData[key];
|
||||
}
|
||||
|
||||
setOtherData(key, value) {
|
||||
this._otherData[key] = value;
|
||||
}
|
||||
|
||||
isVisible() {
|
||||
let dim = this.getContainerDimensions();
|
||||
return (dim.height > 0 && dim.width > 0);
|
||||
}
|
||||
|
||||
isInPage() {
|
||||
return (this._container === document.body) ? false : document.body.contains(this._container);
|
||||
}
|
||||
|
||||
setTooltipFormatter(tooltipFormatter) {
|
||||
let opt = this.getOptions();
|
||||
|
||||
this._tooltipFormatter = tooltipFormatter;
|
||||
|
||||
if(this._tooltipFormatter) {
|
||||
this.setOptions({
|
||||
mouse: {
|
||||
...opt.mouse,
|
||||
trackFormatter: this._tooltipFormatter,
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
draw(dataset) {
|
||||
this._dataset = dataset;
|
||||
if(this._container) {
|
||||
Flotr.draw(this._container, this._dataset, this._options);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
define('pgadmin.dashboard', [
|
||||
'sources/url_for', 'sources/gettext', 'require', 'jquery', 'underscore',
|
||||
'sources/pgadmin', 'backbone', 'backgrid', 'flotr2',
|
||||
'sources/pgadmin', 'backbone', 'backgrid', './charting',
|
||||
'pgadmin.alertifyjs', 'pgadmin.backform',
|
||||
'sources/nodes/dashboard', 'backgrid.filter',
|
||||
'pgadmin.browser', 'bootstrap', 'wcdocker',
|
||||
], function(
|
||||
url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid, Flotr,
|
||||
url_for, gettext, r, $, _, pgAdmin, Backbone, Backgrid, charting,
|
||||
Alertify, Backform, NodesDashboard
|
||||
) {
|
||||
|
||||
@ -210,10 +210,8 @@ define('pgadmin.dashboard', [
|
||||
// Load the default welcome dashboard
|
||||
var url = url_for('dashboard.index');
|
||||
|
||||
/* Store the interval ids of the graph interval functions so that we can clear
|
||||
* them when graphs are disabled
|
||||
*/
|
||||
this.intervalIds = {};
|
||||
/* Store the chart objects and there interval ids in this store */
|
||||
this.chartStore = {};
|
||||
|
||||
var dashboardPanel = pgBrowser.panels['dashboard'].panel;
|
||||
if (dashboardPanel) {
|
||||
@ -266,7 +264,7 @@ define('pgadmin.dashboard', [
|
||||
!_.isUndefined(itemData.connected) &&
|
||||
itemData.connected !== true
|
||||
) {
|
||||
self.clearIntervalId();
|
||||
self.clearChartFromStore();
|
||||
}
|
||||
} else if (itemData && itemData._type) {
|
||||
var treeHierarchy = node.getTreeNodeHierarchy(item),
|
||||
@ -331,8 +329,8 @@ define('pgadmin.dashboard', [
|
||||
) {
|
||||
$(div).empty();
|
||||
|
||||
/* Clear all the interval functions of previous dashboards */
|
||||
self.clearIntervalId();
|
||||
/* Clear all the charts previous dashboards */
|
||||
self.clearChartFromStore();
|
||||
|
||||
$.ajax({
|
||||
url: url,
|
||||
@ -356,8 +354,8 @@ define('pgadmin.dashboard', [
|
||||
!_.isUndefined(itemData.connected) &&
|
||||
itemData.connected !== true
|
||||
) {
|
||||
/* Clear all the interval functions of previous dashboards */
|
||||
self.clearIntervalId();
|
||||
/* Clear all the charts previous dashboards */
|
||||
self.clearChartFromStore();
|
||||
}
|
||||
$(div).html(
|
||||
'<div class="alert alert-info pg-panel-message" role="alert">' + gettext('Please connect to the selected server to view the dashboard.') + '</div>'
|
||||
@ -371,7 +369,7 @@ define('pgadmin.dashboard', [
|
||||
}
|
||||
},
|
||||
|
||||
renderChartLoop: function(container, sid, did, url, options, counter, refresh) {
|
||||
renderChartLoop: function(chartObj, sid, did, url, counter, refresh) {
|
||||
var data = [],
|
||||
dataset = [];
|
||||
|
||||
@ -386,24 +384,22 @@ define('pgadmin.dashboard', [
|
||||
dataType: 'html',
|
||||
})
|
||||
.done(function(resp) {
|
||||
$(container).removeClass('graph-error');
|
||||
$(chartObj.getContainer()).removeClass('graph-error');
|
||||
data = JSON.parse(resp);
|
||||
if (!dashboardVisible)
|
||||
return;
|
||||
|
||||
var y = 0,
|
||||
x;
|
||||
if (dataset.length == 0) {
|
||||
if (counter == true) {
|
||||
// Have we stashed initial values?
|
||||
if (_.isUndefined($(container).data('counter_previous_vals'))) {
|
||||
$(container).data('counter_previous_vals', data[0]);
|
||||
if (_.isUndefined(chartObj.getOtherData('counter_previous_vals'))) {
|
||||
chartObj.setOtherData('counter_previous_vals', data[0]);
|
||||
} else {
|
||||
// Create the initial data structure
|
||||
for (x in data[0]) {
|
||||
dataset.push({
|
||||
'data': [
|
||||
[0, data[0][x] - $(container).data('counter_previous_vals')[x]],
|
||||
[0, data[0][x] - chartObj.getOtherData('counter_previous_vals')[x]],
|
||||
],
|
||||
'label': x,
|
||||
});
|
||||
@ -429,10 +425,10 @@ define('pgadmin.dashboard', [
|
||||
} else {
|
||||
// Store the current value, minus the previous one we stashed.
|
||||
// It's possible the tab has been reloaded, in which case out previous values are gone
|
||||
if (_.isUndefined($(container).data('counter_previous_vals')))
|
||||
if (_.isUndefined(chartObj.getOtherData('counter_previous_vals')))
|
||||
return;
|
||||
|
||||
dataset[y]['data'].unshift([0, data[0][x] - $(container).data('counter_previous_vals')[x]]);
|
||||
dataset[y]['data'].unshift([0, data[0][x] - chartObj.getOtherData('counter_previous_vals')[x]]);
|
||||
}
|
||||
|
||||
// Reset the time index to get a proper scrolling display
|
||||
@ -442,7 +438,7 @@ define('pgadmin.dashboard', [
|
||||
|
||||
y++;
|
||||
}
|
||||
$(container).data('counter_previous_vals', data[0]);
|
||||
chartObj.setOtherData('counter_previous_vals', data[0]);
|
||||
}
|
||||
|
||||
// Remove uneeded elements
|
||||
@ -453,12 +449,9 @@ define('pgadmin.dashboard', [
|
||||
}
|
||||
}
|
||||
|
||||
// Draw Graph, if the container still exists and has a size
|
||||
var dashboardPanel = pgBrowser.panels['dashboard'].panel;
|
||||
var div = dashboardPanel.layout().scene().find('.pg-panel-content');
|
||||
if ($(div).find(container).length) { // Exists?
|
||||
if (container.clientHeight > 0 && container.clientWidth > 0) { // Not hidden?
|
||||
Flotr.draw(container, dataset, options);
|
||||
if (chartObj.isInPage()) {
|
||||
if (chartObj.isVisible()) {
|
||||
chartObj.draw(dataset);
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
@ -487,8 +480,8 @@ define('pgadmin.dashboard', [
|
||||
}
|
||||
}
|
||||
|
||||
$(container).addClass('graph-error');
|
||||
$(container).html(
|
||||
$(chartObj.getContainer()).addClass('graph-error');
|
||||
$(chartObj.getContainer()).html(
|
||||
'<div class="alert alert-' + cls + ' pg-panel-message" role="alert">' + msg + '</div>'
|
||||
);
|
||||
});
|
||||
@ -510,15 +503,41 @@ define('pgadmin.dashboard', [
|
||||
// { data: [[0, y0], [1, y1]...], label: 'Label 3', [options] }
|
||||
// ]
|
||||
|
||||
let self = this;
|
||||
if(self.intervalIds[chartName]
|
||||
let self = this,
|
||||
tooltipFormatter = function(refresh, currVal) {
|
||||
return(`Seconds ago: ${parseInt(currVal.x * refresh)}</br>
|
||||
Value: ${currVal.y}`);
|
||||
};
|
||||
|
||||
if(self.chartStore[chartName]
|
||||
&& self.old_preferences[prefName] != self.preferences[prefName]) {
|
||||
self.clearIntervalId(chartName);
|
||||
self.clearChartFromStore(chartName);
|
||||
}
|
||||
if(!self.intervalIds[chartName]) {
|
||||
self.intervalIds[chartName] = self.renderChartLoop(
|
||||
container, self.sid, self.did, url,
|
||||
options, counter, self.preferences[prefName]
|
||||
|
||||
if(self.chartStore[chartName]) {
|
||||
let chartObj = self.chartStore[chartName].chartObj;
|
||||
chartObj.setOptions(options, false);
|
||||
chartObj.setTooltipFormatter(
|
||||
tooltipFormatter.bind(null, self.preferences[prefName])
|
||||
);
|
||||
}
|
||||
|
||||
if(!self.chartStore[chartName]) {
|
||||
|
||||
let chartObj = new charting.Chart(container, options);
|
||||
|
||||
chartObj.setTooltipFormatter(
|
||||
tooltipFormatter.bind(null, self.preferences[prefName])
|
||||
);
|
||||
|
||||
self.chartStore[chartName] = {
|
||||
'chartObj' : chartObj,
|
||||
'intervalId' : undefined,
|
||||
};
|
||||
|
||||
self.chartStore[chartName]['intervalId'] = self.renderChartLoop(
|
||||
self.chartStore[chartName]['chartObj'], self.sid, self.did, url,
|
||||
counter, self.preferences[prefName]
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -666,17 +685,17 @@ define('pgadmin.dashboard', [
|
||||
});
|
||||
},
|
||||
|
||||
clearIntervalId: function(intervalId) {
|
||||
clearChartFromStore: function(chartName) {
|
||||
var self = this;
|
||||
if(!intervalId){
|
||||
_.each(self.intervalIds, function(id, key) {
|
||||
clearInterval(id);
|
||||
delete self.intervalIds[key];
|
||||
if(!chartName){
|
||||
_.each(self.chartStore, function(chart, key) {
|
||||
clearInterval(chart.intervalId);
|
||||
delete self.chartStore[key];
|
||||
});
|
||||
}
|
||||
else {
|
||||
clearInterval(self.intervalIds[intervalId]);
|
||||
delete self.intervalIds[intervalId];
|
||||
clearInterval(self.chartStore[chartName].intervalId);
|
||||
delete self.chartStore[chartName];
|
||||
}
|
||||
},
|
||||
|
||||
@ -737,20 +756,41 @@ define('pgadmin.dashboard', [
|
||||
yaxis: {
|
||||
autoscale: 1,
|
||||
},
|
||||
legend: {
|
||||
position: 'nw',
|
||||
backgroundColor: '#D2E8FF',
|
||||
},
|
||||
shadowSize: 0,
|
||||
resolution : 5,
|
||||
};
|
||||
|
||||
if(self.preferences.graph_data_points) {
|
||||
/* Merge data points related options */
|
||||
options_line = {
|
||||
...options_line,
|
||||
...{
|
||||
points: {
|
||||
show:true,
|
||||
radius: 1,
|
||||
hitRadius: 3,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if(self.preferences.graph_mouse_track) {
|
||||
/* Merge mouse track related options */
|
||||
options_line = {
|
||||
...options_line,
|
||||
...{
|
||||
mouse: {
|
||||
track:true,
|
||||
position: 'sw',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
if(self.preferences.show_graphs && $('#dashboard-graphs').hasClass('dashboard-hidden')) {
|
||||
$('#dashboard-graphs').removeClass('dashboard-hidden');
|
||||
}
|
||||
else if(!self.preferences.show_graphs) {
|
||||
$('#dashboard-graphs').addClass('dashboard-hidden');
|
||||
self.clearIntervalId();
|
||||
self.clearChartFromStore();
|
||||
}
|
||||
|
||||
if (self.preferences.show_activity && $('#dashboard-activity').hasClass('dashboard-hidden')) {
|
||||
@ -1344,8 +1384,11 @@ define('pgadmin.dashboard', [
|
||||
});
|
||||
}
|
||||
},
|
||||
toggleVisibility: function(flag) {
|
||||
dashboardVisible = flag;
|
||||
toggleVisibility: function(visible, closed=false) {
|
||||
dashboardVisible = visible;
|
||||
if(closed) {
|
||||
this.clearChartFromStore();
|
||||
}
|
||||
},
|
||||
can_take_action: function(m) {
|
||||
// We will validate if user is allowed to cancel the active query
|
||||
|
91
web/regression/javascript/dashboard/charting_spec.js
Normal file
91
web/regression/javascript/dashboard/charting_spec.js
Normal file
@ -0,0 +1,91 @@
|
||||
import $ from 'jquery';
|
||||
import {Chart} from 'top/dashboard/static/js/charting';
|
||||
|
||||
describe('In charting related testcases', ()=> {
|
||||
let chartObj = undefined,
|
||||
chartDiv = undefined,
|
||||
options = {};
|
||||
|
||||
beforeEach(()=> {
|
||||
$('body').append(
|
||||
'<div id="charting-test-container"></div>'
|
||||
);
|
||||
chartDiv = $('#charting-test-container')[0];
|
||||
chartObj = new Chart(chartDiv, options);
|
||||
});
|
||||
|
||||
it('Chart api should be defined', ()=>{
|
||||
expect(chartObj.chartApi).toBeDefined();
|
||||
});
|
||||
|
||||
it('Return the correct container', ()=>{
|
||||
expect(chartObj.getContainer()).toBe(chartDiv);
|
||||
});
|
||||
|
||||
it('Returns the container dimensions', ()=>{
|
||||
let dim = chartObj.getContainerDimensions();
|
||||
expect(dim.height).toBeDefined();
|
||||
expect(dim.width).toBeDefined();
|
||||
});
|
||||
|
||||
it('Check if options are set', ()=>{
|
||||
chartObj.setOptions({
|
||||
mouse: {
|
||||
track:true,
|
||||
},
|
||||
});
|
||||
|
||||
let opt = chartObj.getOptions();
|
||||
|
||||
expect(opt.mouse).toBeDefined();
|
||||
});
|
||||
|
||||
it('Check if options are set with mergeOptions false', ()=>{
|
||||
let overOpt = {
|
||||
mouse: {
|
||||
track:true,
|
||||
},
|
||||
};
|
||||
chartObj.setOptions(overOpt, false);
|
||||
|
||||
let newOptShouldBe = {...chartObj._defaultOptions, ...overOpt};
|
||||
|
||||
let opt = chartObj.getOptions();
|
||||
expect(JSON.stringify(opt)).toEqual(JSON.stringify(newOptShouldBe));
|
||||
});
|
||||
|
||||
it('Check if other data is set', ()=>{
|
||||
chartObj.setOtherData('some_val', 1);
|
||||
expect(chartObj._otherData['some_val']).toEqual(1);
|
||||
});
|
||||
|
||||
it('Check if other data is get', ()=>{
|
||||
chartObj.setOtherData('some_val', 1);
|
||||
expect(chartObj.getOtherData('some_val')).toEqual(1);
|
||||
});
|
||||
|
||||
it('Check if isVisible returns correct', ()=>{
|
||||
let dimSpy = spyOn(chartObj, 'getContainerDimensions');
|
||||
|
||||
dimSpy.and.returnValue({
|
||||
height: 1, width: 1,
|
||||
});
|
||||
expect(chartObj.isVisible()).toBe(true);
|
||||
dimSpy.and.stub();
|
||||
|
||||
dimSpy.and.returnValue({
|
||||
height: 0, width: 0,
|
||||
});
|
||||
expect(chartObj.isVisible()).toBe(false);
|
||||
});
|
||||
|
||||
it('Check if isInPage returns correct', ()=>{
|
||||
expect(chartObj.isInPage()).toBe(true);
|
||||
$('body').find('#charting-test-container').remove();
|
||||
expect(chartObj.isInPage()).toBe(false);
|
||||
});
|
||||
|
||||
afterEach(()=>{
|
||||
$('body').find('#charting-test-container').remove();
|
||||
});
|
||||
});
|
@ -168,6 +168,7 @@ module.exports = {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['es2015', 'react'],
|
||||
plugins: ['transform-object-rest-spread'],
|
||||
},
|
||||
},
|
||||
}, {
|
||||
|
@ -58,6 +58,7 @@ module.exports = {
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx'],
|
||||
alias: {
|
||||
'top': path.join(__dirname, './pgadmin'),
|
||||
'jquery': path.join(__dirname, './node_modules/jquery/dist/jquery'),
|
||||
'alertify': path.join(__dirname, './node_modules/alertifyjs/build/alertify'),
|
||||
'jquery.event.drag': path.join(__dirname, './node_modules/slickgrid/lib/jquery.event.drag-2.3.0'),
|
||||
@ -75,6 +76,8 @@ module.exports = {
|
||||
'slickgrid': nodeModulesDir + '/slickgrid/',
|
||||
'slickgrid.plugins': nodeModulesDir + '/slickgrid/plugins/',
|
||||
'slickgrid.grid': nodeModulesDir + '/slickgrid/slick.grid',
|
||||
'bean': path.join(__dirname, './node_modules/flotr2/lib/bean'),
|
||||
'flotr2': path.join(__dirname, './node_modules/flotr2/flotr2.amd'),
|
||||
'browser': path.resolve(__dirname, 'pgadmin/browser/static/js'),
|
||||
'pgadmin': sourcesDir + '/js/pgadmin',
|
||||
'pgadmin.sqlfoldcode': sourcesDir + '/js/codemirror/addon/fold/pgadmin-sqlfoldcode',
|
||||
|
@ -907,7 +907,7 @@ babel-plugin-transform-jscript@^6.22.0:
|
||||
dependencies:
|
||||
babel-runtime "^6.22.0"
|
||||
|
||||
babel-plugin-transform-object-rest-spread@^6.23.0:
|
||||
babel-plugin-transform-object-rest-spread@^6.23.0, babel-plugin-transform-object-rest-spread@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
|
||||
dependencies:
|
||||
@ -3766,9 +3766,9 @@ flatten@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
|
||||
flotr2@^0.1.0:
|
||||
"flotr2@git+https://github.com/EnterpriseDB/Flotr2.git":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/flotr2/-/flotr2-0.1.0.tgz#8d31b0d1b3dc46f5e399edeb7a179e075b36e036"
|
||||
resolved "git+https://github.com/EnterpriseDB/Flotr2.git#dc514e32d93b2c593ab379a52de1664ee9da63e1"
|
||||
|
||||
flush-write-stream@^1.0.2:
|
||||
version "1.0.3"
|
||||
|
Loading…
Reference in New Issue
Block a user