(core) Copy column type and options when pasting into an empty column

Summary:
Adds a `data-grist-col-ref` attribute to the copied HTML, then uses that when pasting to look up the source column and retrieve info about it. Copies the info into the target column if:

- The document is the same (the docId hash matches)
- The source column still exists and has the same type as when copied
- The source type isn't Text, because in that case it's nice if type guessing still happens
- The target column is empty, meaning it has type Any (we check earlier that it's not a formula column)

The info copied is the type, widgetOptions, and reference column settings (visible and display columns) but not conditional formatting.

The changes are mostly in a function `parsePasteForView` which is based on `BaseView._parsePasteForView` but ported to TypeScript in a new file `BaseView2.ts`.

Added a useraction `MaybeCopyDisplayFormula` exposing an existing Python function `maybe_copy_display_formula` because the target column needs a slightly different display formula.

Test Plan: Added a new nbrowser test file and fixture doc.

Reviewers: cyprien

Reviewed By: cyprien

Subscribers: jarek, dsagal

Differential Revision: https://phab.getgrist.com/D3344
This commit is contained in:
Alex Hall
2022-04-01 22:14:41 +02:00
parent 6305811ca6
commit bf271c822b
7 changed files with 117 additions and 72 deletions

View File

@@ -14,6 +14,7 @@ var {CopySelection} = require('./CopySelection');
var RecordLayout = require('./RecordLayout');
var commands = require('./commands');
const {RowContextMenu} = require('../ui/RowContextMenu');
const {parsePasteForView} = require("./BaseView2");
/**
* DetailView component implements a list of record layouts.
@@ -131,7 +132,9 @@ DetailView.generalCommands = {
copy: function() { return this.copy(this.getSelection()); },
cut: function() { return this.cut(this.getSelection()); },
paste: function(pasteObj, cutCallback) { return this.paste(pasteObj, cutCallback); },
paste: function(pasteObj, cutCallback) {
return this.gristDoc.docData.bundleActions(null, () => this.paste(pasteObj, cutCallback));
},
editLayout: function() {
if (this.scrolly()) {
@@ -166,12 +169,12 @@ DetailView.prototype.deleteRow = function(index) {
* @param {Function} cutCallback - If provided returns the record removal action needed
* for a cut.
*/
DetailView.prototype.paste = function(data, cutCallback) {
DetailView.prototype.paste = async function(data, cutCallback) {
let pasteData = data[0][0];
let field = this.viewSection.viewFields().at(this.cursor.fieldIndex());
let isCompletePaste = (data.length === 1 && data[0].length === 1);
let richData = this._parsePasteForView([[pasteData]], [field]);
const richData = await parsePasteForView([[pasteData]], [field], this.gristDoc);
if (_.isEmpty(richData)) {
return;
}