gristlabs_grist-core/app/client/components/CopySelection.ts
Alex Hall c470c4041b (core) Use visibleCol instead of displayCol with createFormatter
Summary:
Some things (like rendering cells) use the `visibleCol` for `createFormatter`, while other things (like `CopySelection`) used the `displayCol`. For references, the display column has type Any and doesn't know about the original formatting. This resulted in formatting being lost when copying from reference columns even though formatting was preserved when copying from the original (visible) column which looked identical. This diff fixes this and ensures that `createFormatter` is always used with the `visibleCol`. This was agreed on in https://grist.slack.com/archives/C0234CPPXPA/p1639571321043000

Additionally:

- Replaces the functions `createVisibleColFormatter` computed properties `visibleColFormatter` as suggested by a `TODO`.
- Extracts common code from `createVisibleColFormatter` in `ColumnRec` and `ViewFieldRec`

Test Plan: Fixed a test in CopyPaste which displayed the previous inconsistent behaviour.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D3189
2021-12-16 22:19:36 +02:00

56 lines
2.1 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 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.visibleColFormatter();
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";
}
}