1) Port schema diff to React. Fixes #6133

2) Remove SlickGrid.
This commit is contained in:
Nikhil Mohite
2022-09-07 19:20:03 +05:30
committed by Akshay Joshi
parent ad59380676
commit e1942d8c9e
78 changed files with 2794 additions and 7888 deletions

View File

@@ -1,25 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import 'slickgrid/lib/jquery.event.drag-2.3.0';
import 'slickgrid/slick.core';
import 'slickgrid/slick.grid';
import 'slickgrid/slick.dataview';
import 'slickgrid/slick.editors';
import 'slickgrid/slick.formatters';
import 'slickgrid/slick.groupitemmetadataprovider';
import 'slickgrid/plugins/slick.autotooltips';
import 'slickgrid/plugins/slick.cellrangedecorator';
import 'slickgrid/plugins/slick.cellrangeselector';
import 'slickgrid/plugins/slick.checkboxselectcolumn';
import 'slickgrid/plugins/slick.rowselectionmodel';
import 'sources/slickgrid/custom_header_buttons';
import 'sources/slickgrid/plugins/slick.autocolumnsize';
export default window.Slick;

View File

@@ -14,10 +14,6 @@
@import 'node_modules/codemirror/addon/dialog/dialog.css';
@import 'node_modules/codemirror/addon/scroll/simplescrollbars.css';
@import 'node_modules/slickgrid/slick.grid.css';
@import 'node_modules/slickgrid/slick-default-theme.css';
@import 'node_modules/slickgrid/css/smoothness/jquery-ui-1.11.3.custom.css';
@import '../vendor/backgrid/backgrid.css';
@import '../vendor/backgrid/backgrid-select-all.css';

View File

@@ -0,0 +1,115 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
import _ from 'lodash';
import React, { useState, useRef, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Box } from '@material-ui/core';
import CloseIcon from '@material-ui/icons/CloseRounded';
import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
import pgAdmin from 'sources/pgadmin';
import gettext from 'sources/gettext';
import { DefaultButton, PrimaryButton } from '../components/Buttons';
import { useModalStyles } from '../helpers/ModalProvider';
import { FormFooterMessage, InputText, MESSAGE_TYPE } from '../components/FormComponents';
import { setDebuggerTitle } from '../../../tools/debugger/static/js/debugger_utils';
import * as queryToolPanelTitleFunc from '../../../tools/sqleditor/static/js/sqleditor_title';
import * as queryToolPanelViewDataFunc from '../../../tools/sqleditor/static/js/show_view_data';
export default function RenamePanelContent({ closeModal, panel, title, preferences, setHeight, tabType, data }) {
const classes = useModalStyles();
const containerRef = useRef();
const firstEleRef = useRef();
const okBtnRef = useRef();
const [formData, setFormData] = useState({
title: title
});
const onTextChange = (e, id) => {
let val = e;
if (e && e.target) {
val = e.target.value;
}
setFormData((prev) => ({ ...prev, [id]: val }));
};
const onKeyDown = (e) => {
// If enter key is pressed then click on OK button
if (e.key === 'Enter') {
okBtnRef.current?.click();
}
};
useEffect(() => {
setTimeout(() => {
firstEleRef.current && firstEleRef.current.focus();
}, 350);
}, [firstEleRef.current]);
useEffect(() => {
setHeight?.(containerRef.current?.offsetHeight);
}, [containerRef.current, formData]);
return (
<Box display="flex" flexDirection="column" className={classes.container} ref={containerRef}>
<Box flexGrow="1" p={2}>
<Box marginTop='12px'>
<InputText inputRef={firstEleRef} type="text" value={formData['title']} controlProps={{ maxLength: null }}
onChange={(e) => onTextChange(e, 'title')} onKeyDown={(e) => onKeyDown(e)} />
</Box>
<FormFooterMessage type={MESSAGE_TYPE.ERROR} message={formData['title'].length == 0 ? gettext('Title cannot be empty') : ''} closable={false} style={{
position: 'unset', padding: '12px 0px 0px'
}} />
</Box>
<Box className={classes.footer}>
<DefaultButton data-test="close" startIcon={<CloseIcon />} onClick={() => {
closeModal();
}} >{gettext('Cancel')}</DefaultButton>
<PrimaryButton ref={okBtnRef} data-test="save" className={classes.margin} disabled={formData['title'].length == 0 ? true : false} startIcon={<CheckRoundedIcon />} onClick={() => {
if (tabType == 'debugger') {
setDebuggerTitle(panel, preferences, data.function_name, data.schema_name, data.database_name, _.escape(formData['title']), pgAdmin.Browser);
} else if (tabType == 'querytool') {
let selected_item = pgAdmin.Browser.tree.selected();
let panel_titles = '';
if (data.is_query_tool) {
panel_titles = queryToolPanelTitleFunc.getPanelTitle(pgAdmin.Browser, selected_item, formData['title']);
} else {
panel_titles = queryToolPanelViewDataFunc.generateViewDataTitle(pgAdmin.Browser, selected_item, formData['title']);
}
// Set title to the selected tab.
if (data.is_dirty_editor) {
panel_titles = panel_titles + ' *';
}
queryToolPanelTitleFunc.setQueryToolDockerTitle(panel, data.is_query_tool, panel_titles, data.is_file);
} else {
panel.title(_.escape(formData.title));
}
closeModal();
}} >{gettext('OK')}</PrimaryButton>
</Box>
</Box>
);
}
RenamePanelContent.propTypes = {
closeModal: PropTypes.func,
data: PropTypes.object,
setHeight: PropTypes.func,
panel: PropTypes.object,
title: PropTypes.string,
preferences: PropTypes.object,
tabType: PropTypes.string,
'panel.title': PropTypes.string,
};

View File

@@ -22,6 +22,7 @@ import ChangePasswordContent from './ChangePasswordContent';
import NamedRestoreContent from './NamedRestoreContent';
import ChangeOwnershipContent from './ChangeOwnershipContent';
import UrlDialogContent from './UrlDialogContent';
import RenamePanelContent from './RenamePanelContent';
function mountDialog(title, getDialogContent, docker=undefined, width, height) {
// Register dialog panel
@@ -353,3 +354,29 @@ export function showUrlDialog() {
{ isFullScreen: false, isResizeable: true, showFullScreen: true, isFullWidth: true,
dialogWidth: width || pgAdmin.Browser.stdW.md, dialogHeight: height || pgAdmin.Browser.stdH.md});
}
export function showRenamePanel() {
let title = arguments[0],
preferences = arguments[1],
panel = arguments[2],
tabType= arguments[3],
data= arguments[4];
mountDialog(gettext(`Rename Panel ${_.escape(title)}`), (onClose, setNewSize)=> {
return <Theme>
<RenamePanelContent
setHeight={(containerHeight)=>{
setNewSize(pgAdmin.Browser.stdW.md, containerHeight);
}}
closeModal={()=>{
onClose();
}}
panel={panel}
tabType={tabType}
title={title}
data={data}
preferences={preferences}
/>
</Theme>;
});
}

