diff --git a/superset-frontend/src/components/JsonModal/JsonModal.test.tsx b/superset-frontend/src/components/JsonModal/JsonModal.test.tsx index f0e2230f5a82..44f01404a3b3 100644 --- a/superset-frontend/src/components/JsonModal/JsonModal.test.tsx +++ b/superset-frontend/src/components/JsonModal/JsonModal.test.tsx @@ -42,6 +42,21 @@ test('renders JSON object in a tree view in a modal', () => { expect(getByTestId('mock-json-tree')).toBeInTheDocument(); }); +test('renders an object in a tree view in a modal', () => { + const jsonData = { a: 1 }; + const expected = JSON.stringify(jsonData); + const { getByText, getByTestId, queryByTestId } = render( + , + { + useRedux: true, + }, + ); + expect(queryByTestId('mock-json-tree')).not.toBeInTheDocument(); + const link = getByText(expected); + fireEvent.click(link); + expect(getByTestId('mock-json-tree')).toBeInTheDocument(); +}); + test('renders bigInt value in a number format', () => { expect(convertBigIntStrToNumber('123')).toBe('123'); expect(convertBigIntStrToNumber('some string value')).toBe( diff --git a/superset-frontend/src/components/JsonModal/index.tsx b/superset-frontend/src/components/JsonModal/index.tsx index e599f483dcd2..79ff25ef5afc 100644 --- a/superset-frontend/src/components/JsonModal/index.tsx +++ b/superset-frontend/src/components/JsonModal/index.tsx @@ -36,7 +36,7 @@ * under the License. */ import JSONbig from 'json-bigint'; -import { FC } from 'react'; +import { FC, useMemo } from 'react'; import { JSONTree } from 'react-json-tree'; import { useJsonTreeTheme } from 'src/hooks/useJsonTreeTheme'; import Button from '../Button'; @@ -46,6 +46,10 @@ import ModalTrigger from '../ModalTrigger'; export function safeJsonObjectParse( data: unknown, ): null | unknown[] | Record { + if (typeof data === 'object') { + return data as null | unknown[] | Record; + } + // First perform a cheap proxy to avoid calling JSON.parse on data that is clearly not a // JSON object or array if ( @@ -78,7 +82,7 @@ function renderBigIntStrToNumber(value: string | number) { return <>{convertBigIntStrToNumber(value)}; } -type CellDataType = string | number | null; +type CellDataType = string | number | null | object; export interface Props { modalTitle: string; @@ -88,6 +92,11 @@ export interface Props { export const JsonModal: FC = ({ modalTitle, jsonObject, jsonValue }) => { const jsonTreeTheme = useJsonTreeTheme(); + const content = useMemo( + () => + typeof jsonValue === 'object' ? JSON.stringify(jsonValue) : jsonValue, + [jsonValue], + ); return ( = ({ modalTitle, jsonObject, jsonValue }) => { } modalFooter={ } modalTitle={modalTitle} - triggerNode={<>{jsonValue}} + triggerNode={<>{content}} /> ); };