insert multiple JSON documents

This commit is contained in:
Jan Prochazka 2021-12-02 15:20:56 +01:00
parent 5180e7ad27
commit 7575b59f4f
7 changed files with 97 additions and 37 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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 @@
<ErrorInfo message={errorMessage} alignTop />
{:else if isDynamicStructure && isLoadedAll && grider?.rowCount == 0}
<div>
<ErrorInfo alignTop message="No rows loaded, check filter or add new documents" />
<ErrorInfo alignTop message="No rows loaded, check filter or add new documents. You could copy documents from ohter collections/tables with Copy advanved/Copy as JSON command." />
{#if display.filterCount > 0}
<FormStyledButton value="Reset filter" on:click={() => display.clearFilters()} />
{/if}

View File

@ -22,6 +22,9 @@ export default abstract class Grider {
insertRow(): number {
return null;
}
insertDocuments(documents: any[]): number {
return null;
}
revertRowChanges(index: number) {}
revertAllChanges() {}
undo() {}

View File

@ -47,6 +47,15 @@ export default class FreeTableGrider extends Grider {
};
return this.currentModel.rows.length - 1;
}
insertDocuments(documents: any[]): number {
const model = this.currentModel;
this.currentModel = {
...model,
rows: [...model.rows, ...documents],
};
return this.currentModel.rows.length - documents.length;
}
deleteRow(index: number) {
const model = this.currentModel;
this.currentModel = {

View File

@ -56,6 +56,7 @@
import EditJsonModal from '../modals/EditJsonModal.svelte';
import ChangeSetGrider from '../datagrid/ChangeSetGrider';
import { setContext } from 'svelte';
import _ from 'lodash';
export let tabid;
export let conid;
@ -139,8 +140,7 @@
json: {},
onSave: value => {
const grider = new ChangeSetGrider(loadedRows, $changeSetStore, dispatchChangeSet, display);
const newRowIndex = grider.insertRow();
grider.setRowData(newRowIndex, value);
grider.insertDocuments(_.isArray(value) ? value : [value]);
return true;
},
});