View File

@@ -103,6 +103,13 @@ export default function(basicSettings) {
textMuted: '#8A8A8A',
erdCanvasBg: '#303030',
erdGridColor: '#444952',
schemaDiff: {
diffRowColor: '#807a48',
sourceRowColor: '#402025',
targetRowColor: '#6b5438',
diffColorFg: '#d4d4d4',
diffSelectFG: '#d4d4d4'
}
}
});
}

View File

@@ -101,6 +101,13 @@ export default function(basicSettings) {
textMuted: '#8b9cad',
erdCanvasBg: '#010B15',
erdGridColor: '#1F2932',
schemaDiff: {
diffRowColor: '#CFC56E',
sourceRowColor: '#EE97A5',
targetRowColor: '#FFAD65',
diffColorFg: '#FFFFFF',
diffSelectFG: '#010B15'
}
}
});
}

View File

@@ -121,6 +121,13 @@ export default function(basicSettings) {
color: '#FFFFFF',
bg: '#880000'
},
},
schemaDiff: {
diffRowColor: '#fff9c4',
sourceRowColor: '#ffebee',
targetRowColor: '#fbe3bf',
diffColorFg: '#222',
diffSelectFG: '#222'
}
}
});

View File

@@ -37,6 +37,7 @@ const useStyles = makeStyles((theme)=>({
},
message: {
marginLeft: '0.5rem',
fontSize: '16px',
}
}));

View File

