/** * This file contains logic moved from BaseView.js and ported to TS. */ import {GristDoc} from 'app/client/components/GristDoc'; import {getDocIdHash, RichPasteObject} from 'app/client/lib/tableUtil'; import {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec'; import {UserAction} from 'app/common/DocActions'; import {isFullReferencingType} from 'app/common/gristTypes'; import {SchemaTypes} from 'app/common/schema'; import {BulkColValues} from 'app/plugin/GristData'; import omit = require('lodash/omit'); /** * Given a 2-d paste column-oriented paste data and target cols, transform the data to omit * fields that shouldn't be pasted over and extract rich paste data if available. * When pasting into empty columns, also update them with options from the source column. * `data` is a column-oriented 2-d array of either * plain strings or rich paste data returned by `tableUtil.parsePasteHtml`. * `fields` are the target fields being pasted into. */ export async function parsePasteForView( data: Array[], fields: ViewFieldRec[], gristDoc: GristDoc ): Promise { const result: BulkColValues = {}; const actions: UserAction[] = []; const thisDocIdHash = getDocIdHash(); data.forEach((col, idx) => { const field = fields[idx]; const colRec = field?.column(); if (!colRec || colRec.isRealFormula() || colRec.disableEditData()) { return; } const parser = field.createValueParser() || (x => x); let typeMatches = false; if (col[0] && typeof col[0] === "object") { const {colType, docIdHash, colRef} = col[0]; const targetType = colRec.type(); const docIdMatches = docIdHash === thisDocIdHash; typeMatches = docIdMatches || !isFullReferencingType(colType || ""); if (targetType !== "Any") { typeMatches = typeMatches && colType === targetType; } else if (docIdMatches && colRef) { // Try copying source column type and options into empty columns const sourceColRec = gristDoc.docModel.columns.getRowModel(colRef); const sourceType = sourceColRec.type(); // Check that the source column still exists, has a type other than Text, and the type hasn't changed. // For Text columns, we don't copy over column info so that type guessing can still happen. if (sourceColRec.getRowId() && sourceType !== "Text" && sourceType === colType) { const colInfo: Partial = { type: sourceType, visibleCol: sourceColRec.visibleCol(), // Conditional formatting rules are not copied right now, that's a bit more complicated // and copying the formula may or may not be desirable. widgetOptions: JSON.stringify(omit(sourceColRec.widgetOptionsJson(), "rulesOptions")), }; actions.push( ["UpdateRecord", "_grist_Tables_column", colRec.getRowId(), colInfo], ["MaybeCopyDisplayFormula", colRef, colRec.getRowId()], ); } } } result[colRec.colId()] = col.map(v => { if (v) { if (typeof v === "string") { return parser(v); } if (typeMatches && v.hasOwnProperty('rawValue')) { return v.rawValue; } if (v.hasOwnProperty('displayValue')) { return parser(v.displayValue); } } return v; }); }); if (actions.length) { await gristDoc.docData.sendActions(actions); } return result; }