mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(core) Guess numeric formatting options
Summary: Change NumberParse.parse to return not just the parsed number but also information it gathered along the way about how the input string was formatted. Use this in the new NumberParse.guessOptions to guess the actual widget options based on an array of strings. Use NumberParse.guessOptions in TypeConversion (for when a user explicitly chooses to change type) and in ValueGuesser (for guesses about strings entered into empty columns). Test Plan: Adds unit tests for NumberParse and ValueGuesser and updates the TypeChange2 nbrowser test. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3294
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
import {DocData} from 'app/common/DocData';
|
||||
import {DocumentSettings} from 'app/common/DocumentSettings';
|
||||
import {countIf} from 'app/common/gutil';
|
||||
import {NumberFormatOptions} from 'app/common/NumberFormat';
|
||||
import NumberParse from 'app/common/NumberParse';
|
||||
import {dateTimeWidgetOptions, guessDateFormat} from 'app/common/parseDate';
|
||||
import {createFormatter} from 'app/common/ValueFormatter';
|
||||
import {createParserRaw, ValueParser} from 'app/common/ValueParser';
|
||||
import * as moment from 'moment-timezone';
|
||||
|
||||
interface GuessedColInfo {
|
||||
@@ -9,7 +13,7 @@ interface GuessedColInfo {
|
||||
widgetOptions?: object;
|
||||
}
|
||||
|
||||
interface GuessResult {
|
||||
export interface GuessResult {
|
||||
values?: any[];
|
||||
colInfo: GuessedColInfo;
|
||||
}
|
||||
@@ -39,7 +43,8 @@ abstract class ValueGuesser<T> {
|
||||
const {type, widgetOptions} = colInfo;
|
||||
const formatter = createFormatter(type, widgetOptions || {}, docSettings);
|
||||
const result: any[] = [];
|
||||
const maxUnparsed = values.length * 0.1; // max number of non-parsed strings to allow before giving up
|
||||
// max number of non-parsed strings to allow before giving up
|
||||
const maxUnparsed = countIf(values, v => Boolean(v)) * 0.1;
|
||||
let unparsed = 0;
|
||||
|
||||
for (const value of values) {
|
||||
@@ -94,14 +99,22 @@ class BoolGuesser extends ValueGuesser<boolean> {
|
||||
}
|
||||
|
||||
class NumericGuesser extends ValueGuesser<number> {
|
||||
private _parser: ValueParser;
|
||||
constructor(docSettings: DocumentSettings, private _options: NumberFormatOptions) {
|
||||
super();
|
||||
this._parser = createParserRaw('Numeric', _options, docSettings);
|
||||
}
|
||||
|
||||
public colInfo(): GuessedColInfo {
|
||||
// TODO parse and guess options for formatted numbers, e.g. currency amounts
|
||||
return {type: 'Numeric'};
|
||||
const result: GuessedColInfo = {type: 'Numeric'};
|
||||
if (Object.keys(this._options).length) {
|
||||
result.widgetOptions = this._options;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public parse(value: string): number | string {
|
||||
const parsed = Number(value);
|
||||
return !isNaN(parsed) ? parsed : value;
|
||||
return this._parser.cleanParse(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +157,10 @@ export function guessColInfo(
|
||||
return (
|
||||
new BoolGuesser()
|
||||
.guess(values, docSettings) ||
|
||||
new NumericGuesser()
|
||||
new NumericGuesser(
|
||||
docSettings,
|
||||
NumberParse.fromSettings(docSettings).guessOptions(values)
|
||||
)
|
||||
.guess(values, docSettings) ||
|
||||
new DateGuesser(guessDateFormat(values, timezone) || "YYYY-MM-DD", timezone)
|
||||
.guess(values, docSettings) ||
|
||||
|
||||
Reference in New Issue
Block a user