(core) Change formatUnknown/formatDecoded to format 'simple' lists like CSVs rather than JSON

Summary:
Formats lists as CSVs at the top level, so the list `["a", "b"]` gets formatted as `a,b`. Further nesting looks like JSON, with quotes around strings, which get doubled to escape them in the CSV. So the common case looks significantly nicer, but the rare case of nested arrays looks very weird and confusing.

There's also some smaller details about quotes and spaces to discuss if we're happy with the overall idea.

This is part of revamping type conversion and was discussed here: https://grist.quip.com/csqCAfx6KHt2#HOaADA7Q6NM

Test Plan: Updated several tests, need to confirm if we want this behaviour before continuing.

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D3208
This commit is contained in:
Alex Hall 2022-01-10 20:43:45 +02:00
parent 98a331a1e4
commit 3facb2a7cd

View File

@ -1,5 +1,6 @@
// tslint:disable:max-classes-per-file
import {csvEncodeRow} from 'app/common/csvFormat';
import {CellValue} from 'app/common/DocActions';
import {DocumentSettings} from 'app/common/DocumentSettings';
import * as gristTypes from 'app/common/gristTypes';
@ -31,7 +32,11 @@ export function formatUnknown(value: CellValue): string {
export function formatDecoded(value: unknown, isTopLevel: boolean = true): string {
if (typeof value === 'object' && value) {
if (Array.isArray(value)) {
return '[' + value.map(v => formatDecoded(v, false)).join(', ') + ']';
if (!isTopLevel || value.some(v => typeof v === 'object' && v && (Array.isArray(v) || isPlainObject(v)))) {
return '[' + value.map(v => formatDecoded(v, false)).join(', ') + ']';
} else {
return csvEncodeRow(value.map(v => formatDecoded(v, true)), {prettier: true});
}
} else if (isPlainObject(value)) {
const obj: any = value;
const items = Object.keys(obj).map(k => `${JSON.stringify(k)}: ${formatDecoded(obj[k], false)}`);