mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
1654a2681f
Summary: This moves all client code to core, and makes minimal fix-ups to get grist and grist-core to compile correctly. The client works in core, but I'm leaving clean-up around the build and bundles to follow-up. Test Plan: existing tests pass; server-dev bundle looks sane Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2627
113 lines
4.0 KiB
JavaScript
113 lines
4.0 KiB
JavaScript
var _ = require('underscore');
|
|
var ko = require('knockout');
|
|
|
|
var gutil = require('app/common/gutil');
|
|
|
|
var dispose = require('../lib/dispose');
|
|
var dom = require('../lib/dom');
|
|
var kd = require('../lib/koDom');
|
|
|
|
var TextBox = require('./TextBox');
|
|
|
|
const {colors, testId} = require('app/client/ui2018/cssVars');
|
|
const {icon} = require('app/client/ui2018/icons');
|
|
const {select} = require('app/client/ui2018/menus');
|
|
const {cssLabel, cssRow} = require('app/client/ui/RightPanel');
|
|
const {isVersions} = require('app/common/gristTypes');
|
|
const {Computed, styled} = require('grainjs');
|
|
|
|
/**
|
|
* Reference - The widget for displaying references to another table's records.
|
|
*/
|
|
function Reference(field) {
|
|
TextBox.call(this, field);
|
|
var col = field.column();
|
|
this.field = field;
|
|
this.colId = col.colId;
|
|
this.docModel = this.field._table.docModel;
|
|
|
|
this._refValueFormatter = this.autoDispose(ko.computed(() =>
|
|
field.createVisibleColFormatter()));
|
|
|
|
this._visibleColRef = Computed.create(this, (use) => use(this.field.visibleColRef));
|
|
// Note that saveOnly is used here to prevent display value flickering on visible col change.
|
|
this._visibleColRef.onWrite((val) => this.field.visibleColRef.saveOnly(val));
|
|
|
|
this._validCols = Computed.create(this, (use) => {
|
|
const refTable = use(use(this.field.column).refTable);
|
|
if (!refTable) { return []; }
|
|
return use(use(refTable.columns))
|
|
.filter(col => !use(col.isHiddenCol))
|
|
.map(col => ({
|
|
label: use(col.label),
|
|
value: col.getRowId(),
|
|
icon: 'FieldColumn',
|
|
disabled: gutil.startsWith(use(col.type), 'Ref:') || use(col.isTransforming)
|
|
}))
|
|
.concat([{label: 'Row ID', value: 0, icon: 'FieldColumn'}]);
|
|
});
|
|
|
|
// Computed returns a function that formats cell values.
|
|
this._formatValue = this.autoDispose(ko.computed(() => {
|
|
// If the field is pulling values from a display column, use a general-purpose formatter.
|
|
if (this.field.displayColRef() !== this.field.colRef()) {
|
|
const fmt = this._refValueFormatter();
|
|
return (val) => fmt.formatAny(val);
|
|
} else {
|
|
const refTable = this.field.column().refTable();
|
|
const refTableId = refTable ? refTable.tableId() : "";
|
|
return (val) => val > 0 ? `${refTableId}[${val}]` : "";
|
|
}
|
|
}));
|
|
}
|
|
dispose.makeDisposable(Reference);
|
|
_.extend(Reference.prototype, TextBox.prototype);
|
|
|
|
Reference.prototype.buildConfigDom = function() {
|
|
return [
|
|
cssLabel('SHOW COLUMN'),
|
|
cssRow(
|
|
select(this._visibleColRef, this._validCols),
|
|
testId('fbuilder-ref-col-select')
|
|
)
|
|
];
|
|
};
|
|
|
|
Reference.prototype.buildTransformConfigDom = function() {
|
|
return this.buildConfigDom();
|
|
};
|
|
|
|
Reference.prototype.buildDom = function(row, options) {
|
|
const formattedValue = ko.computed(() => {
|
|
if (row._isAddRow() || this.isDisposed() || this.field.displayColModel().isDisposed()) {
|
|
// Work around JS errors during certain changes (noticed when visibleCol field gets removed
|
|
// for a column using per-field settings).
|
|
return "";
|
|
}
|
|
const value = row.cells[this.field.displayColModel().colId()];
|
|
if (!value) { return ""; }
|
|
const content = value();
|
|
if (isVersions(content)) {
|
|
// We can arrive here if the reference value is unchanged (viewed as a foreign key)
|
|
// 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.
|
|
return this._formatValue()(content[1].local || content[1].parent);
|
|
}
|
|
return this._formatValue()(content);
|
|
});
|
|
return dom('div.field_clip',
|
|
dom.autoDispose(formattedValue),
|
|
cssRefIcon('FieldReference',
|
|
testId('ref-link-icon')
|
|
),
|
|
kd.text(formattedValue));
|
|
};
|
|
|
|
const cssRefIcon = styled(icon, `
|
|
background-color: ${colors.slate};
|
|
margin: -1px 2px 2px 0;
|
|
`);
|
|
|
|
module.exports = Reference;
|