gristlabs_grist-core/app/client/components/FieldConfigTab.js

170 lines
5.7 KiB
JavaScript
Raw Normal View History

var ko = require('knockout');
var dispose = require('../lib/dispose');
var dom = require('../lib/dom');
var kd = require('../lib/koDom');
var kf = require('../lib/koForm');
var modelUtil = require('../models/modelUtil');
var gutil = require('app/common/gutil');
var AceEditor = require('./AceEditor');
var RefSelect = require('./RefSelect');
const {dom: grainjsDom, makeTestId} = require('grainjs');
const testId = makeTestId('test-fconfigtab-');
function FieldConfigTab(options) {
this.gristDoc = options.gristDoc;
this.fieldBuilder = options.fieldBuilder;
this.origColRef = this.autoDispose(ko.computed(() =>
this.fieldBuilder() ? this.fieldBuilder().origColumn.origColRef() : null));
this.isColumnValid = this.autoDispose(ko.computed(() => Boolean(this.origColRef())));
this.origColumn = this.autoDispose(
this.gristDoc.docModel.columns.createFloatingRowModel(this.origColRef));
this.disableModify = this.autoDispose(ko.computed(() =>
this.origColumn.disableModify() || this.origColumn.isTransforming()));
this.colId = modelUtil.customComputed({
read: () => this.origColumn.colId(),
save: val => this.origColumn.colId.saveOnly(val)
});
this.showColId = this.autoDispose(ko.pureComputed({
read: () => {
let label = this.origColumn.label();
let derivedColId = label ? gutil.sanitizeIdent(label) : null;
return derivedColId === this.colId() && !this.origColumn.untieColIdFromLabel();
}
}));
this.isDerivedFromLabel = this.autoDispose(ko.pureComputed({
read: () => !this.origColumn.untieColIdFromLabel(),
write: newValue => this.origColumn.untieColIdFromLabel.saveOnly(!newValue)
}));
// Indicates whether this is a ref col that references a different table.
this.isForeignRefCol = this.autoDispose(ko.pureComputed(() => {
let type = this.origColumn.type();
return type && gutil.startsWith(type, 'Ref:') &&
this.origColumn.table().tableId() !== gutil.removePrefix(type, 'Ref:');
}));
// Create an instance of AceEditor that can be built for each column
this.formulaEditor = this.autoDispose(AceEditor.create({observable: this.origColumn.formula}));
// Builder for the reference display column multiselect.
this.refSelect = this.autoDispose(RefSelect.create(this));
if (options.contentCallback) {
options.contentCallback(this.buildConfigDomObj());
} else {
this.autoDispose(this.gristDoc.addOptionsTab(
'Field', dom('span.glyphicon.glyphicon-sort-by-attributes'),
this.buildConfigDomObj(),
{ 'category': 'options', 'show': this.fieldBuilder }
));
}
}
dispose.makeDisposable(FieldConfigTab);
// Builds object with FieldConfigTab dom builder and settings for the sidepane.
// TODO: Field still cannot be filtered/filter settings cannot be opened from FieldConfigTab.
// This should be considered.
FieldConfigTab.prototype.buildConfigDomObj = function() {
return [{
'buildDom': this._buildNameDom.bind(this),
'keywords': ['field', 'column', 'name', 'title']
}, {
'header': true,
'items': [{
'buildDom': this._buildFormulaDom.bind(this),
'keywords': ['field', 'column', 'formula']
}]
}, {
'header': true,
'label': 'Format Cells',
'items': [{
'buildDom': this._buildFormatDom.bind(this),
'keywords': ['field', 'type', 'widget', 'options', 'alignment', 'justify', 'justification']
}]
}, {
'header': true,
'label': 'Additional Columns',
'showObs': this.isForeignRefCol,
'items': [{
'buildDom': () => this.refSelect.buildDom(),
'keywords': ['additional', 'columns', 'reference', 'formula']
}]
}, {
'header': true,
'label': 'Transform',
'items': [{
'buildDom': this._buildTransformDom.bind(this),
'keywords': ['field', 'type']
}]
}];
};
FieldConfigTab.prototype._buildNameDom = function() {
return grainjsDom.maybe(this.isColumnValid, () => dom('div',
kf.row(
1, dom('div.glyphicon.glyphicon-sort-by-attributes.config_icon'),
4, kf.label('Field'),
13, kf.text(this.origColumn.label, { disabled: this.disableModify },
dom.testId("FieldConfigTab_fieldLabel"),
testId('field-label'))
),
kf.row(
kd.hide(this.showColId),
1, dom('div.glyphicon.glyphicon-tag.config_icon'),
4, kf.label('ID'),
13, kf.text(this.colId, { disabled: this.disableModify },
dom.testId("FieldConfigTab_colId"),
testId('field-col-id'))
),
kf.row(
8, kf.lightLabel("Use Name as ID?"),
1, kf.checkbox(this.isDerivedFromLabel,
dom.testId("FieldConfigTab_deriveId"),
testId('field-derive-id'))
)
));
};
FieldConfigTab.prototype._buildFormulaDom = function() {
return grainjsDom.maybe(this.isColumnValid, () => dom('div',
kf.row(
3, kf.buttonGroup(
kf.checkButton(this.origColumn.isFormula,
dom('span.formula_button_f', '\u0192'),
dom('span.formula_button_x', 'x'),
kd.toggleClass('disabled', this.disableModify),
{ title: 'Change to formula column' }
)
),
15, dom('div.transform_editor', this.formulaEditor.buildDom())
),
kf.helpRow(
3, dom('span'),
15, kf.lightLabel(kd.text(
() => this.origColumn.isFormula() ? 'Formula' : 'Default Formula'))
)
));
};
FieldConfigTab.prototype._buildTransformDom = function() {
return grainjsDom.maybe(this.fieldBuilder, builder => builder.buildTransformDom());
};
FieldConfigTab.prototype._buildFormatDom = function() {
return grainjsDom.maybe(this.fieldBuilder, builder => [
builder.buildSelectTypeDom(),
builder.buildSelectWidgetDom(),
builder.buildConfigDom()
]);
};
module.exports = FieldConfigTab;