2021-11-19 18:54:42 +00:00
|
|
|
import {csvDecodeRow} from 'app/common/csvFormat';
|
|
|
|
import {DocumentSettings} from 'app/common/DocumentSettings';
|
2021-10-21 18:50:49 +00:00
|
|
|
import * as gristTypes from 'app/common/gristTypes';
|
|
|
|
import * as gutil from 'app/common/gutil';
|
2021-11-19 18:54:42 +00:00
|
|
|
import {safeJsonParse} from 'app/common/gutil';
|
|
|
|
import {getCurrency, NumberFormatOptions} from 'app/common/NumberFormat';
|
2021-10-21 18:50:49 +00:00
|
|
|
import NumberParse from 'app/common/NumberParse';
|
2021-11-24 22:48:37 +00:00
|
|
|
import {parseDateStrict, parseDateTime} from 'app/common/parseDate';
|
2021-11-19 18:54:42 +00:00
|
|
|
import {DateFormatOptions, DateTimeFormatOptions, formatDecoded, FormatOptions} from 'app/common/ValueFormatter';
|
|
|
|
import flatMap = require('lodash/flatMap');
|
2021-10-21 18:50:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
export class ValueParser {
|
|
|
|
constructor(public type: string, public widgetOpts: object, public docSettings: DocumentSettings) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public cleanParse(value: string): any {
|
|
|
|
if (!value) {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
return this.parse(value) ?? value;
|
|
|
|
}
|
|
|
|
|
|
|
|
public parse(value: string): any {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export class NumericParser extends ValueParser {
|
|
|
|
private _parse: NumberParse;
|
|
|
|
|
|
|
|
constructor(type: string, options: NumberFormatOptions, docSettings: DocumentSettings) {
|
|
|
|
super(type, options, docSettings);
|
|
|
|
this._parse = new NumberParse(docSettings.locale, getCurrency(options, docSettings));
|
|
|
|
}
|
|
|
|
|
|
|
|
public parse(value: string): number | null {
|
|
|
|
return this._parse.parse(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class DateParser extends ValueParser {
|
|
|
|
public parse(value: string): any {
|
2021-10-25 17:42:06 +00:00
|
|
|
return parseDateStrict(value, (this.widgetOpts as DateFormatOptions).dateFormat!);
|
2021-10-21 18:50:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-24 22:48:37 +00:00
|
|
|
class DateTimeParser extends ValueParser {
|
2021-10-21 18:50:49 +00:00
|
|
|
constructor(type: string, widgetOpts: DateTimeFormatOptions, docSettings: DocumentSettings) {
|
|
|
|
super(type, widgetOpts, docSettings);
|
|
|
|
const timezone = gutil.removePrefix(type, "DateTime:") || '';
|
|
|
|
this.widgetOpts = {...widgetOpts, timezone};
|
|
|
|
}
|
2021-11-24 22:48:37 +00:00
|
|
|
|
|
|
|
public parse(value: string): any {
|
|
|
|
return parseDateTime(value, this.widgetOpts);
|
|
|
|
}
|
2021-10-21 18:50:49 +00:00
|
|
|
}
|
|
|
|
|
2021-11-19 18:54:42 +00:00
|
|
|
|
|
|
|
class ChoiceListParser extends ValueParser {
|
|
|
|
public cleanParse(value: string): string[] | null {
|
|
|
|
value = value.trim();
|
|
|
|
const result = (
|
|
|
|
this._parseJson(value) ||
|
|
|
|
this._parseCsv(value)
|
|
|
|
).map(v => v.trim())
|
|
|
|
.filter(v => v);
|
|
|
|
if (!result.length) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
return ["L", ...result];
|
|
|
|
}
|
|
|
|
|
|
|
|
private _parseJson(value: string): string[] | undefined {
|
|
|
|
// Don't parse JSON non-arrays
|
|
|
|
if (value[0] === "[") {
|
|
|
|
const arr: unknown[] | null = safeJsonParse(value, null);
|
|
|
|
return arr
|
|
|
|
// Remove nulls and empty strings
|
|
|
|
?.filter(v => v || v === 0)
|
|
|
|
// Convert values to strings, formatting nested JSON objects/arrays as JSON
|
|
|
|
.map(v => formatDecoded(v));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private _parseCsv(value: string): string[] {
|
|
|
|
// Split everything on newlines which are not allowed by the choice editor.
|
|
|
|
return flatMap(value.split(/[\n\r]+/), row => {
|
|
|
|
return csvDecodeRow(row)
|
|
|
|
.map(v => v.trim());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 18:50:49 +00:00
|
|
|
const parsers: { [type: string]: typeof ValueParser } = {
|
|
|
|
Numeric: NumericParser,
|
|
|
|
Int: NumericParser,
|
|
|
|
Date: DateParser,
|
|
|
|
DateTime: DateTimeParser,
|
2021-11-19 18:54:42 +00:00
|
|
|
ChoiceList: ChoiceListParser,
|
2021-10-21 18:50:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export function createParser(
|
|
|
|
type: string, widgetOpts: FormatOptions, docSettings: DocumentSettings
|
2021-11-01 15:48:08 +00:00
|
|
|
): (value: string) => any {
|
2021-10-21 18:50:49 +00:00
|
|
|
const cls = parsers[gristTypes.extractTypeFromColType(type)];
|
|
|
|
if (cls) {
|
|
|
|
const parser = new cls(type, widgetOpts, docSettings);
|
|
|
|
return parser.cleanParse.bind(parser);
|
|
|
|
}
|
2021-11-01 15:48:08 +00:00
|
|
|
return value => value;
|
2021-10-21 18:50:49 +00:00
|
|
|
}
|