mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Add ValueParser, use when pasting
Summary: Add ValueParser file, base class, and subclasses for column types. Only NumericParser is used for now. Add valueParser field to ViewFieldRec. Use valueParser when parsing pasted text data in Grid and Detail views. Test Plan: Add test to nbrowser CopyPaste suite, copying into a numeric column with different currency and locale settings. Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D3082
This commit is contained in:
@@ -356,29 +356,40 @@ BaseView.prototype.insertRow = function(index) {
|
||||
* @returns {Object} - Object mapping colId to array of column values, suitable for use in Bulk
|
||||
* actions.
|
||||
*/
|
||||
BaseView.prototype._parsePasteForView = function(data, cols) {
|
||||
let updateCols = cols.map(col => {
|
||||
BaseView.prototype._parsePasteForView = function(data, fields) {
|
||||
const updateCols = fields.map(field => {
|
||||
const col = field && field.column();
|
||||
if (col && !col.isRealFormula() && !col.disableEditData()) {
|
||||
return col;
|
||||
} else {
|
||||
return null; // Don't include formulas and missing columns
|
||||
}
|
||||
});
|
||||
let updateColIds = updateCols.map(c => c && c.colId());
|
||||
let updateColTypes = updateCols.map(c => c && c.type());
|
||||
const updateColIds = updateCols.map(c => c && c.colId());
|
||||
const updateColTypes = updateCols.map(c => c && c.type());
|
||||
const parsers = fields.map(field => field && field.valueParser() || (x => x));
|
||||
|
||||
let richData = data;
|
||||
|
||||
if (data.length > 0 && data[0].length > 0 &&
|
||||
_.isObject(data[0][0]) && data[0][0].hasOwnProperty('displayValue')) {
|
||||
richData = data.map((col, idx) => {
|
||||
if (col[0].colType === updateColTypes[idx]) {
|
||||
return col.map(v => v && v.hasOwnProperty('rawValue') ? v.rawValue : v.displayValue);
|
||||
} else {
|
||||
return col.map(v => v && v.displayValue);
|
||||
const richData = data.map((col, idx) => {
|
||||
if (!col.length) {
|
||||
return col;
|
||||
}
|
||||
const typeMatches = col[0].colType === updateColTypes[idx];
|
||||
const parser = parsers[idx];
|
||||
return col.map(v => {
|
||||
if (v) {
|
||||
if (typeMatches && v.hasOwnProperty('rawValue')) {
|
||||
return v.rawValue;
|
||||
}
|
||||
if (v.hasOwnProperty('displayValue')) {
|
||||
return parser(v.displayValue);
|
||||
}
|
||||
if (typeof v === "string") {
|
||||
return parser(v);
|
||||
}
|
||||
}
|
||||
return v;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return _.omit(_.object(updateColIds, richData), null);
|
||||
};
|
||||
|
||||
@@ -167,10 +167,10 @@ DetailView.prototype.deleteRow = function(index) {
|
||||
*/
|
||||
DetailView.prototype.paste = function(data, cutCallback) {
|
||||
let pasteData = data[0][0];
|
||||
let col = this.currentColumn();
|
||||
let field = this.viewSection.viewFields().at(this.cursor.fieldIndex());
|
||||
let isCompletePaste = (data.length === 1 && data[0].length === 1);
|
||||
|
||||
let richData = this._parsePasteForView([[pasteData]], [col]);
|
||||
let richData = this._parsePasteForView([[pasteData]], [field]);
|
||||
if (_.isEmpty(richData)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -355,9 +355,9 @@ GridView.prototype.paste = function(data, cutCallback) {
|
||||
pasteData = gutil.growMatrix(pasteData, updateColIndices.length, updateRowIds.length);
|
||||
|
||||
let fields = this.viewSection.viewFields().peek();
|
||||
let pasteCols = updateColIndices.map(i => fields[i] && fields[i].column() || null);
|
||||
let pasteFields = updateColIndices.map(i => fields[i] || null);
|
||||
|
||||
let richData = this._parsePasteForView(pasteData, pasteCols);
|
||||
let richData = this._parsePasteForView(pasteData, pasteFields);
|
||||
let actions = this._createBulkActionsFromPaste(updateRowIds, richData);
|
||||
|
||||
if (actions.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user