diff --git a/desktop/plugins/databases/DatabaseDetailSidebar.tsx b/desktop/plugins/databases/DatabaseDetailSidebar.tsx index 64d105195..64f714746 100644 --- a/desktop/plugins/databases/DatabaseDetailSidebar.tsx +++ b/desktop/plugins/databases/DatabaseDetailSidebar.tsx @@ -9,23 +9,25 @@ import React, {useMemo, useState, useEffect, useReducer} from 'react'; import { - Text, Input, DetailSidebar, Panel, - ManagedTable, - TableRows, - TableBodyRow, ManagedDataInspector, Value, valueToNullableString, renderValue, - Layout, Button, styled, produce, + colors, } from 'flipper'; +type TableRow = { + col: string; + type: Value['type']; + value: React.ReactElement; +}; + type DatabaseDetailSidebarProps = { columnLabels: Array; columnValues: Array; @@ -41,29 +43,48 @@ const EditTriggerSection = styled.div({ paddingRight: '10px', }); -function sidebarRows(labels: Array, values: Array): TableRows { +const TableDetailRow = styled.div({ + borderBottom: `1px solid ${colors.blackAlpha10}`, + padding: 8, +}); + +const TableDetailRowTitle = styled.div({ + fontWeight: 'bold', + marginBottom: 8, +}); + +const TableDetailRowType = styled.span({ + color: colors.light20, + marginLeft: 8, + fontWeight: 'normal', +}); + +const TableDetailRowValue = styled.div({}); + +function sidebarRows(labels: Array, values: Array): TableRow[] { return labels.map((label, idx) => buildSidebarRow(label, values[idx])); } -function buildSidebarRow(key: string, val: Value): TableBodyRow { +function buildSidebarRow(key: string, val: Value): TableRow { let output = renderValue(val, true); - // TODO(T60896483): Narrow the scope of this try/catch block. - if (val.type === 'string') { + if ( + (val.type === 'string' || val.type === 'blob') && + (val.value[0] === '[' || val.value[0] === '{') + ) { try { - const parsed = JSON.parse(val.value); - output = ( - - ); + // eslint-disable-next-line + var parsed = JSON.parse(val.value); } catch (_error) {} + if (parsed) { + output = ( + + ); + } } return { - columns: { - col: {value: {key}}, - val: { - value: output, - }, - }, - key: key, + col: key, + type: val.type, + value: output, }; } @@ -71,35 +92,32 @@ function sidebarEditableRows( labels: Array, values: Array, rowDispatch: (action: RowAction) => void, -): TableRows { +): TableRow[] { return labels.map((label, idx) => - buildSidebarEditableRow( - label, - valueToNullableString(values[idx]), - (value: string | null) => rowDispatch({type: 'set', key: label, value}), + buildSidebarEditableRow(label, values[idx], (value: string | null) => + rowDispatch({type: 'set', key: label, value}), ), ); } function buildSidebarEditableRow( key: string, - value: string | null, + val: Value, onUpdateValue: (value: string | null) => void, -): TableBodyRow { +): TableRow { + if (val.type === 'blob' || !val.type) { + return buildSidebarRow(key, val); + } return { - columns: { - col: {value: {key}}, - val: { - value: ( - - ), - }, - }, - key: key, + col: key, + type: val.type, + value: ( + + ), }; } @@ -120,24 +138,11 @@ const EditField = React.memo( }} placeholder={value === null ? 'NULL' : undefined} data-testid={'update-query-input'} + style={{width: '100%'}} /> ); }, ); -const cols = { - col: { - value: 'Column', - resizable: true, - }, - val: { - value: 'Value', - resizable: true, - }, -}; -const colSizes = { - col: '35%', - val: 'flex', -}; type RowState = {changes: {[key: string]: string | null}; updated: boolean}; type RowAction = @@ -181,37 +186,36 @@ export default React.memo(function DatabaseDetailSidebar( floating={false} collapsable={true} padded={false}> - - {onSave && ( - - {editing ? ( - <> - - - - ) : ( - - )} - - )} - - + {onSave ? ( + + {editing ? ( + <> + + + + ) : ( + + )} + + ) : null} +
+ {rows.map((row) => ( + + + {row.col} + ({row.type}) + + {row.value} + + ))} +
); diff --git a/desktop/plugins/databases/__test__/DatabaseDetailSidebar.node.tsx b/desktop/plugins/databases/__test__/DatabaseDetailSidebar.node.tsx index a0a84d637..60a4e88c8 100644 --- a/desktop/plugins/databases/__test__/DatabaseDetailSidebar.node.tsx +++ b/desktop/plugins/databases/__test__/DatabaseDetailSidebar.node.tsx @@ -134,12 +134,15 @@ test('editing some field after trigger Edit', async () => { fireEvent.click(res.getByText('Edit')); // still find all values because it needs to show up for (const value of values) { - if (value.type === 'blob') { - continue; - } - const searchValue: string = - value.type === 'null' ? 'NULL' : value.value.toString(); - expect(res.queryAllByText(searchValue).length).toBeGreaterThan(0); + const searchValue = value.value?.toString(); + expect( + (value.type === 'null' + ? res.queryAllByPlaceholderText('NULL') + : value.type === 'blob' + ? res.queryAllByText(searchValue!) + : res.queryAllByDisplayValue(searchValue!) + ).length, + ).toBeGreaterThan(0); } // expect the last one to contain value of 'db_1_column9_value'