gristlabs_grist-core/app/client/components/CopySelection.ts
Alex Hall bf271c822b (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
2022-04-04 14:53:16 +02:00

57 lines
2.2 KiB
TypeScript

import type {ViewFieldRec} from 'app/client/models/entities/ViewFieldRec';
import type {CellValue} from 'app/common/DocActions';
import type {TableData} from 'app/common/TableData';
import type {UIRowId} from 'app/common/UIRowId';
/**
* The CopySelection class is an abstraction for a subset of currently selected cells.
* @param {Array} rowIds - row ids of the rows selected
* @param {Array} fields - MetaRowModels of the selected view fields
* @param {Object} options.rowStyle - an object that maps rowId to an object containing
* style options. i.e. { 1: { height: 20px } }
* @param {Object} options.colStyle - an object that maps colId to an object containing
* style options.
*/
export class CopySelection {
public readonly colIds = this.fields.map(f => f.colId());
public readonly colRefs = this.fields.map(f => f.colRef());
public readonly displayColIds = this.fields.map(f => f.displayColModel().colId());
public readonly rowStyle: {[r: number]: object}|undefined;
public readonly colStyle: {[c: string]: object}|undefined;
public readonly columns: Array<{
colId: string,
fmtGetter: (rowId: UIRowId) => string,
rawGetter: (rowId: UIRowId) => CellValue|undefined,
}>;
constructor(tableData: TableData, public readonly rowIds: UIRowId[], public readonly fields: ViewFieldRec[],
options: {
rowStyle?: {[r: number]: object},
colStyle?: {[c: string]: object},
}
) {
this.rowStyle = options.rowStyle;
this.colStyle = options.colStyle;
this.columns = fields.map((f, i) => {
const formatter = f.formatter();
const _fmtGetter = tableData.getRowPropFunc(this.displayColIds[i])!;
const _rawGetter = tableData.getRowPropFunc(this.colIds[i])!;
return {
colId: this.colIds[i],
fmtGetter: rowId => formatter.formatAny(_fmtGetter(rowId)),
rawGetter: rowId => _rawGetter(rowId)
};
});
}
public isCellSelected(rowId: UIRowId, colId: string): boolean {
return this.rowIds.includes(rowId) && this.colIds.includes(colId);
}
public onlyAddRowSelected(): boolean {
return this.rowIds.length === 1 && this.rowIds[0] === "new";
}
}