@@ -128,7 +128,7 @@ CustomRow.propTypes = {
};
export default function PgReactDataGrid({gridRef, className, hasSelectColumn=true, onItemEnter, onItemSelect,
onItemClick, noRowsText, ...props}) {
onItemClick, noRowsText, noRowsIcon,...props}) {
const classes = useStyles();
let finalClassName = [classes.root];
hasSelectColumn && finalClassName.push(classes.hasSelectColumn);
@@ -142,7 +142,7 @@ export default function PgReactDataGrid({gridRef, className, hasSelectColumn=tru
components={{
sortIcon: CutomSortIcon,
rowRenderer: CustomRow,
noRowsFallback: <Box textAlign="center" gridColumn="1/-1" p={1}>{noRowsText || gettext('No rows found.')}</Box>,
noRowsFallback: <Box textAlign="center" gridColumn="1/-1" p={1}>{noRowsIcon}{noRowsText || gettext('No rows found.')}</Box>,
}}
{...props}
/>
@@ -158,5 +158,6 @@ PgReactDataGrid.propTypes = {
onItemEnter: PropTypes.func,
onItemSelect: PropTypes.func,
onItemClick: PropTypes.func,
noRowsText: PropTypes.string
noRowsText: PropTypes.string,
noRowsIcon: PropTypes.elementType
};

View File

@@ -67,6 +67,12 @@ const useStyles = makeStyles((theme)=>({
'& .dock-tabpane': {
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
},
'& #id-schema-diff': {
overflowY: 'auto'
},
'& #id-results': {
overflowY: 'auto'
}
},
'& .dock-tab': {

View File

@@ -1,203 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'jquery',
'sources/selection/range_selection_helper',
], function ($, RangeSelectionHelper) {
return function () {
var KEY_RIGHT = 39;
var KEY_LEFT = 37;
var KEY_UP = 38;
var KEY_DOWN = 40;
var bypassDefaultActiveCellRangeChange = false;
var isColumnsResized = false;
var isMouseInHeader = false;
var grid;
var init = function (slickGrid) {
grid = slickGrid;
grid.onDragEnd.subscribe(onDragEndHandler);
grid.onHeaderClick.subscribe(onHeaderClickHandler);
grid.onClick.subscribe(onClickHandler);
grid.onActiveCellChanged.subscribe(onActiveCellChangedHandler);
grid.onKeyDown.subscribe(onKeyDownHandler);
grid.onHeaderMouseEnter.subscribe(onHeaderMouseEnterHandler);
grid.onHeaderMouseLeave.subscribe(onHeaderMouseLeaveHandler);
grid.onColumnsResized.subscribe(onColumnsResizedHandler);
};
var destroy = function () {
grid.onDragEnd.unsubscribe(onDragEndHandler);
grid.onHeaderClick.unsubscribe(onHeaderClickHandler);
grid.onActiveCellChanged.unsubscribe(onActiveCellChangedHandler);
grid.onKeyDown.unsubscribe(onKeyDownHandler);
grid.onHeaderMouseEnter.unsubscribe(onHeaderMouseEnterHandler);
grid.onHeaderMouseLeave.unsubscribe(onHeaderMouseLeaveHandler);
grid.onColumnsResized.unsubscribe(onColumnsResizedHandler);
};
$.extend(this, {
'init': init,
'destroy': destroy,
});
function onDragEndHandler(event, dragData) {
bypassDefaultActiveCellRangeChange = true;
grid.setActiveCell(dragData.range.start.row, dragData.range.start.cell);
}
function onHeaderClickHandler(event, args) {
if (isColumnsResizedAndCurrentlyInHeader()) {
isColumnsResized = false;
event.stopPropagation();
return;
}
/* Skip if clicked on resize handler */
if($(event.target).hasClass('slick-resizable-handle')) {
return;
}
bypassDefaultActiveCellRangeChange = true;
var clickedColumn = args.column.pos + 1;
if (isClickingLastClickedHeader(0, clickedColumn)) {
if (isSingleRangeSelected()) {
grid.resetActiveCell();
} else {
grid.setActiveCell(0, retrievePreviousSelectedRange().fromCell);
}
} else if (!isClickingInSelectedColumn(clickedColumn)) {
grid.setActiveCell(0, clickedColumn);
}
}
function isEditableNewRow(row) {
return row >= grid.getDataLength();
}
function onHeaderMouseLeaveHandler() {
isMouseInHeader = false;
}
function onHeaderMouseEnterHandler() {
isMouseInHeader = true;
isColumnsResized = false;
}
function onColumnsResizedHandler() {
isColumnsResized = true;
}
function onClickHandler(event, args) {
if (isRowHeader(args.cell)) {
bypassDefaultActiveCellRangeChange = true;
var rowClicked = args.row;
if (isEditableNewRow(rowClicked)) {
return;
}
if (isClickingLastClickedHeader(rowClicked, 1)) {
if (isSingleRangeSelected() || grid.getSelectionModel().getSelectedRanges().length === 0) {
grid.resetActiveCell();
} else {
grid.setActiveCell(retrievePreviousSelectedRange().fromRow, 1);
}
} else if (!isClickingInSelectedRow(rowClicked)) {
grid.setActiveCell(rowClicked, 1);
}
}
}
function onActiveCellChangedHandler(event) {
if (bypassDefaultActiveCellRangeChange) {
bypassDefaultActiveCellRangeChange = false;
event.stopPropagation();
}
}
function onKeyDownHandler(event) {
if (hasActiveCell() && isShiftArrowKey(event)) {
selectOnlyRangeOfActiveCell();
}
}
function isColumnsResizedAndCurrentlyInHeader() {
return isMouseInHeader && isColumnsResized;
}
function isClickingLastClickedHeader(clickedRow, clickedColumn) {
return hasActiveCell() && grid.getActiveCell().row === clickedRow && grid.getActiveCell().cell === clickedColumn;
}
function isClickingInSelectedColumn(clickedColumn) {
var column = RangeSelectionHelper.rangeForColumn(grid, clickedColumn);
var cellSelectionModel = grid.getSelectionModel();
var ranges = cellSelectionModel.getSelectedRanges();
return RangeSelectionHelper.isRangeSelected(ranges, column);
}
function isRowHeader(cellClicked) {
return grid.getColumns()[cellClicked].id === 'row-header-column';
}
function isClickingInSelectedRow(rowClicked) {
var row = RangeSelectionHelper.rangeForRow(grid, rowClicked);
var cellSelectionModel = grid.getSelectionModel();
var ranges = cellSelectionModel.getSelectedRanges();
return RangeSelectionHelper.isRangeSelected(ranges, row);
}
function isSingleRangeSelected() {
var cellSelectionModel = grid.getSelectionModel();
var ranges = cellSelectionModel.getSelectedRanges();
return ranges.length === 1;
}
function retrievePreviousSelectedRange() {
var cellSelectionModel = grid.getSelectionModel();
var ranges = cellSelectionModel.getSelectedRanges();
return ranges[ranges.length - 2];
}
function isArrowKey(event) {
return event.which === KEY_RIGHT
|| event.which === KEY_UP
|| event.which === KEY_LEFT
|| event.which === KEY_DOWN;
}
function isModifiedByShiftOnly(event) {
return event.shiftKey
&& !event.ctrlKey
&& !event.altKey;
}
function isShiftArrowKey(event) {
return isModifiedByShiftOnly(event) && isArrowKey(event);
}
function hasActiveCell() {
return !!grid.getActiveCell();
}
function selectOnlyRangeOfActiveCell() {
var cellSelectionModel = grid.getSelectionModel();
var ranges = cellSelectionModel.getSelectedRanges();
if (ranges.length > 1) {
cellSelectionModel.setSelectedRanges([ranges.pop()]);
}
}
};
});

View File

@@ -1,164 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'jquery',
'sources/selection/range_selection_helper',
'slickgrid',
], function ($, RangeSelectionHelper) {
return function () {
var Slick = window.Slick,
gridEventBus = new Slick.EventHandler(),
onBeforeColumnSelectAll = new Slick.Event(),
onColumnSelectAll = new Slick.Event();
var init = function (grid) {
gridEventBus.subscribe(grid.onHeaderClick, handleHeaderClick.bind(null, grid));
grid.getSelectionModel().onSelectedRangesChanged
.subscribe(handleSelectedRangesChanged.bind(null, grid));
onColumnSelectAll.subscribe(function(e, args) {
updateRanges(args.grid, args.column.id);
});
};
var handleHeaderClick = function (grid, event, args) {
var columnDefinition = args.column;
grid.focus();
if (isColumnSelectable(columnDefinition)) {
var $columnHeader = $(event.target);
if (hasClickedChildOfColumnHeader(event)) {
if ($(event.target).hasClass('slick-resizable-handle')) {
return;
}
$columnHeader = $(event.target).parents('.slick-header-column');
}
$columnHeader.toggleClass('selected');
if ($columnHeader.hasClass('selected')) {
onBeforeColumnSelectAll.notify(args, event);
}
if (!(event.isPropagationStopped() || event.isImmediatePropagationStopped())) {
updateRanges(grid, columnDefinition.id);
}
} else {
toggleColumnHeaderForCopyHeader(grid);
}
};
var toggleColumnHeaderForCopyHeader = function(grid) {
if(!$('.copy-with-header').hasClass('visibility-hidden')) {
var selRowCnt = grid.getSelectedRows();
$('.slick-header-column').each(function (index, columnHeader) {
if (selRowCnt.length == 0) {
$(columnHeader).removeClass('selected');
grid.getColumns()[index].selected = false;
}
else {
if (index > 0 && grid.getColumns()[index].selectable) {
$(columnHeader).addClass('selected');
grid.getColumns()[index].selected = true;
}
}
});
} else {
$('.slick-header-column').each(function (index, columnHeader) {
$(columnHeader).removeClass('selected');
});
}
}.bind(RangeSelectionHelper);
var handleSelectedRangesChanged = function (grid, event, selectedRanges) {
$('.slick-header-column').each(function (index, columnHeader) {
var $spanHeaderColumn = $(columnHeader).find('[data-cell-type="column-header-row"]');
var columnIndex = grid.getColumnIndex($spanHeaderColumn.data('column-id'));
if (isColumnSelected(grid, selectedRanges, columnIndex)) {
$(columnHeader).addClass('selected');
if (columnIndex) grid.getColumns()[columnIndex].selected = true;
} else if(!RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges)){
$(columnHeader).removeClass('selected');
if (columnIndex) grid.getColumns()[columnIndex].selected = false;
}
});
};
var updateRanges = function (grid, columnId) {
var selectionModel = grid.getSelectionModel();
var ranges = selectionModel.getSelectedRanges();
var columnIndex = grid.getColumnIndex(columnId);
var columnRange = RangeSelectionHelper.rangeForColumn(grid, columnIndex);
var newRanges;
if (RangeSelectionHelper.isRangeSelected(ranges, columnRange)) {
newRanges = RangeSelectionHelper.removeRange(ranges, columnRange);
} else {
if (RangeSelectionHelper.areAllRangesSingleColumns(ranges, grid)) {
newRanges = RangeSelectionHelper.addRange(ranges, columnRange);
} else {
newRanges = [columnRange];
}
}
selectionModel.setSelectedRanges(newRanges);
};
var hasClickedChildOfColumnHeader = function (event) {
return !$(event.target).hasClass('slick-header-column');
};
var isColumnSelectable = function (columnDefinition) {
return columnDefinition.selectable !== false;
};
var isColumnSelected = function (grid, selectedRanges, columnIndex) {
var allRangesAreRows = RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges);
return isAnyCellSelectedInColumn(grid, selectedRanges, columnIndex) && !allRangesAreRows;
};
var isAnyCellSelectedInColumn = function (grid, selectedRanges, columnIndex) {
var isStillSelected = RangeSelectionHelper.isRangeEntirelyWithinSelectedRanges(selectedRanges,
RangeSelectionHelper.rangeForColumn(grid, columnIndex));
var cellSelectedInColumn = RangeSelectionHelper.isAnyCellOfColumnSelected(selectedRanges, columnIndex);
return isStillSelected || cellSelectedInColumn;
};
var getColumnDefinitions = function (columnDefinitions) {
return _.map(columnDefinitions, function (columnDefinition) {
if (isColumnSelectable(columnDefinition)) {
var name =
'<span data-cell-type=\'column-header-row\' ' +
' data-test=\'output-column-header\'' +
' data-column-id=\'' + columnDefinition.id + '\'>' +
' <span class=\'column-description\'>' +
' <span class=\'column-name\'>' + columnDefinition.display_name + '</span>' +
' <span class=\'column-type\'>' + columnDefinition.column_type + '</span>' +
' </span>' +
'</span>';
return _.extend(columnDefinition, {
name: name,
});
} else {
return columnDefinition;
}
});
};
$.extend(this, {
'init': init,
'getColumnDefinitions': getColumnDefinitions,
'onBeforeColumnSelectAll': onBeforeColumnSelectAll,
'onColumnSelectAll': onColumnSelectAll,
'toggleColumnHeaderForCopyHeader': toggleColumnHeaderForCopyHeader,
});
};
});

