(core) Reference and ReferenceList formatters

Summary:
Previously, ref/reflist columns were formatted entirely based on their visible column, since they received values from the visible or display columns rather than the actual row IDs. This creates `ReferenceFormatter` and `ReferenceListFormatter` which still delegate most of the formatting work to a visible column formatter but fix a few issues:

- ReferenceList columns now actually use the options (e.g. date format) of the visible column to format their elements. Previously they were formatted generically because the visible column formatter wasn't expecting a list.
- Invalid references aren't formatted with an `#Invalid Ref` prefix.
- When the ref column displays the Row ID, it doesn't have a visible or display column. Previously this led to the references being formatted as just numbers in most cases, with special code in the widget to display them like `Table1[2]`. Now they are consistently formatted in that style throughout.

Test Plan: Updated existing tests.

Reviewers: jarek

Reviewed By: jarek

Subscribers: dsagal

Differential Revision: https://phab.getgrist.com/D3212
This commit is contained in:
Alex Hall
2022-01-13 12:04:56 +02:00
parent 85ef873ce5
commit 8f531ef622
13 changed files with 158 additions and 46 deletions

View File

@@ -12,8 +12,6 @@ import {Computed, dom, styled} from 'grainjs';
* Reference - The widget for displaying references to another table's records.
*/
export class Reference extends NTextBox {
protected _formatValue: Computed<(val: any) => string>;
private _visibleColRef: Computed<number>;
private _validCols: Computed<Array<IOptionFull<number>>>;
@@ -37,19 +35,6 @@ export class Reference extends NTextBox {
}))
.concat([{label: 'Row ID', value: 0, icon: 'FieldColumn'}]);
});
// Computed returns a function that formats cell values.
this._formatValue = Computed.create(this, (use) => {
// If the field is pulling values from a display column, use a general-purpose formatter.
if (use(this.field.displayColRef) !== use(this.field.colRef)) {
const fmt = use(this.field.visibleColFormatter);
return (val: any) => fmt.formatAny(val);
} else {
const refTable = use(use(this.field.column).refTable);
const refTableId = refTable ? use(refTable.tableId) : "";
return (val: any) => val > 0 ? `${refTableId}[${val}]` : "";
}
});
}
public buildConfigDom() {
@@ -100,8 +85,8 @@ export class Reference extends NTextBox {
// but the content of its displayCol has changed. Postponing doing anything about
// this until we have three-way information for computed columns. For now,
// just showing one version of the cell. TODO: elaborate.
use(this._formatValue)(displayValue[1].local || displayValue[1].parent) :
use(this._formatValue)(displayValue);
use(this.field.formatter).formatAny(displayValue[1].local || displayValue[1].parent) :
use(this.field.formatter).formatAny(displayValue);
hasBlankReference = referenceId.get() !== 0 && value.trim() === '';