From 11b233b5165076e7580531818d448787d29fdaa6 Mon Sep 17 00:00:00 2001 From: Chaiwat Ekkaewnumchai Date: Tue, 19 May 2020 09:11:12 -0700 Subject: [PATCH] Allow Long Text to Be Shown in The Sidebar Summary: This allows long text to be seen on the sidebar in database plugin. Also, remove weird padding in the sidebar and separate sidebar component to a new file Refactoring is in the next diff Reviewed By: mweststrate Differential Revision: D21550672 fbshipit-source-id: 3e80be16783719e18392fe3d8f8068caf9283f8f --- .../table/TypeBasedValueRenderer.tsx | 19 ++- .../databases/DatabaseDetailSidebar.tsx | 125 ++++++++++++++++++ desktop/plugins/databases/index.tsx | 115 +--------------- 3 files changed, 144 insertions(+), 115 deletions(-) create mode 100644 desktop/plugins/databases/DatabaseDetailSidebar.tsx diff --git a/desktop/app/src/ui/components/table/TypeBasedValueRenderer.tsx b/desktop/app/src/ui/components/table/TypeBasedValueRenderer.tsx index ef1a9cd9d..05a098cdf 100644 --- a/desktop/app/src/ui/components/table/TypeBasedValueRenderer.tsx +++ b/desktop/app/src/ui/components/table/TypeBasedValueRenderer.tsx @@ -29,6 +29,14 @@ export type Value = type: 'null'; }; +const WrappingText = styled(Text)({ + wordWrap: 'break-word', + width: '100%', + lineHeight: '125%', + padding: '3px 0', +}); +WrappingText.displayName = 'TypeBasedValueRenderer:WrappingText'; + const NonWrappingText = styled(Text)({ overflow: 'hidden', textOverflow: 'ellipsis', @@ -51,7 +59,8 @@ const BooleanValue = styled(NonWrappingText)<{active?: boolean}>((props) => ({ })); BooleanValue.displayName = 'TypeBasedValueRenderer:BooleanValue'; -export function renderValue(val: Value) { +export function renderValue(val: Value, wordWrap?: boolean) { + const TextComponent = wordWrap ? WrappingText : NonWrappingText; switch (val.type) { case 'boolean': return ( @@ -61,15 +70,15 @@ export function renderValue(val: Value) { ); case 'blob': case 'string': - return {val.value}; + return {val.value}; case 'integer': case 'float': case 'double': case 'number': - return {val.value}; + return {val.value}; case 'null': - return NULL; + return NULL; default: - return ; + return ; } } diff --git a/desktop/plugins/databases/DatabaseDetailSidebar.tsx b/desktop/plugins/databases/DatabaseDetailSidebar.tsx new file mode 100644 index 000000000..7028c3e5f --- /dev/null +++ b/desktop/plugins/databases/DatabaseDetailSidebar.tsx @@ -0,0 +1,125 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +import React from 'react'; +import {QueriedTable} from '.'; +import { + Text, + DetailSidebar, + Panel, + ManagedTable, + TableRows, + TableBodyRow, + ManagedDataInspector, +} from 'flipper'; + +function sidebarRows(id: number, table: QueriedTable): TableRows { + const columns = table.columns; + const row = table.rows[id]; + if (columns.length === 1) { + const sidebarArray = []; + // TODO(T60896483): Narrow the scope of this try/catch block. + try { + const parsed = JSON.parse(row.columns[columns[0]].value.props.children); + for (const key in parsed) { + sidebarArray.push( + buildSidebarRow(key, { + props: { + children: parsed[key], + }, + }), + ); + } + } catch (e) { + sidebarArray.push( + buildSidebarRow(columns[0], row.columns[columns[0]].value), + ); + } + return sidebarArray; + } else { + return columns.map((column, i) => + buildSidebarRow(columns[i], row.columns[columns[i]].value), + ); + } +} + +function buildSidebarRow(key: string, val: any): TableBodyRow { + let output: any = ''; + // TODO(T60896483): Narrow the scope of this try/catch block. + try { + const parsed = JSON.parse(val.props.children); + for (const key in parsed) { + try { + parsed[key] = JSON.parse(parsed[key]); + } catch (err) {} + } + output = ( + + ); + } catch (error) { + output = val; + } + return { + columns: { + col: {value: {key}}, + val: { + value: output, + }, + }, + key: key, + }; +} + +export default React.memo(function DatabaseDetailSidebar(props: { + table: QueriedTable; +}) { + const {table} = props; + if ( + table.highlightedRows === null || + typeof table.highlightedRows === 'undefined' || + table.highlightedRows.length !== 1 + ) { + return null; + } + const id = table.highlightedRows[0]; + const cols = { + col: { + value: 'Column', + resizable: true, + }, + val: { + value: 'Value', + resizable: true, + }, + }; + const colSizes = { + col: '35%', + val: 'flex', + }; + return ( + + + + + + ); +}); diff --git a/desktop/plugins/databases/index.tsx b/desktop/plugins/databases/index.tsx index c10862962..a9481327f 100644 --- a/desktop/plugins/databases/index.tsx +++ b/desktop/plugins/databases/index.tsx @@ -23,9 +23,6 @@ import { getStringFromErrorLike, Spacer, Textarea, - DetailSidebar, - Panel, - ManagedDataInspector, TableBodyColumn, TableRows, Props as FlipperPluginProps, @@ -37,6 +34,7 @@ import {DatabaseClient} from './ClientProtocol'; import {renderValue} from 'flipper'; import {Value} from 'flipper'; import ButtonNavigation from './ButtonNavigation'; +import DatabaseDetailSidebar from './DatabaseDetailSidebar'; import sqlFormatter from 'sql-formatter'; import dateFormat from 'dateformat'; @@ -110,7 +108,7 @@ type QueryResult = { count: number | null; }; -type QueriedTable = { +export type QueriedTable = { columns: Array; rows: Array; highlightedRows: Array; @@ -252,7 +250,7 @@ function transformRow( ): TableBodyRow { const transformedColumns: {[key: string]: TableBodyColumn} = {}; for (let i = 0; i < columns.length; i++) { - transformedColumns[columns[i]] = {value: renderValue(row[i])}; + transformedColumns[columns[i]] = {value: renderValue(row[i], true)}; } return {key: String(index), columns: transformedColumns}; } @@ -1064,109 +1062,6 @@ export default class DatabasesPlugin extends FlipperPlugin< ); } - renderSidebar = (table: QueriedTable) => { - if ( - table.highlightedRows === null || - typeof table.highlightedRows === 'undefined' || - table.highlightedRows.length !== 1 - ) { - return null; - } - const id = table.highlightedRows[0]; - const cols = { - col: { - value: 'Column', - resizable: true, - }, - val: { - value: 'Value', - resizable: true, - }, - }; - const colSizes = { - col: '35%', - val: 'flex', - }; - return ( - - - - - - ); - }; - - sidebarRows(id: number, table: QueriedTable): TableRows { - const columns = table.columns; - const row = table.rows[id]; - if (columns.length === 1) { - const sidebarArray = []; - // TODO(T60896483): Narrow the scope of this try/catch block. - try { - const parsed = JSON.parse(row.columns[columns[0]].value.props.children); - for (const key in parsed) { - sidebarArray.push( - this.buildSidebarRow(key, { - props: { - children: parsed[key], - }, - }), - ); - } - } catch (e) { - sidebarArray.push( - this.buildSidebarRow(columns[0], row.columns[columns[0]].value), - ); - } - return sidebarArray; - } else { - return columns.map((column, i) => - this.buildSidebarRow(columns[i], row.columns[columns[i]].value), - ); - } - } - - buildSidebarRow(key: string, val: any): TableBodyRow { - let output: any = ''; - // TODO(T60896483): Narrow the scope of this try/catch block. - try { - const parsed = JSON.parse(val.props.children); - for (const key in parsed) { - try { - parsed[key] = JSON.parse(parsed[key]); - } catch (err) {} - } - output = ( - - ); - } catch (error) { - output = val; - } - return { - columns: { - col: {value: {key}}, - val: { - value: output, - }, - }, - key: key, - }; - } - renderTable(page: Page | null) { if (!page) { return null; @@ -1210,7 +1105,7 @@ export default class DatabasesPlugin extends FlipperPlugin< }} initialSortOrder={this.state.currentSort ?? undefined} /> - {this.renderSidebar(page)} + ); } @@ -1258,7 +1153,7 @@ export default class DatabasesPlugin extends FlipperPlugin< }); }} /> - {this.renderSidebar(table)} + ); } else if (query.id && query.id !== null) {