View File

@@ -1,58 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'jquery',
'underscore',
'sources/selection/clipboard',
'sources/selection/range_selection_helper',
'sources/selection/range_boundary_navigator',
],
function ($, _, clipboard, RangeSelectionHelper, rangeBoundaryNavigator) {
var copyData = function () {
var self = this || window;
var grid = self.slickgrid;
var columnDefinitions = grid.getColumns();
var selectedRanges = grid.getSelectionModel().getSelectedRanges();
var dataView = grid.getData();
var rows = grid.getSelectedRows();
var CSVOptions = grid.CSVOptions;
if (RangeSelectionHelper.areAllRangesCompleteRows(grid, selectedRanges)) {
self.copied_rows = rows.map(function (rowIndex) {
return grid.getDataItem(rowIndex);
});
setPasteRowButtonEnablement(self.can_edit, true);
} else {
self.copied_rows = [];
setPasteRowButtonEnablement(self.can_edit, false);
}
var csvText = rangeBoundaryNavigator.rangesToCsv(dataView.getItems(), columnDefinitions,
selectedRanges, CSVOptions, copyWithHeader());
if (csvText) {
clipboard.copyTextToClipboard(csvText);
}
};
var copyWithHeader = function () {
return !$('.copy-with-header').hasClass('visibility-hidden');
};
var setPasteRowButtonEnablement = function (canEditFlag, isEnabled) {
if (canEditFlag) {
$('#btn-paste-row').prop('disabled', !isEnabled);
if(isEnabled && window.parent.$) {
// trigger copied event to all sessions
window.parent.$(window.parent.document).trigger('pgadmin-sqleditor:rows-copied', copyWithHeader());
}
}
};
return copyData;
});

View File

@@ -1,92 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define(['jquery',
'sources/gettext',
'sources/selection/column_selector',
'sources/selection/row_selector',
'sources/selection/range_selection_helper',
'sources/url_for',
], function ($, gettext, ColumnSelector, RowSelector, RangeSelectionHelper, url_for) {
return function (columnDefinitions) {
var Slick = window.Slick,
rowSelector = new RowSelector(columnDefinitions),
columnSelector = new ColumnSelector(columnDefinitions),
onBeforeGridSelectAll = new Slick.Event(),
onGridSelectAll = new Slick.Event(),
onBeforeGridColumnSelectAll = columnSelector.onBeforeColumnSelectAll,
onGridColumnSelectAll = columnSelector.onColumnSelectAll;
var init = function (grid) {
this.grid = grid;
grid.onHeaderClick.subscribe(function (event, eventArguments) {
if (eventArguments.column.selectAllOnClick && !$(event.target).hasClass('slick-resizable-handle')) {
toggleSelectAll(grid, event, eventArguments);
}
});
grid.getSelectionModel().onSelectedRangesChanged
.subscribe(handleSelectedRangesChanged.bind(null, grid));
grid.registerPlugin(rowSelector);
grid.registerPlugin(columnSelector);
onGridSelectAll.subscribe(function(e, args) {
RangeSelectionHelper.selectAll(args.grid);
});
};
var getColumnDefinitions = function (columnDefinition) {
columnDefinition = columnSelector.getColumnDefinitions(columnDefinition);
columnDefinition = rowSelector.getColumnDefinitions(columnDefinition);
columnDefinition[0].selectAllOnClick = true;
columnDefinition[0].name = '<span data-id="select-all" ' +
'title="' + gettext('Select/Deselect All') + '">' +
'<br>' +
columnDefinition[0].name +
'<img class="select-all-icon" src="' + url_for('static', {'filename': 'img/select-all-icon.png'}) + '"></img>' +
'</span>';
return columnDefinition;
};
function handleSelectedRangesChanged(grid) {
if(RangeSelectionHelper.isEntireGridSelected(grid)) {
$('[data-id=\'select-all\']').addClass('selected');
} else {
$('[data-id=\'select-all\']').removeClass('selected');
}
}
function toggleSelectAll(grid, event, eventArguments) {
if (RangeSelectionHelper.isEntireGridSelected(grid)) {
selectNone(grid);
} else {
onBeforeGridSelectAll.notify(eventArguments, event);
if (!(event.isPropagationStopped() || event.isImmediatePropagationStopped())) {
RangeSelectionHelper.selectAll(grid);
}
}
}
function selectNone(grid) {
var selectionModel = grid.getSelectionModel();
selectionModel.setSelectedRanges([]);
}
$.extend(this, {
'init': init,
'getColumnDefinitions': getColumnDefinitions,
'onBeforeGridSelectAll': onBeforeGridSelectAll,
'onGridSelectAll': onGridSelectAll,
'onBeforeGridColumnSelectAll': onBeforeGridColumnSelectAll,
'onGridColumnSelectAll': onGridColumnSelectAll,
});
};
});

View File

