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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
f2b46e558f
commit
11b233b516
@@ -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 <NonWrappingText>{val.value}</NonWrappingText>;
|
||||
return <TextComponent>{val.value}</TextComponent>;
|
||||
case 'integer':
|
||||
case 'float':
|
||||
case 'double':
|
||||
case 'number':
|
||||
return <NonWrappingText>{val.value}</NonWrappingText>;
|
||||
return <TextComponent>{val.value}</TextComponent>;
|
||||
case 'null':
|
||||
return <NonWrappingText>NULL</NonWrappingText>;
|
||||
return <TextComponent>NULL</TextComponent>;
|
||||
default:
|
||||
return <NonWrappingText />;
|
||||
return <TextComponent />;
|
||||
}
|
||||
}
|
||||
|
||||
125
desktop/plugins/databases/DatabaseDetailSidebar.tsx
Normal file
125
desktop/plugins/databases/DatabaseDetailSidebar.tsx
Normal file
@@ -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 = (
|
||||
<ManagedDataInspector data={parsed} expandRoot={false} collapsed />
|
||||
);
|
||||
} catch (error) {
|
||||
output = val;
|
||||
}
|
||||
return {
|
||||
columns: {
|
||||
col: {value: <Text>{key}</Text>},
|
||||
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 (
|
||||
<DetailSidebar>
|
||||
<Panel
|
||||
heading="Row details"
|
||||
floating={false}
|
||||
collapsable={true}
|
||||
padded={false}>
|
||||
<ManagedTable
|
||||
highlightableRows={false}
|
||||
columnSizes={colSizes}
|
||||
multiline={true}
|
||||
columns={cols}
|
||||
autoHeight={true}
|
||||
floating={false}
|
||||
zebra={false}
|
||||
rows={sidebarRows(id, table)}
|
||||
/>
|
||||
</Panel>
|
||||
</DetailSidebar>
|
||||
);
|
||||
});
|
||||
@@ -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<string>;
|
||||
rows: Array<TableBodyRow>;
|
||||
highlightedRows: Array<number>;
|
||||
@@ -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 (
|
||||
<DetailSidebar width={500}>
|
||||
<Panel
|
||||
padded={true}
|
||||
heading="Row details"
|
||||
floating={false}
|
||||
collapsable={true}
|
||||
grow={true}>
|
||||
<ManagedTable
|
||||
highlightableRows={false}
|
||||
columnSizes={colSizes}
|
||||
multiline={true}
|
||||
columns={cols}
|
||||
autoHeight={true}
|
||||
floating={false}
|
||||
zebra={true}
|
||||
rows={this.sidebarRows(id, table)}
|
||||
/>
|
||||
</Panel>
|
||||
</DetailSidebar>
|
||||
);
|
||||
};
|
||||
|
||||
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 = (
|
||||
<ManagedDataInspector data={parsed} expandRoot={false} collapsed />
|
||||
);
|
||||
} catch (error) {
|
||||
output = val;
|
||||
}
|
||||
return {
|
||||
columns: {
|
||||
col: {value: <Text>{key}</Text>},
|
||||
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)}
|
||||
<DatabaseDetailSidebar table={page} />
|
||||
</FlexRow>
|
||||
);
|
||||
}
|
||||
@@ -1258,7 +1153,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
||||
});
|
||||
}}
|
||||
/>
|
||||
{this.renderSidebar(table)}
|
||||
<DatabaseDetailSidebar table={table} />
|
||||
</FlexRow>
|
||||
);
|
||||
} else if (query.id && query.id !== null) {
|
||||
|
||||
Reference in New Issue
Block a user