Support double-click on Query Tool result grid column resize handles to auto-size to the content. Fixes #4034

This commit is contained in:
Aditya Toshniwal 2019-02-26 13:44:16 +00:00 committed by Dave Page
parent 1770c94b07
commit 9c5b9364b6
5 changed files with 170 additions and 1 deletions

View File

@ -16,6 +16,7 @@ Features
| `Feature #3559 <https://redmine.postgresql.org/issues/3559>`_ - Automatically expand child nodes as well as the selected node on the treeview if there is only one.
| `Feature #3886 <https://redmine.postgresql.org/issues/3886>`_ - Include multiple versions of the PG utilties in containers.
| `Feature #3991 <https://redmine.postgresql.org/issues/3991>`_ - Update Alpine Linux version in the docker container.
| `Feature #4034 <https://redmine.postgresql.org/issues/4034>`_ - Support double-click on Query Tool result grid column resize handles to auto-size to the content.
Bug fixes
*********

View File

@ -62,6 +62,11 @@ define([
return;
}
/* Skip if clicked on resize handler */
if($(event.target).hasClass('slick-resizable-handle')) {
return;
}
bypassDefaultActiveCellRangeChange = true;
var clickedColumn = args.column.pos + 1;

View File

@ -0,0 +1,160 @@
/*
* https://github.com/naresh-n/slickgrid-column-data-autosize
*/
(function($) {
$.extend(true, window, {
'Slick': {
'AutoColumnSize': AutoColumnSize,
},
});
function AutoColumnSize(maxWidth) {
var grid, $container, context,
keyCodes = {
'A': 65,
};
function init(_grid) {
grid = _grid;
maxWidth = maxWidth || 200;
$container = $(grid.getContainerNode());
$container.on('dblclick.autosize', '.slick-resizable-handle', reSizeColumn);
$container.keydown(handleControlKeys);
context = document.createElement('canvas').getContext('2d');
}
function destroy() {
$container.off();
}
function handleControlKeys(event) {
if (event.ctrlKey && event.shiftKey && event.keyCode === keyCodes.A) {
resizeAllColumns();
}
}
function resizeAllColumns() {
var elHeaders = $container.find('.slick-header-column');
var allColumns = grid.getColumns();
elHeaders.each(function(index, el) {
var columnDef = $(el).data('column');
var headerWidth = getElementWidth(el);
var colIndex = grid.getColumnIndex(columnDef.id);
var column = allColumns[colIndex];
var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
autoSizeWidth = Math.min(maxWidth, autoSizeWidth);
column.width = autoSizeWidth;
});
grid.setColumns(allColumns);
grid.onColumnsResized.notify();
}
function reSizeColumn(e) {
var headerEl = $(e.currentTarget).closest('.slick-header-column');
var columnDef = headerEl.data('column');
if (!columnDef || !columnDef.resizable) {
return;
}
e.preventDefault();
e.stopPropagation();
var headerWidth = getElementWidth(headerEl[0]);
var colIndex = grid.getColumnIndex(columnDef.id);
var allColumns = grid.getColumns();
var column = allColumns[colIndex];
var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
if (autoSizeWidth !== column.width) {
column.width = autoSizeWidth;
grid.setColumns(allColumns);
grid.onColumnsResized.notify();
}
}
function getMaxColumnTextWidth(columnDef, colIndex) {
var texts = [];
var rowEl = createRow();
var data = grid.getData();
if (window.Slick.Data && data instanceof window.Slick.Data.DataView) {
data = data.getItems();
}
for (var i = 0; i < data.length; i++) {
texts.push(data[i][columnDef.field]);
}
var template = getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl);
var width = getTemplateWidth(rowEl, template);
deleteRow(rowEl);
return width;
}
function getTemplateWidth(rowEl, template) {
var cell = $(rowEl.find('.slick-cell'));
cell.append(template);
$(cell).find('*').css('position', 'relative');
return cell.outerWidth() + 1;
}
function getMaxTextTemplate(texts, columnDef, colIndex, data, rowEl) {
var max = 0,
maxTemplate = null;
var formatFun = columnDef.formatter;
$(texts).each(function(index, text) {
var template;
if (formatFun) {
template = $('<span>' + formatFun(index, colIndex, text, columnDef, data[index]) + '</span>');
text = template.text() || text;
}
var length = text ? getElementWidthUsingCanvas(rowEl, text) : 0;
if (length > max) {
max = length;
maxTemplate = template || text;
}
});
return maxTemplate;
}
function createRow() {
var rowEl = $('<div class="slick-row"><div class="slick-cell"></div></div>');
rowEl.find('.slick-cell').css({
'visibility': 'hidden',
'text-overflow': 'initial',
'white-space': 'nowrap',
});
var gridCanvas = $container.find('.grid-canvas');
$(gridCanvas).append(rowEl);
return rowEl;
}
function deleteRow(rowEl) {
$(rowEl).remove();
}
function getElementWidth(element) {
var width, clone = element.cloneNode(true);
clone.style.cssText = 'position: absolute; visibility: hidden;right: auto;text-overflow: initial;white-space: nowrap;';
element.parentNode.insertBefore(clone, element);
width = clone.offsetWidth;
clone.parentNode.removeChild(clone);
return width;
}
function getElementWidthUsingCanvas(element, text) {
context.font = element.css('font-size') + ' ' + element.css('font-family');
var metrics = context.measureText(text);
return metrics.width;
}
return {
init: init,
destroy: destroy,
};
}
}(window.jQuery));

View File

@ -41,6 +41,7 @@ define('tools.querytool', [
'backgrid.sizeable.columns',
'slick.pgadmin.formatters',
'slick.pgadmin.editors',
'slick.pgadmin.plugins/slick.autocolumnsize',
'pgadmin.browser',
'pgadmin.tools.user_management',
], function(
@ -863,6 +864,7 @@ define('tools.querytool', [
grid.registerPlugin(new ActiveCellCapture());
grid.setSelectionModel(new XCellSelectionModel());
grid.registerPlugin(gridSelector);
grid.registerPlugin(new Slick.AutoColumnSize());
var headerButtonsPlugin = new Slick.Plugins.HeaderButtons();
headerButtonsPlugin.onCommand.subscribe(function (e, args) {
let command = args.command;
@ -926,7 +928,7 @@ define('tools.querytool', [
var column_size = self.handler['col_size'];
column_size[self.handler['table_name']][col['id']] = col['width'];
});
});
}.bind(grid));
gridSelector.onBeforeGridSelectAll.subscribe(function(e, args) {
if (self.handler.has_more_rows) {

View File

@ -283,6 +283,7 @@ var webpackShimConfig = {
'pgadmin.user_management.current_user': '/user_management/current_user',
'slick.pgadmin.editors': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/editors'),
'slick.pgadmin.formatters': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/formatters'),
'slick.pgadmin.plugins': path.join(__dirname, './pgadmin/tools/../static/js/slickgrid/plugins'),
},
externals: [
'pgadmin.user_management.current_user',