@@ -1,171 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define(['slickgrid'], function () {
var Slick = window.Slick;
var isSameRange = function (range, otherRange) {
return range.fromCell == otherRange.fromCell && range.toCell == otherRange.toCell &&
range.fromRow == otherRange.fromRow && range.toRow == otherRange.toRow;
};
var isRangeSelected = function (selectedRanges, range) {
return _.any(selectedRanges, function (selectedRange) {
return isSameRange(selectedRange, range);
});
};
var isAnyCellOfColumnSelected = function (selectedRanges, column) {
return _.any(selectedRanges, function (selectedRange) {
return selectedRange.fromCell <= column && selectedRange.toCell >= column;
});
};
var isAnyCellOfRowSelected = function (selectedRanges, row) {
return _.any(selectedRanges, function (selectedRange) {
return selectedRange.fromRow <= row && selectedRange.toRow >= row;
});
};
var isRangeEntirelyWithinSelectedRanges = function (selectedRanges, range) {
return _.any(selectedRanges, function (selectedRange) {
return selectedRange.fromCell <= range.fromCell && selectedRange.toCell >= range.toCell &&
selectedRange.fromRow <= range.fromRow && selectedRange.toRow >= range.toRow;
});
};
var removeRange = function (selectedRanges, range) {
return _.filter(selectedRanges, function (selectedRange) {
return !(isSameRange(selectedRange, range));
});
};
var addRange = function (ranges, range) {
ranges.push(range);
return ranges;
};
var areAllRangesSingleRows = function (ranges, grid) {
return _.every(ranges, function (range) {
return range.fromRow == range.toRow && rangeHasCompleteRows(grid, range);
});
};
var areAllRangesSingleColumns = function (ranges, grid) {
return _.every(ranges, isRangeAColumn.bind(this, grid));
};
var rangeForRow = function (grid, rowId) {
var columnDefinitions = grid.getColumns();
if (isFirstColumnData(columnDefinitions)) {
return new Slick.Range(rowId, 0, rowId, grid.getColumns().length - 1);
}
return new Slick.Range(rowId, 1, rowId, grid.getColumns().length - 1);
};
var rangeForColumn = function (grid, columnIndex) {
return new Slick.Range(0, columnIndex, grid.getDataLength() - 1, columnIndex);
};
var getRangeOfWholeGrid = function (grid) {
return new Slick.Range(0, 1, grid.getDataLength() - 1, grid.getColumns().length - 1);
};
var isEntireGridSelected = function (grid) {
var selectionModel = grid.getSelectionModel();
var selectedRanges = selectionModel.getSelectedRanges();
return selectedRanges.length == 1 && isSameRange(selectedRanges[0], getRangeOfWholeGrid(grid));
};
var isFirstColumnData = function (columnDefinitions) {
return !_.isUndefined(columnDefinitions[0].pos);
};
var areAllRangesCompleteColumns = function (grid, ranges) {
return _.every(ranges, function (range) {
return rangeHasCompleteColumns(grid, range);
});
};
var areAllRangesCompleteRows = function (grid, ranges) {
return _.every(ranges, function (range) {
return rangeHasCompleteRows(grid, range);
});
};
var getIndexesOfCompleteRows = function (grid, ranges) {
var indexArray = [];
ranges.forEach(function (range) {
if (rangeHasCompleteRows(grid, range))
indexArray = indexArray.concat(_.range(range.fromRow, range.toRow + 1));
});
return indexArray;
};
var isRangeAColumn = function (grid, range) {
return range.fromCell == range.toCell &&
range.fromRow == 0 && range.toRow == grid.getDataLength() - 1;
};
var rangeHasCompleteColumns = function (grid, range) {
return range.fromRow === 0 && range.toRow === grid.getDataLength() - 1;
};
var rangeHasCompleteRows = function (grid, range) {
return range.fromCell === getFirstDataColumnIndex(grid) &&
range.toCell === getLastDataColumnIndex(grid);
};
function getFirstDataColumnIndex(grid) {
return _.findIndex(grid.getColumns(), function (columnDefinition) {
var pos = columnDefinition.pos;
return !_.isUndefined(pos) && isSelectable(columnDefinition);
});
}
function getLastDataColumnIndex(grid) {
return _.findLastIndex(grid.getColumns(), isSelectable);
}
function isSelectable(columnDefinition) {
return (_.isUndefined(columnDefinition.selectable) || columnDefinition.selectable === true);
}
function selectAll(grid) {
var range = getRangeOfWholeGrid(grid);
var selectionModel = grid.getSelectionModel();
selectionModel.setSelectedRanges([range]);
}
return {
addRange: addRange,
removeRange: removeRange,
isRangeSelected: isRangeSelected,
areAllRangesSingleRows: areAllRangesSingleRows,
areAllRangesSingleColumns: areAllRangesSingleColumns,
areAllRangesCompleteRows: areAllRangesCompleteRows,
areAllRangesCompleteColumns: areAllRangesCompleteColumns,
rangeForRow: rangeForRow,
rangeForColumn: rangeForColumn,
isEntireGridSelected: isEntireGridSelected,
getRangeOfWholeGrid: getRangeOfWholeGrid,
isFirstColumnData: isFirstColumnData,
getIndexesOfCompleteRows: getIndexesOfCompleteRows,
selectAll: selectAll,
isRangeAColumn: isRangeAColumn,
rangeHasCompleteColumns: rangeHasCompleteColumns,
rangeHasCompleteRows: rangeHasCompleteRows,
isAnyCellOfColumnSelected: isAnyCellOfColumnSelected,
isRangeEntirelyWithinSelectedRanges: isRangeEntirelyWithinSelectedRanges,
isAnyCellOfRowSelected: isAnyCellOfRowSelected,
};
});

View File

@@ -1,110 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'jquery',
'sources/selection/range_selection_helper',
'sources/selection/column_selector',
'slickgrid',
], function ($, RangeSelectionHelper, ColumnSelector) {
return function () {
var Slick = window.Slick;
var gridEventBus = new Slick.EventHandler();
var columnSelector = new ColumnSelector();
var init = function (grid) {
grid.getSelectionModel().onSelectedRangesChanged
.subscribe(handleSelectedRangesChanged.bind(null, grid));
gridEventBus
.subscribe(grid.onClick, handleClick.bind(null, grid));
};
var handleClick = function (grid, event, args) {
if (grid.getColumns()[args.cell].id === 'row-header-column') {
var $rowHeaderSpan = $(event.target);
if ($rowHeaderSpan.data('cell-type') != 'row-header-selector') {
$rowHeaderSpan = $(event.target).find('[data-cell-type="row-header-selector"]');
}
$rowHeaderSpan.parent().toggleClass('selected');
updateRanges(grid, args.row);
columnSelector.toggleColumnHeaderForCopyHeader(grid);
}
};
var handleSelectedRangesChanged = function (grid, event, selectedRanges) {
$('[data-cell-type="row-header-selector"]').each(function (index, rowHeaderSpan) {
var $rowHeaderSpan = $(rowHeaderSpan);
var row = parseInt($rowHeaderSpan.data('row'));
if (isRowSelected(grid, selectedRanges, row)) {
$rowHeaderSpan.parent().addClass('selected');
} else {
$rowHeaderSpan.parent().removeClass('selected');
}
});
};
var updateRanges = function (grid, rowId) {
var selectionModel = grid.getSelectionModel();
var ranges = selectionModel.getSelectedRanges();
var rowRange = RangeSelectionHelper.rangeForRow(grid, rowId);
var newRanges;
if (RangeSelectionHelper.isRangeSelected(ranges, rowRange)) {
newRanges = RangeSelectionHelper.removeRange(ranges, rowRange);
} else {
if (RangeSelectionHelper.areAllRangesSingleRows(ranges, grid)) {
newRanges = RangeSelectionHelper.addRange(ranges, rowRange);
} else {
newRanges = [rowRange];
}
}
selectionModel.setSelectedRanges(newRanges);
};
var isAnyCellSelectedInRow = function (grid, selectedRanges, row) {
var isStillSelected = RangeSelectionHelper.isRangeEntirelyWithinSelectedRanges(selectedRanges,
RangeSelectionHelper.rangeForRow(grid, row));
var cellSelectedInRow = RangeSelectionHelper.isAnyCellOfRowSelected(selectedRanges, row);
return isStillSelected || cellSelectedInRow;
};
var isRowSelected = function (grid, selectedRanges, row) {
var allRangesAreColumns = RangeSelectionHelper.areAllRangesCompleteColumns(grid, selectedRanges);
return isAnyCellSelectedInRow(grid, selectedRanges, row) && !allRangesAreColumns;
};
var getColumnDefinitions = function (columnDefinitions) {
columnDefinitions.unshift({
id: 'row-header-column',
name: '',
selectable: false,
focusable: false,
formatter: function (rowIndex) {
return '<span ' +
'data-row="' + rowIndex + '" ' +
'data-cell-type="row-header-selector">' +
(rowIndex+1) + '</span>';
},
width: 30,
});
return columnDefinitions;
};
$.extend(this, {
'init': init,
'getColumnDefinitions': getColumnDefinitions,
});
};
});

