diff --git a/packages/datalib/src/ChangeSet.ts b/packages/datalib/src/ChangeSet.ts
index a063bb160..a46f5935e 100644
--- a/packages/datalib/src/ChangeSet.ts
+++ b/packages/datalib/src/ChangeSet.ts
@@ -390,6 +390,25 @@ export function changeSetInsertNewRow(changeSet: ChangeSet, name?: NamedObjectIn
};
}
+export function changeSetInsertDocuments(
+ changeSet: ChangeSet,
+ documents: any[],
+ name?: NamedObjectInfo
+): ChangeSet {
+ const insertedRows = getChangeSetInsertedRows(changeSet, name);
+ return {
+ ...changeSet,
+ inserts: [
+ ...changeSet.inserts,
+ ...documents.map((doc, index) => ({
+ ...name,
+ insertedRowIndex: insertedRows.length + index,
+ fields: doc,
+ })),
+ ],
+ };
+}
+
export function changeSetContainsChanges(changeSet: ChangeSet) {
if (!changeSet) return false;
return changeSet.deletes.length > 0 || changeSet.updates.length > 0 || changeSet.inserts.length > 0;
diff --git a/packages/datalib/src/CollectionGridDisplay.ts b/packages/datalib/src/CollectionGridDisplay.ts
index 133490238..74dfe747d 100644
--- a/packages/datalib/src/CollectionGridDisplay.ts
+++ b/packages/datalib/src/CollectionGridDisplay.ts
@@ -98,8 +98,9 @@ export class CollectionGridDisplay extends GridDisplay {
changeSet
) {
super(config, setConfig, cache, setCache, driver);
- const changedDocs = _.compact([...changeSet.inserts, ...changeSet.updates].map(chs => chs.document));
- this.columns = analyseCollectionDisplayColumns([...(loadedRows || []), ...changedDocs], this);
+ const changedDocs = _.compact(changeSet.updates.map(chs => chs.document));
+ const insertedDocs = _.compact(changeSet.inserts.map(chs => chs.fields));
+ this.columns = analyseCollectionDisplayColumns([...(loadedRows || []), ...changedDocs, ...insertedDocs], this);
this.filterable = true;
this.sortable = true;
this.editable = true;
diff --git a/packages/web/src/datagrid/ChangeSetGrider.ts b/packages/web/src/datagrid/ChangeSetGrider.ts
index 591a9d984..b74b8d3f0 100644
--- a/packages/web/src/datagrid/ChangeSetGrider.ts
+++ b/packages/web/src/datagrid/ChangeSetGrider.ts
@@ -14,6 +14,7 @@ import {
setChangeSetRowData,
compileMacroFunction,
runMacroOnValue,
+ changeSetInsertDocuments,
} from 'dbgate-datalib';
import Grider, { GriderRowStatus } from './Grider';
@@ -181,6 +182,12 @@ export default class ChangeSetGrider extends Grider {
return res;
}
+ insertDocuments(documents: any[]): number {
+ const res = this.rowCountInUpdate;
+ this.applyModification(chs => changeSetInsertDocuments(chs, documents, this.display.baseTableOrCollection));
+ return res;
+ }
+
beginUpdate() {
this.batchChangeSet = this.changeSet;
}
diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte
index da193a886..6cbec73cc 100644
--- a/packages/web/src/datagrid/DataGridCore.svelte
+++ b/packages/web/src/datagrid/DataGridCore.svelte
@@ -1094,7 +1094,7 @@
return [row, col];
}
- function handlePaste(event) {
+ async function handlePaste(event) {
var pastedText = undefined;
// @ts-ignore
if (window.clipboardData && window.clipboardData.getData) {
@@ -1105,41 +1105,62 @@
pastedText = event.clipboardData.getData('text/plain');
}
event.preventDefault();
- grider.beginUpdate();
- const pasteRows = pastedText
- .replace(/\r/g, '')
- .split('\n')
- .map(row => row.split('\t'));
- const selectedRegular = cellsToRegularCells(selectedCells);
- if (selectedRegular.length <= 1) {
- const startRow = isRegularCell(currentCell) ? currentCell[0] : grider.rowCount;
- const startCol = isRegularCell(currentCell) ? currentCell[1] : 0;
- let rowIndex = startRow;
- for (const rowData of pasteRows) {
- if (rowIndex >= grider.rowCountInUpdate) {
- grider.insertRow();
- }
- let colIndex = startCol;
- for (const cell of rowData) {
- setCellValue([rowIndex, colIndex], cell == '(NULL)' ? null : cell);
- colIndex += 1;
- }
- rowIndex += 1;
+
+ let json = null;
+ if (grider.canInsert) {
+ try {
+ json = JSON.parse(pastedText);
+ } catch (e) {
+ json = null;
}
}
- if (selectedRegular.length > 1) {
- const startRow: number = _.min(selectedRegular.map(x => x[0]));
- const startCol: number = _.min(selectedRegular.map(x => x[1]));
- for (const cell of selectedRegular) {
- const [rowIndex, colIndex] = cell;
- const selectionRow = rowIndex - startRow;
- const selectionCol = colIndex - startCol;
- const pasteRow = pasteRows[selectionRow % pasteRows.length];
- const pasteCell = pasteRow[selectionCol % pasteRow.length];
- setCellValue(cell, pasteCell);
+
+ if (json && (_.isArray(json) || _.isPlainObject(json))) {
+ const rowIndex = grider.insertDocuments(_.isArray(json) ? json : [json]);
+ const cell = [rowIndex, (currentCell && currentCell[1]) || 0];
+ // @ts-ignore
+ currentCell = cell;
+ // @ts-ignore
+ selectedCells = [cell];
+ await tick();
+ scrollIntoView(cell);
+ } else {
+ grider.beginUpdate();
+ const pasteRows = pastedText
+ .replace(/\r/g, '')
+ .split('\n')
+ .map(row => row.split('\t'));
+ const selectedRegular = cellsToRegularCells(selectedCells);
+ if (selectedRegular.length <= 1) {
+ const startRow = isRegularCell(currentCell) ? currentCell[0] : grider.rowCount;
+ const startCol = isRegularCell(currentCell) ? currentCell[1] : 0;
+ let rowIndex = startRow;
+ for (const rowData of pasteRows) {
+ if (rowIndex >= grider.rowCountInUpdate) {
+ grider.insertRow();
+ }
+ let colIndex = startCol;
+ for (const cell of rowData) {
+ setCellValue([rowIndex, colIndex], cell == '(NULL)' ? null : cell);
+ colIndex += 1;
+ }
+ rowIndex += 1;
+ }
}
+ if (selectedRegular.length > 1) {
+ const startRow: number = _.min(selectedRegular.map(x => x[0]));
+ const startCol: number = _.min(selectedRegular.map(x => x[1]));
+ for (const cell of selectedRegular) {
+ const [rowIndex, colIndex] = cell;
+ const selectionRow = rowIndex - startRow;
+ const selectionCol = colIndex - startCol;
+ const pasteRow = pasteRows[selectionRow % pasteRows.length];
+ const pasteCell = pasteRow[selectionCol % pasteRow.length];
+ setCellValue(cell, pasteCell);
+ }
+ }
+ grider.endUpdate();
}
- grider.endUpdate();
}
function cellsToRegularCells(cells) {
@@ -1296,7 +1317,7 @@