diff --git a/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap b/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap index c019c38fa22..5ed0f315896 100644 --- a/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap +++ b/web-console/src/components/table-cell/__snapshots__/table-cell.spec.tsx.snap @@ -49,6 +49,14 @@ exports[`TableCell matches snapshot array long 1`] = ` `; +exports[`TableCell matches snapshot array mixed 1`] = ` +
+ ["a",{"v":"b"},"c"] +
+`; + exports[`TableCell matches snapshot array short 1`] = `
{ expect(container.firstChild).toMatchSnapshot(); }); + it('matches snapshot array mixed', () => { + const tableCell = ; + + const { container } = render(tableCell); + expect(container.firstChild).toMatchSnapshot(); + }); + it('matches snapshot object', () => { const tableCell = ; diff --git a/web-console/src/components/table-cell/table-cell.tsx b/web-console/src/components/table-cell/table-cell.tsx index 3895a805a70..78f080b306d 100644 --- a/web-console/src/components/table-cell/table-cell.tsx +++ b/web-console/src/components/table-cell/table-cell.tsx @@ -21,6 +21,7 @@ import * as JSONBig from 'json-bigint-native'; import React, { useState } from 'react'; import { ShowValueDialog } from '../../dialogs/show-value-dialog/show-value-dialog'; +import { isSimpleArray } from '../../utils'; import { ActionIcon } from '../action-icon/action-icon'; import './table-cell.scss'; @@ -97,7 +98,7 @@ export const TableCell = React.memo(function TableCell(props: TableCellProps) { {isNaN(dateValue) ? 'Unusable date' : value.toISOString()}
); - } else if (Array.isArray(value)) { + } else if (isSimpleArray(value)) { return renderTruncated(`[${value.join(', ')}]`); } else if (typeof value === 'object') { return renderTruncated(JSONBig.stringify(value)); diff --git a/web-console/src/druid-models/ingestion-spec/ingestion-spec.spec.ts b/web-console/src/druid-models/ingestion-spec/ingestion-spec.spec.ts index a846d29a818..3f4be422c79 100644 --- a/web-console/src/druid-models/ingestion-spec/ingestion-spec.spec.ts +++ b/web-console/src/druid-models/ingestion-spec/ingestion-spec.spec.ts @@ -725,6 +725,15 @@ describe('spec utils', () => { it('works for multi-value', () => { expect(guessColumnTypeFromInput(['a', ['b'], 'c'], false)).toEqual('string'); expect(guessColumnTypeFromInput([1, [2], 3], false)).toEqual('string'); + expect(guessColumnTypeFromInput([true, [true, 7, false], false, 'x'], false)).toEqual( + 'string', + ); + }); + + it('works for complex arrays', () => { + expect(guessColumnTypeFromInput([{ type: 'Dogs' }, { type: 'JavaScript' }], false)).toEqual( + 'COMPLEX', + ); }); it('works for strange json', () => { diff --git a/web-console/src/druid-models/ingestion-spec/ingestion-spec.tsx b/web-console/src/druid-models/ingestion-spec/ingestion-spec.tsx index d7bf5091634..fe9b8074c16 100644 --- a/web-console/src/druid-models/ingestion-spec/ingestion-spec.tsx +++ b/web-console/src/druid-models/ingestion-spec/ingestion-spec.tsx @@ -32,6 +32,7 @@ import { EMPTY_ARRAY, EMPTY_OBJECT, filterMap, + isSimpleArray, oneOf, parseCsvLine, typeIs, @@ -2330,7 +2331,7 @@ export function guessIsArrayFromHeaderAndRows( headerAndRows: SampleHeaderAndRows, column: string, ): boolean { - return headerAndRows.rows.some(r => Array.isArray(r.input?.[column])); + return headerAndRows.rows.some(r => isSimpleArray(r.input?.[column])); } export function guessColumnTypeFromInput( @@ -2343,7 +2344,7 @@ export function guessColumnTypeFromInput( if (!definedValues.length) return 'string'; // If we see any arrays in the input this is a multi-value dimension that must be a string - if (definedValues.some(v => Array.isArray(v))) return 'string'; + if (definedValues.some(v => isSimpleArray(v))) return 'string'; // If we see any JSON objects in the input assume COMPLEX if (definedValues.some(v => v && typeof v === 'object')) return 'COMPLEX'; diff --git a/web-console/src/utils/general.tsx b/web-console/src/utils/general.tsx index 772e3c646f2..5cf8ca0ce5f 100644 --- a/web-console/src/utils/general.tsx +++ b/web-console/src/utils/general.tsx @@ -40,6 +40,16 @@ export function nonEmptyArray(a: any): a is unknown[] { return Array.isArray(a) && Boolean(a.length); } +export function isSimpleArray(a: any): a is (string | number | boolean)[] { + return ( + Array.isArray(a) && + a.every(x => { + const t = typeof x; + return t === 'string' || t === 'number' || t === 'boolean'; + }) + ); +} + export function wait(ms: number): Promise { return new Promise(resolve => { setTimeout(resolve, ms);