View File

@@ -1,240 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'jquery',
'underscore',
'sources/selection/range_selection_helper',
'sources/window',
'slickgrid',
], function ($, _, RangeSelectionHelper, pgWindow) {
return function (options) {
var KEY_ARROW_RIGHT = 39;
var KEY_ARROW_LEFT = 37;
var KEY_ARROW_UP = 38;
var KEY_ARROW_DOWN = 40;
var Slick = window.Slick;
var _grid;
var _ranges = [];
var _self = this;
var _selector = new Slick.CellRangeSelector({
selectionCss: {
border: '2px solid black',
},
offset: {
top: 0,
left: -1,
height: 2,
width: 1,
},
});
var _options;
var _defaults = {
selectActiveCell: true,
};
function init(grid) {
_options = $.extend(true, {}, _defaults, options);
_grid = grid;
_grid.onActiveCellChanged.subscribe(handleActiveCellChange);
_grid.onKeyDown.subscribe(handleKeyDown);
grid.registerPlugin(_selector);
_selector.onCellRangeSelected.subscribe(handleCellRangeSelected);
_selector.onBeforeCellRangeSelected.subscribe(handleBeforeCellRangeSelected);
$(pgWindow.default).on('mouseup',handleWindowMouseUp);
}
function destroy() {
_grid.onActiveCellChanged.unsubscribe(handleActiveCellChange);
_grid.onKeyDown.unsubscribe(handleKeyDown);
_selector.onCellRangeSelected.unsubscribe(handleCellRangeSelected);
_selector.onBeforeCellRangeSelected.unsubscribe(handleBeforeCellRangeSelected);
_grid.unregisterPlugin(_selector);
$(pgWindow.default).off('mouseup', handleWindowMouseUp);
}
function removeInvalidRanges(ranges) {
var result = [];
for (let range_val of ranges) {
var r = range_val;
if (_grid.canCellBeSelected(r.fromRow, r.fromCell) && _grid.canCellBeSelected(r.toRow, r.toCell)) {
result.push(r);
}
}
return result;
}
function setSelectedRanges(ranges) {
// simple check for: empty selection didn't change, prevent firing onSelectedRangesChanged
if ((!_ranges || _ranges.length === 0) && (!ranges || ranges.length === 0)) { return; }
_ranges = removeInvalidRanges(ranges);
_self.onSelectedRangesChanged.notify(_ranges);
}
function getSelectedRanges() {
return _ranges;
}
function setSelectedRows(rows) {
_ranges = [];
for(let row_val of rows) {
_ranges.push(RangeSelectionHelper.rangeForRow(_grid, row_val));
}
}
function handleBeforeCellRangeSelected(e) {
if (_grid.getEditorLock().isActive()) {
e.stopPropagation();
return false;
}
}
function handleCellRangeSelected(e, args) {
setSelectedRanges([args.range]);
}
function handleActiveCellChange(e, args) {
if (_options.selectActiveCell && args.row != null && args.cell != null) {
setSelectedRanges([new Slick.Range(args.row, args.cell)]);
}
}
function arrowKeyPressed(event) {
return event.which == KEY_ARROW_RIGHT
|| event.which == KEY_ARROW_LEFT
|| event.which == KEY_ARROW_UP
|| event.which == KEY_ARROW_DOWN;
}
function shiftArrowKeyPressed(event) {
return event.shiftKey && !event.ctrlKey && !event.altKey &&
(arrowKeyPressed(event));
}
function needUpdateRange(newRange) {
return removeInvalidRanges([newRange]).length;
}
function handleKeyDown(e) {
var ranges;
var lastSelectedRange;
var anchorActiveCell = _grid.getActiveCell();
function isKey(key) { return e.which === key; }
function getKeycode() { return e.which; }
function shouldScrollToBottommostRow() { return anchorActiveCell.row === newSelectedRange.fromRow; }
function shouldScrollToRightmostColumn() { return anchorActiveCell.cell === newSelectedRange.fromCell; }
function getMobileCellFromRange(range, activeCell) {
var localMobileCell = {};
localMobileCell.row = range.fromRow === activeCell.row ? range.toRow : range.fromRow;
localMobileCell.cell = range.fromCell === activeCell.cell ? range.toCell : range.fromCell;
return localMobileCell;
}
function getNewRange(rangeCorner, oppositeCorner) {
var newFromCell = rangeCorner.cell <= oppositeCorner.cell ? rangeCorner.cell : oppositeCorner.cell;
var newToCell = rangeCorner.cell <= oppositeCorner.cell ? oppositeCorner.cell : rangeCorner.cell;
var newFromRow = rangeCorner.row <= oppositeCorner.row ? rangeCorner.row : oppositeCorner.row;
var newToRow = rangeCorner.row <= oppositeCorner.row ? oppositeCorner.row : rangeCorner.row;
return new Slick.Range(
newFromRow,
newFromCell,
newToRow,
newToCell
);
}
if (anchorActiveCell && shiftArrowKeyPressed(e)) {
ranges = getSelectedRanges();
if (!ranges.length) {
ranges.push(new Slick.Range(anchorActiveCell.row, anchorActiveCell.cell));
}
// keyboard can work with last range only
lastSelectedRange = ranges.pop();
// can't handle selection out of active cell
if (!lastSelectedRange.contains(anchorActiveCell.row, anchorActiveCell.cell)) {
lastSelectedRange = new Slick.Range(anchorActiveCell.row, anchorActiveCell.cell);
}
var mobileCell = getMobileCellFromRange(lastSelectedRange, anchorActiveCell);
switch (getKeycode()) {
case KEY_ARROW_LEFT:
mobileCell.cell -= 1;
break;
case KEY_ARROW_RIGHT:
mobileCell.cell += 1;
break;
case KEY_ARROW_UP:
mobileCell.row -= 1;
break;
case KEY_ARROW_DOWN:
mobileCell.row += 1;
break;
}
var newSelectedRange = getNewRange(anchorActiveCell, mobileCell);
if (needUpdateRange(newSelectedRange)) {
var rowToView = shouldScrollToBottommostRow() ? newSelectedRange.toRow : newSelectedRange.fromRow;
var columnToView = shouldScrollToRightmostColumn() ? newSelectedRange.toCell : newSelectedRange.fromCell;
if (isKey(KEY_ARROW_RIGHT) || isKey(KEY_ARROW_LEFT)) {
_grid.scrollColumnIntoView(columnToView);
} else if (isKey(KEY_ARROW_UP) || isKey(KEY_ARROW_DOWN)) {
_grid.scrollRowIntoView(rowToView);
}
ranges.push(newSelectedRange);
} else {
ranges.push(lastSelectedRange);
}
setSelectedRanges(ranges);
e.preventDefault();
e.stopPropagation();
}
}
function handleWindowMouseUp() {
var selectedRange = _selector.getCurrentRange();
if (!_.isUndefined(selectedRange)) {
_grid.onDragEnd.notify({range: selectedRange});
}
}
$.extend(this, {
'getSelectedRanges': getSelectedRanges,
'setSelectedRanges': setSelectedRanges,
'setSelectedRows': setSelectedRows,
'init': init,
'destroy': destroy,
'onSelectedRangesChanged': new Slick.Event(),
});
};
});

