mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 08:26:01 +00:00
copy to clipboard event
This commit is contained in:
@@ -37,6 +37,7 @@ import {
|
||||
} from '@dbgate/datalib';
|
||||
import { scriptToSql } from '@dbgate/sqltree';
|
||||
import { sleep } from '../utility/common';
|
||||
import { copyTextToClipboard } from '../utility/clipboard';
|
||||
|
||||
const GridContainer = styled.div`
|
||||
position: absolute;
|
||||
@@ -324,6 +325,34 @@ export default function DataGridCore(props) {
|
||||
}
|
||||
}
|
||||
|
||||
function handleCopy(event) {
|
||||
if (event && event.target.localName == 'input') return;
|
||||
if (event) event.preventDefault();
|
||||
copyToClipboard();
|
||||
}
|
||||
|
||||
// function handlePaste(event) {
|
||||
// console.log('PASTE', event);
|
||||
// }
|
||||
|
||||
function copyToClipboard() {
|
||||
const rowIndexes = _.uniq(selectedCells.map(x => x[0])).sort();
|
||||
const lines = rowIndexes.map(rowIndex => {
|
||||
const colIndexes = selectedCells
|
||||
.filter(x => x[0] == rowIndex)
|
||||
.map(x => x[1])
|
||||
.sort();
|
||||
const rowData = loadedAndInsertedRows[rowIndex];
|
||||
const line = colIndexes
|
||||
.map(columnUniqueName)
|
||||
.map(col => (rowData[col] == null ? '' : rowData[col]))
|
||||
.join('\t');
|
||||
return line;
|
||||
});
|
||||
const text = lines.join('\r\n');
|
||||
copyTextToClipboard(text);
|
||||
}
|
||||
|
||||
function handleGridMouseMove(event) {
|
||||
if (autofillDragStartCell) {
|
||||
const cell = cellFromEvent(event);
|
||||
@@ -339,6 +368,10 @@ export default function DataGridCore(props) {
|
||||
}
|
||||
}
|
||||
|
||||
function columnUniqueName(columnIndex) {
|
||||
return columns[columnSizes.realToModel(columnIndex)].uniqueName;
|
||||
}
|
||||
|
||||
function handleGridMouseUp(event) {
|
||||
if (dragStartCell) {
|
||||
const cell = cellFromEvent(event);
|
||||
@@ -351,7 +384,7 @@ export default function DataGridCore(props) {
|
||||
if (_.isNumber(currentRowNumber)) {
|
||||
const rowIndexes = _.uniq((autofillSelectedCells || []).map(x => x[0])).filter(x => x != currentRowNumber);
|
||||
// @ts-ignore
|
||||
const colNames = selectedCells.map(cell => columns[columnSizes.realToModel(cell[1])].uniqueName);
|
||||
const colNames = selectedCells.map(cell => columnUniqueName(cell[1]));
|
||||
const changeObject = _.pick(loadedAndInsertedRows[currentRowNumber], colNames);
|
||||
setChangeSet(
|
||||
batchUpdateChangeSet(
|
||||
@@ -465,6 +498,11 @@ export default function DataGridCore(props) {
|
||||
revertRowChanges();
|
||||
}
|
||||
|
||||
if (event.keyCode == keycodes.c && event.ctrlKey) {
|
||||
event.preventDefault();
|
||||
copyToClipboard();
|
||||
}
|
||||
|
||||
if (event.keyCode == keycodes.delete && event.ctrlKey) {
|
||||
event.preventDefault();
|
||||
deleteCurrentRow();
|
||||
@@ -668,6 +706,8 @@ export default function DataGridCore(props) {
|
||||
onMouseUp={handleGridMouseUp}
|
||||
onKeyDown={handleGridKeyDown}
|
||||
onWheel={handleGridWheel}
|
||||
onCopy={handleCopy}
|
||||
// onPasteCapture={handlePaste}
|
||||
// table can be focused
|
||||
tabIndex={-1}
|
||||
ref={tableRef}
|
||||
|
||||
56
packages/web/src/utility/clipboard.js
Normal file
56
packages/web/src/utility/clipboard.js
Normal file
@@ -0,0 +1,56 @@
|
||||
export function copyTextToClipboard(text) {
|
||||
const textArea = document.createElement('textarea');
|
||||
|
||||
//
|
||||
// *** This styling is an extra step which is likely not required. ***
|
||||
//
|
||||
// Why is it here? To ensure:
|
||||
// 1. the element is able to have focus and selection.
|
||||
// 2. if element was to flash render it has minimal visual impact.
|
||||
// 3. less flakyness with selection and copying which **might** occur if
|
||||
// the textarea element is not visible.
|
||||
//
|
||||
// The likelihood is the element won't even render, not even a flash,
|
||||
// so some of these are just precautions. However in IE the element
|
||||
// is visible whilst the popup box asking the user for permission for
|
||||
// the web page to copy to the clipboard.
|
||||
//
|
||||
|
||||
// Place in top-left corner of screen regardless of scroll position.
|
||||
textArea.style.position = 'fixed';
|
||||
textArea.style.top = '0';
|
||||
textArea.style.left = '0';
|
||||
|
||||
// Ensure it has a small width and height. Setting to 1px / 1em
|
||||
// doesn't work as this gives a negative w/h on some browsers.
|
||||
textArea.style.width = '2em';
|
||||
textArea.style.height = '2em';
|
||||
|
||||
// We don't need padding, reducing the size if it does flash render.
|
||||
textArea.style.padding = '0';
|
||||
|
||||
// Clean up any borders.
|
||||
textArea.style.border = 'none';
|
||||
textArea.style.outline = 'none';
|
||||
textArea.style.boxShadow = 'none';
|
||||
|
||||
// Avoid flash of white box if rendered for any reason.
|
||||
textArea.style.background = 'transparent';
|
||||
|
||||
textArea.value = text;
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
let successful = document.execCommand('copy');
|
||||
if (!successful) {
|
||||
console.log('Failed copy to clipboard');
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('Failed copy to clipboard: ' + err);
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
Reference in New Issue
Block a user