View File

@@ -1,27 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define(['slickgrid'], function () {
var Slick = window.Slick;
return function () {
this.init = function (grid) {
grid.onActiveCellChanged.subscribe(function (event, slickEvent) {
grid.getSelectionModel().setSelectedRanges([
new Slick.Range(
slickEvent.row,
slickEvent.cell,
slickEvent.row,
slickEvent.cell
),
]);
});
};
};
});

View File

@@ -1,189 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
(function ($) {
// register namespace
$.extend(true, window, {
'Slick': {
'Plugins': {
'HeaderButtons': HeaderButtons,
},
},
});
/***
* custom header button modified from slick.headerbuttons.js
*
* USAGE:
*
* Add the plugin .js & .css files and register it with the grid.
*
* To specify a custom button in a column header, extend the column definition like so:
*
* var columns = [
* {
* id: 'myColumn',
* name: 'My column',
*
* // This is the relevant part
* header: {
* buttons: [
* {
* // button options
* },
* {
* // button options
* }
* ]
* }
* }
* ];
*
* Available button options:
* cssClass: CSS class to add to the button.
* image: Relative button image path.
* tooltip: Button tooltip.
* showOnHover: Only show the button on hover.
* handler: Button click handler.
* command: A command identifier to be passed to the onCommand event handlers.
*
* The plugin exposes the following events:
* onCommand: Fired on button click for buttons with 'command' specified.
* Event args:
* grid: Reference to the grid.
* column: Column definition.
* command: Button command identified.
* button: Button options. Note that you can change the button options in your
* event handler, and the column header will be automatically updated to
* reflect them. This is useful if you want to implement something like a
* toggle button.
*
*
* @param options {Object} Options:
* buttonCssClass: a CSS class to use for buttons (default 'slick-header-button')
* @class Slick.Plugins.HeaderButtons
* @constructor
*/
function HeaderButtons(options) {
var _grid;
var _self = this;
var _handler = new window.Slick.EventHandler();
var _defaults = {
buttonCssClass: 'slick-header-button',
};
function init(grid) {
options = $.extend(true, {}, _defaults, options);
_grid = grid;
_handler
.subscribe(_grid.onHeaderCellRendered, handleHeaderCellRendered)
.subscribe(_grid.onBeforeHeaderCellDestroy, handleBeforeHeaderCellDestroy);
// Force the grid to re-render the header now that the events are hooked up.
_grid.setColumns(_grid.getColumns());
}
function destroy() {
_handler.unsubscribeAll();
}
function handleHeaderCellRendered(e, args) {
var column = args.column;
if (column.header && column.header.buttons) {
// Append buttons in reverse order since they are floated to the right.
var i = column.header.buttons.length;
while (i--) {
var button = column.header.buttons[i];
var btn = $('<div></div>')
.addClass(options.buttonCssClass)
.data('column', column)
.data('button', button);
if (button.content){
btn.append(button.content);
}
if (button.showOnHover) {
btn.addClass('slick-header-button-hidden');
}
if (button.image) {
btn.css('backgroundImage', 'url(' + button.image + ')');
}
if (button.cssClass) {
btn.addClass(button.cssClass);
}
if (button.tooltip) {
btn.attr('title', button.tooltip);
}
if (button.command) {
btn.data('command', button.command);
}
if (button.handler) {
btn.bind('click', button.handler);
}
btn
.bind('click', handleButtonClick)
.prependTo(args.node);
}
}
}
function handleBeforeHeaderCellDestroy(e, args) {
var column = args.column;
if (column.header && column.header.buttons) {
// Removing buttons via jQuery will also clean up any event handlers and data.
// NOTE: If you attach event handlers directly or using a different framework,
// you must also clean them up here to avoid memory leaks.
$(args.node).find('.' + options.buttonCssClass).remove();
}
}
function handleButtonClick(e) {
var command = $(this).data('command');
var columnDef = $(this).data('column');
var button = $(this).data('button');
if (command != null) {
_self.onCommand.notify({
'grid': _grid,
'column': columnDef,
'command': command,
'button': button,
}, e, _self);
// Update the header in case the user updated the button definition in the handler.
_grid.updateColumnHeader(columnDef.id);
}
// Stop propagation so that it doesn't register as a header click event.
e.preventDefault();
e.stopPropagation();
}
$.extend(this, {
'init': init,
'destroy': destroy,
'onCommand': new window.Slick.Event(),
});
}
})(window.jQuery);

File diff suppressed because it is too large Load Diff

View File

@@ -1,31 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
define([
'sources/selection/copy_data',
'sources/selection/range_selection_helper',
],
function (copyData, RangeSelectionHelper) {
return function handleQueryOutputKeyboardEvent(event, args) {
var KEY_C = 67;
var KEY_A = 65;
var modifiedKey = event.keyCode;
var isModifierDown = event.ctrlKey || event.metaKey;
var self = this || window;
self.slickgrid = args.grid;
if (isModifierDown && modifiedKey == KEY_C) {
copyData.apply(self);
}
if (isModifierDown && modifiedKey == KEY_A) {
RangeSelectionHelper.selectAll(self.slickgrid);
}
};
});

View File

@@ -1,132 +0,0 @@
/////////////////////////////////////////////////////////////
//
// pgAdmin 4 - PostgreSQL Tools
//
// Copyright (C) 2013 - 2022, The pgAdmin Development Team
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////
/***
* Contains pgAdmin4 related SlickGrid formatters.
*
* @module Formatters
* @namespace Slick
*/
(function($) {
// register namespace
$.extend(true, window, {
'Slick': {
'Formatters': {
'JsonString': JsonFormatter,
'Numbers': NumbersFormatter,
'Checkmark': CheckmarkFormatter,
'Text': TextFormatter,
'Binary': BinaryFormatter,
},
},
});
function NullAndDefaultFormatter(row, cell, value, columnDef) {
if (_.isUndefined(value) && columnDef.has_default_val) {
return '<span class=\'pull-left disabled_cell\'>[default]</span>';
} else if (
(_.isUndefined(value) && columnDef.not_null) ||
(_.isUndefined(value) || value === null)
) {
return '<span class=\'pull-left disabled_cell\'>[null]</span>';
}
return null;
}
function NullAndDefaultNumberFormatter(row, cell, value, columnDef) {
if (_.isUndefined(value) && columnDef.has_default_val) {
return '<span class=\'pull-right disabled_cell\'>[default]</span>';
} else if (
(_.isUndefined(value) && columnDef.not_null) ||
(_.isUndefined(value) || value === null)
) {
return '<span class=\'pull-right disabled_cell\'>[null]</span>';
}
return null;
}
function JsonFormatter(row, cell, value, columnDef) {
// If column has default value, set placeholder
var data = NullAndDefaultFormatter(row, cell, value, columnDef);
if (data) {
return data;
} else {
// Stringify only if it's json object
if (typeof value === 'object' && !Array.isArray(value)) {
return _.escape(JSON.stringify(value));
} else if (Array.isArray(value)) {
var temp = [];
$.each(value, function(i, val) {
if (typeof val === 'object') {
temp.push(JSON.stringify(val));
} else {
temp.push(val);
}
});
return _.escape('[' + temp.join() + ']');
} else {
return _.escape(value);
}
}
}
function NumbersFormatter(row, cell, value, columnDef) {
// If column has default value, set placeholder
var data = NullAndDefaultNumberFormatter(row, cell, value, columnDef);
if (data) {
return data;
} else {
return '<span style=\'float:right\'>' + _.escape(value) + '</span>';
}
}
function CheckmarkFormatter(row, cell, value, columnDef) {
/* Checkbox has 3 states
* 1) checked=true
* 2) unchecked=false
* 3) indeterminate=null
*/
var data = NullAndDefaultFormatter(row, cell, value, columnDef);
if (data) {
return data;
} else {
return value ? 'true' : 'false';
}
}
function TextFormatter(row, cell, value, columnDef) {
// If column has default value, set placeholder
var raw = NullAndDefaultFormatter(row, cell, value, columnDef);
var data;
if (raw) {
data = raw;
} else {
data = _.escape(value);
}
// Replace leading whitespace with a marker so we don't just show blank lines
if (data.trimStart() != data) {
data = '[...] ' + data.trimStart();
}
return data;
}
function BinaryFormatter(row, cell, value, columnDef) {
// If column has default value, set placeholder
var data = NullAndDefaultFormatter(row, cell, value, columnDef);
if (data) {
return data;
} else {
return '<span class=\'pull-left disabled_cell\'>[' + _.escape(value) + ']</span>';
}
}
})(window.jQuery);

View File

@@ -1,169 +0,0 @@
/*
* https://github.com/naresh-n/slickgrid-column-data-autosize
*/
(function($) {
$.extend(true, window, {
'Slick': {
'AutoColumnSize': AutoColumnSize,
},
});
function AutoColumnSize() {
var grid, $container, context,
keyCodes = {
'A': 65,
};
function init(_grid) {
grid = _grid;
$container = $(grid.getContainerNode());
$container.on('dblclick.autosize', '.slick-resizable-handle', reSizeColumn);
$container.keydown(handleControlKeys);
context = document.createElement('canvas').getContext('2d');
// Expose resizeAllColumns method to call from outside of this file.
grid.resizeAllColumns = resizeAllColumns;
}
function destroy() {
$container.off();
}
function handleControlKeys(event) {
if (event.ctrlKey && event.shiftKey && event.keyCode === keyCodes.A) {
resizeAllColumns();
}
}
function resizeAllColumns(maxWidth, max_width_changed=false) {
var elHeaders = $container.find('.slick-header-column');
var allColumns = grid.getColumns();
elHeaders.each(function(index, el) {
var columnDef = $(el).data('column');
// Check if width is set then no need to resize that column.
if (typeof(columnDef.width) !== 'undefined' && !isNaN(columnDef.width) && !max_width_changed) {
return;
}
var headerWidth = getElementWidth(el);
var colIndex = grid.getColumnIndex(columnDef.id);
var column = allColumns[colIndex];
var autoSizeWidth = Math.max(headerWidth, getMaxColumnTextWidth(columnDef, colIndex)) + 1;
// If max width is provided and it is greater than 0
if (typeof(maxWidth) !== 'undefined' && maxWidth > 0) {
autoSizeWidth = Math.min(maxWidth, autoSizeWidth);
}
column.width = autoSizeWidth + (columnDef.addWidth || 0);
});
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 (let data_val of data) {
texts.push(data_val[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').first();
$(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

@@ -833,18 +833,6 @@ body {
font-size: inherit !important;
}
/* CSS for custom checkbox editor in SlickGrid */
.multi-checkbox .check {
display: inline-block;
vertical-align: top;
width: 16px;
height: 16px;
border: 1px solid $color-gray-dark;
margin: 3px;
text-align: center;
line-height: 16px;
}
.multi-checkbox .check.checked,
.multi-checkbox .check.unchecked {
background: $color-bg;

View File

@@ -1,83 +0,0 @@
.slick-row .cell-actions {
text-align: left;
}
.slick-row.selected .cell-selection {
background-color: transparent; /* show default selected row background */
}
.slick-cell span[data-cell-type="row-header-selector"] {
display: block;
text-align: center;
}
/*
SlickGrid, To fix the issue of width misalignment between Column Header &
actual Column in Mozilla Firefox browser
Ref: https://github.com/mleibman/SlickGrid/issues/742
*/
.slickgrid, .slickgrid *, .slick-header-column {
box-sizing: content-box;
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box;
-ms-box-sizing: content-box;
}
.slick-cell.selected span[data-cell-type="row-header-selector"] {
color: $color-primary-fg;
}
.slick-cell.cell-move-handle {
font-weight: bold;
text-align: right;
border-right: solid $border-color;
background: $color-gray-lighter;
cursor: move;
&:hover {
background: $color-gray-light;
}
}
.cell-selection {
border-right-color: $border-color;
border-right-style: solid;
background: $color-gray-lighter;
color: $color-gray;
text-align: right;
font-size: 10px;
}
.slick-row.selected .cell-move-handle {
background: $color-warning-light;
}
.slick-row.complete {
background-color: $color-success-light;
color: $color-gray-dark;
}
.slick-row:hover .slick-cell{
border-top: $table-hover-border;
border-bottom: $table-hover-border;
background-color: $table-hover-bg-color;
}
.slick-row .slick-cell {
border-bottom: $panel-border;
border-right: $panel-border;
z-index: 0;
}
.slick-cell.active {
border: 1px solid transparent;
border-right: 1px solid $color-gray-light;
border-bottom-color: $color-gray-light;
}
.ui-widget-content.slick-row {
&.even, &.odd {
background: none;
background-color: $table-bg;
}
}

View File

@@ -34,6 +34,5 @@ $theme-colors: (
@import 'jsoneditor.overrides';
@import 'pgadmin4-tree.overrides';
@import 'pgadmin4-tree/src/css/styles';
@import 'slickgrid.overrides';
@import 'rc-dock/dist/rc-dock.css';
@import '@szhsin/react-menu/dist/index.css';