Convert Database Plugin to TypeScript
Summary: Mainly convert `js` to `tsx` Additional change: - Try not to directly change object value in reduce function - Add emotion styled when there is error using style prop directly Reviewed By: nikoant Differential Revision: D21406943 fbshipit-source-id: 30312fa0b0d2d70fa52c5ff9db747e1a83beb270
This commit is contained in:
committed by
Facebook GitHub Bot
parent
171b049a81
commit
7d2101c68f
@@ -8,17 +8,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Button, ButtonGroup, Glyph, colors} from 'flipper';
|
import {Button, ButtonGroup, Glyph, colors} from 'flipper';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
export default function ButtonNavigation(props: {|
|
export default function ButtonNavigation(props: {
|
||||||
/** Back button is enabled */
|
/** Back button is enabled */
|
||||||
canGoBack: boolean,
|
canGoBack: boolean;
|
||||||
/** Forwards button is enabled */
|
/** Forwards button is enabled */
|
||||||
canGoForward: boolean,
|
canGoForward: boolean;
|
||||||
/** Callback when back button is clicked */
|
/** Callback when back button is clicked */
|
||||||
onBack: () => void,
|
onBack: () => void;
|
||||||
/** Callback when forwards button is clicked */
|
/** Callback when forwards button is clicked */
|
||||||
onForward: () => void,
|
onForward: () => void;
|
||||||
|}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button disabled={!props.canGoBack} onClick={props.onBack}>
|
<Button disabled={!props.canGoBack} onClick={props.onBack}>
|
||||||
@@ -7,68 +7,68 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {PluginClient, Value} from 'flipper';
|
import {PluginClient, Value} from 'flipper';
|
||||||
|
|
||||||
type ClientCall<Params, Response> = (Params) => Promise<Response>;
|
type ClientCall<Params, Response> = (arg: Params) => Promise<Response>;
|
||||||
|
|
||||||
type DatabaseListRequest = {};
|
type DatabaseListRequest = {};
|
||||||
|
|
||||||
type DatabaseListResponse = Array<{
|
type DatabaseListResponse = Array<{
|
||||||
id: number,
|
id: number;
|
||||||
name: string,
|
name: string;
|
||||||
tables: Array<string>,
|
tables: Array<string>;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
type QueryTableRequest = {
|
type QueryTableRequest = {
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
table: string,
|
table: string;
|
||||||
order?: string,
|
order?: string;
|
||||||
reverse: boolean,
|
reverse: boolean;
|
||||||
start: number,
|
start: number;
|
||||||
count: number,
|
count: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type QueryTableResponse = {
|
type QueryTableResponse = {
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
values: Array<Array<Value>>,
|
values: Array<Array<Value>>;
|
||||||
start: number,
|
start: number;
|
||||||
count: number,
|
count: number;
|
||||||
total: number,
|
total: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetTableStructureRequest = {
|
type GetTableStructureRequest = {
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
table: string,
|
table: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetTableStructureResponse = {
|
type GetTableStructureResponse = {
|
||||||
structureColumns: Array<string>,
|
structureColumns: Array<string>;
|
||||||
structureValues: Array<Array<Value>>,
|
structureValues: Array<Array<Value>>;
|
||||||
indexesColumns: Array<string>,
|
indexesColumns: Array<string>;
|
||||||
indexesValues: Array<Array<Value>>,
|
indexesValues: Array<Array<Value>>;
|
||||||
definition: string,
|
definition: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ExecuteSqlRequest = {
|
type ExecuteSqlRequest = {
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
value: string,
|
value: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ExecuteSqlResponse = {
|
type ExecuteSqlResponse = {
|
||||||
type: string,
|
type: string;
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
values: Array<Array<Value>>,
|
values: Array<Array<Value>>;
|
||||||
insertedId: number,
|
insertedId: number;
|
||||||
affectedCount: number,
|
affectedCount: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetTableInfoRequest = {
|
type GetTableInfoRequest = {
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
table: string,
|
table: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GetTableInfoResponse = {
|
type GetTableInfoResponse = {
|
||||||
definition: string,
|
definition: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class DatabaseClient {
|
export class DatabaseClient {
|
||||||
@@ -78,16 +78,15 @@ export class DatabaseClient {
|
|||||||
this.client = pluginClient;
|
this.client = pluginClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDatabases: ClientCall<DatabaseListRequest, DatabaseListResponse> = (
|
getDatabases: ClientCall<DatabaseListRequest, DatabaseListResponse> = () =>
|
||||||
params,
|
this.client.call('databaseList', {});
|
||||||
) => this.client.call('databaseList', {});
|
|
||||||
|
|
||||||
getTableData: ClientCall<QueryTableRequest, QueryTableResponse> = (params) =>
|
getTableData: ClientCall<QueryTableRequest, QueryTableResponse> = (params) =>
|
||||||
this.client.call('getTableData', params);
|
this.client.call('getTableData', params);
|
||||||
|
|
||||||
getTableStructure: ClientCall<
|
getTableStructure: ClientCall<
|
||||||
GetTableStructureRequest,
|
GetTableStructureRequest,
|
||||||
GetTableStructureResponse,
|
GetTableStructureResponse
|
||||||
> = (params) => this.client.call('getTableStructure', params);
|
> = (params) => this.client.call('getTableStructure', params);
|
||||||
|
|
||||||
getExecution: ClientCall<ExecuteSqlRequest, ExecuteSqlResponse> = (params) =>
|
getExecution: ClientCall<ExecuteSqlRequest, ExecuteSqlResponse> = (params) =>
|
||||||
@@ -25,13 +25,16 @@ import {
|
|||||||
DetailSidebar,
|
DetailSidebar,
|
||||||
Panel,
|
Panel,
|
||||||
ManagedDataInspector,
|
ManagedDataInspector,
|
||||||
|
TableBodyColumn,
|
||||||
|
TableRows,
|
||||||
|
Props as FlipperPluginProps,
|
||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
import {Component} from 'react';
|
import React, {Component, KeyboardEvent, ChangeEvent} from 'react';
|
||||||
import type {TableBodyRow, TableRowSortOrder} from 'flipper';
|
import {TableBodyRow, TableRowSortOrder} from 'flipper';
|
||||||
import {FlipperPlugin} from 'flipper';
|
import {FlipperPlugin} from 'flipper';
|
||||||
import {DatabaseClient} from './ClientProtocol';
|
import {DatabaseClient} from './ClientProtocol';
|
||||||
import {renderValue} from 'flipper';
|
import {renderValue} from 'flipper';
|
||||||
import type {Value} from 'flipper';
|
import {Value} from 'flipper';
|
||||||
import ButtonNavigation from './ButtonNavigation';
|
import ButtonNavigation from './ButtonNavigation';
|
||||||
import sqlFormatter from 'sql-formatter';
|
import sqlFormatter from 'sql-formatter';
|
||||||
import dateFormat from 'dateformat';
|
import dateFormat from 'dateformat';
|
||||||
@@ -50,55 +53,65 @@ const ErrorBar = styled.div({
|
|||||||
lineHeight: '26px',
|
lineHeight: '26px',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
});
|
});
|
||||||
|
const QueryHistoryManagedTable = styled(ManagedTable)({paddingLeft: 16});
|
||||||
|
const PageInfoContainer = styled(FlexRow)({alignItems: 'center'});
|
||||||
|
const TableInfoTextArea = styled(Textarea)({
|
||||||
|
width: '98%',
|
||||||
|
height: '100%',
|
||||||
|
marginLeft: '1%',
|
||||||
|
marginTop: '1%',
|
||||||
|
marginBottom: '1%',
|
||||||
|
readOnly: true,
|
||||||
|
});
|
||||||
|
|
||||||
type DatabasesPluginState = {|
|
type DatabasesPluginState = {
|
||||||
selectedDatabase: number,
|
selectedDatabase: number;
|
||||||
selectedDatabaseTable: ?string,
|
selectedDatabaseTable: string | null;
|
||||||
pageRowNumber: number,
|
pageRowNumber: number;
|
||||||
databases: Array<DatabaseEntry>,
|
databases: Array<DatabaseEntry>;
|
||||||
outdatedDatabaseList: boolean,
|
outdatedDatabaseList: boolean;
|
||||||
viewMode: 'data' | 'structure' | 'SQL' | 'tableInfo' | 'queryHistory',
|
viewMode: 'data' | 'structure' | 'SQL' | 'tableInfo' | 'queryHistory';
|
||||||
error: ?null,
|
error: null;
|
||||||
currentPage: ?Page,
|
currentPage: Page | null;
|
||||||
currentStructure: ?Structure,
|
currentStructure: Structure | null;
|
||||||
currentSort: ?TableRowSortOrder,
|
currentSort: TableRowSortOrder | null;
|
||||||
query: ?Query,
|
query: Query | null;
|
||||||
queryResult: ?QueryResult,
|
queryResult: QueryResult | null;
|
||||||
favorites: Array<string>,
|
favorites: Array<string>;
|
||||||
executionTime: number,
|
executionTime: number;
|
||||||
tableInfo: string,
|
tableInfo: string;
|
||||||
queryHistory: Array<Query>,
|
queryHistory: Array<Query>;
|
||||||
|};
|
|
||||||
|
|
||||||
type Page = {
|
|
||||||
databaseId: number,
|
|
||||||
table: string,
|
|
||||||
columns: Array<string>,
|
|
||||||
rows: Array<TableBodyRow>,
|
|
||||||
start: number,
|
|
||||||
count: number,
|
|
||||||
total: number,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type Structure = {|
|
type Page = {
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
table: string,
|
table: string;
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
rows: Array<TableBodyRow>,
|
rows: Array<TableBodyRow>;
|
||||||
indexesColumns: Array<string>,
|
start: number;
|
||||||
indexesValues: Array<TableBodyRow>,
|
count: number;
|
||||||
|};
|
total: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Structure = {
|
||||||
|
databaseId: number;
|
||||||
|
table: string;
|
||||||
|
columns: Array<string>;
|
||||||
|
rows: Array<TableBodyRow>;
|
||||||
|
indexesColumns: Array<string>;
|
||||||
|
indexesValues: Array<TableBodyRow>;
|
||||||
|
};
|
||||||
|
|
||||||
type QueryResult = {
|
type QueryResult = {
|
||||||
table: ?QueriedTable,
|
table: QueriedTable | null;
|
||||||
id: ?number,
|
id: number | null;
|
||||||
count: ?number,
|
count: number | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type QueriedTable = {
|
type QueriedTable = {
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
rows: Array<TableBodyRow>,
|
rows: Array<TableBodyRow>;
|
||||||
highlightedRows: Array<number>,
|
highlightedRows: Array<number>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Actions =
|
type Actions =
|
||||||
@@ -122,112 +135,112 @@ type Actions =
|
|||||||
| UpdateQueryEvent;
|
| UpdateQueryEvent;
|
||||||
|
|
||||||
type DatabaseEntry = {
|
type DatabaseEntry = {
|
||||||
id: number,
|
id: number;
|
||||||
name: string,
|
name: string;
|
||||||
tables: Array<string>,
|
tables: Array<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Query = {|
|
type Query = {
|
||||||
value: string,
|
value: string;
|
||||||
time: string,
|
time: string;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type UpdateDatabasesEvent = {|
|
type UpdateDatabasesEvent = {
|
||||||
databases: Array<{name: string, id: number, tables: Array<string>}>,
|
databases: Array<{name: string; id: number; tables: Array<string>}>;
|
||||||
type: 'UpdateDatabases',
|
type: 'UpdateDatabases';
|
||||||
|};
|
};
|
||||||
|
|
||||||
type SelectDatabaseEvent = {|
|
type SelectDatabaseEvent = {
|
||||||
type: 'UpdateSelectedDatabase',
|
type: 'UpdateSelectedDatabase';
|
||||||
database: number,
|
database: number;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type SelectDatabaseTableEvent = {|
|
type SelectDatabaseTableEvent = {
|
||||||
type: 'UpdateSelectedDatabaseTable',
|
type: 'UpdateSelectedDatabaseTable';
|
||||||
table: string,
|
table: string;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type UpdateViewModeEvent = {|
|
type UpdateViewModeEvent = {
|
||||||
type: 'UpdateViewMode',
|
type: 'UpdateViewMode';
|
||||||
viewMode: 'data' | 'structure' | 'SQL' | 'tableInfo' | 'queryHistory',
|
viewMode: 'data' | 'structure' | 'SQL' | 'tableInfo' | 'queryHistory';
|
||||||
|};
|
};
|
||||||
|
|
||||||
type UpdatePageEvent = {|
|
type UpdatePageEvent = {
|
||||||
type: 'UpdatePage',
|
type: 'UpdatePage';
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
table: string,
|
table: string;
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
values: Array<Array<any>>,
|
values: Array<Array<any>>;
|
||||||
start: number,
|
start: number;
|
||||||
count: number,
|
count: number;
|
||||||
total: number,
|
total: number;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type UpdateStructureEvent = {|
|
type UpdateStructureEvent = {
|
||||||
type: 'UpdateStructure',
|
type: 'UpdateStructure';
|
||||||
databaseId: number,
|
databaseId: number;
|
||||||
table: string,
|
table: string;
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
rows: Array<Array<any>>,
|
rows: Array<Array<any>>;
|
||||||
indexesColumns: Array<string>,
|
indexesColumns: Array<string>;
|
||||||
indexesValues: Array<Array<any>>,
|
indexesValues: Array<Array<any>>;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type DisplaySelectEvent = {|
|
type DisplaySelectEvent = {
|
||||||
type: 'DisplaySelect',
|
type: 'DisplaySelect';
|
||||||
columns: Array<string>,
|
columns: Array<string>;
|
||||||
values: Array<Array<any>>,
|
values: Array<Array<any>>;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type DisplayInsertEvent = {|
|
type DisplayInsertEvent = {
|
||||||
type: 'DisplayInsert',
|
type: 'DisplayInsert';
|
||||||
id: number,
|
id: number;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type DisplayUpdateDeleteEvent = {|
|
type DisplayUpdateDeleteEvent = {
|
||||||
type: 'DisplayUpdateDelete',
|
type: 'DisplayUpdateDelete';
|
||||||
count: number,
|
count: number;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type UpdateTableInfoEvent = {|
|
type UpdateTableInfoEvent = {
|
||||||
type: 'UpdateTableInfo',
|
type: 'UpdateTableInfo';
|
||||||
tableInfo: string,
|
tableInfo: string;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type NextPageEvent = {
|
type NextPageEvent = {
|
||||||
type: 'NextPage',
|
type: 'NextPage';
|
||||||
};
|
};
|
||||||
|
|
||||||
type PreviousPageEvent = {
|
type PreviousPageEvent = {
|
||||||
type: 'PreviousPage',
|
type: 'PreviousPage';
|
||||||
};
|
};
|
||||||
|
|
||||||
type ExecuteEvent = {
|
type ExecuteEvent = {
|
||||||
type: 'Execute',
|
type: 'Execute';
|
||||||
};
|
};
|
||||||
|
|
||||||
type RefreshEvent = {
|
type RefreshEvent = {
|
||||||
type: 'Refresh',
|
type: 'Refresh';
|
||||||
};
|
};
|
||||||
|
|
||||||
type UpdateFavoritesEvent = {
|
type UpdateFavoritesEvent = {
|
||||||
type: 'UpdateFavorites',
|
type: 'UpdateFavorites';
|
||||||
favorites: ?Array<string>,
|
favorites: Array<string> | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SortByChangedEvent = {
|
type SortByChangedEvent = {
|
||||||
type: 'SortByChanged',
|
type: 'SortByChanged';
|
||||||
sortOrder: TableRowSortOrder,
|
sortOrder: TableRowSortOrder;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GoToRowEvent = {
|
type GoToRowEvent = {
|
||||||
type: 'GoToRow',
|
type: 'GoToRow';
|
||||||
row: number,
|
row: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type UpdateQueryEvent = {
|
type UpdateQueryEvent = {
|
||||||
type: 'UpdateQuery',
|
type: 'UpdateQuery';
|
||||||
value: string,
|
value: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
function transformRow(
|
function transformRow(
|
||||||
@@ -235,14 +248,14 @@ function transformRow(
|
|||||||
row: Array<Value>,
|
row: Array<Value>,
|
||||||
index: number,
|
index: number,
|
||||||
): TableBodyRow {
|
): TableBodyRow {
|
||||||
const transformedColumns = {};
|
const transformedColumns: {[key: string]: TableBodyColumn} = {};
|
||||||
for (let i = 0; i < columns.length; i++) {
|
for (let i = 0; i < columns.length; i++) {
|
||||||
transformedColumns[columns[i]] = {value: renderValue(row[i])};
|
transformedColumns[columns[i]] = {value: renderValue(row[i])};
|
||||||
}
|
}
|
||||||
return {key: String(index), columns: transformedColumns};
|
return {key: String(index), columns: transformedColumns};
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderTable(page: ?Page, component: DatabasesPlugin) {
|
function renderTable(page: Page | null, component: DatabasesPlugin) {
|
||||||
if (!page) {
|
if (!page) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -254,10 +267,13 @@ function renderTable(page: ?Page, component: DatabasesPlugin) {
|
|||||||
key: name,
|
key: name,
|
||||||
visible: true,
|
visible: true,
|
||||||
}))}
|
}))}
|
||||||
columns={page.columns.reduce((acc, val) => {
|
columns={page.columns.reduce(
|
||||||
acc[val] = {value: val, resizable: true, sortable: true};
|
(acc, val) =>
|
||||||
return acc;
|
Object.assign({}, acc, {
|
||||||
}, {})}
|
[val]: {value: val, resizable: true, sortable: true},
|
||||||
|
}),
|
||||||
|
{},
|
||||||
|
)}
|
||||||
zebra={true}
|
zebra={true}
|
||||||
rows={page.rows}
|
rows={page.rows}
|
||||||
horizontallyScrollable={true}
|
horizontallyScrollable={true}
|
||||||
@@ -268,12 +284,12 @@ function renderTable(page: ?Page, component: DatabasesPlugin) {
|
|||||||
sortOrder,
|
sortOrder,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
initialSortOrder={component.state.currentSort}
|
initialSortOrder={component.state.currentSort ?? undefined}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDatabaseColumns(structure: ?Structure) {
|
function renderDatabaseColumns(structure: Structure | null) {
|
||||||
if (!structure) {
|
if (!structure) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -285,10 +301,11 @@ function renderDatabaseColumns(structure: ?Structure) {
|
|||||||
key: name,
|
key: name,
|
||||||
visible: true,
|
visible: true,
|
||||||
}))}
|
}))}
|
||||||
columns={structure.columns.reduce((acc, val) => {
|
columns={structure.columns.reduce(
|
||||||
acc[val] = {value: val, resizable: true};
|
(acc, val) =>
|
||||||
return acc;
|
Object.assign({}, acc, {[val]: {value: val, resizable: true}}),
|
||||||
}, {})}
|
{},
|
||||||
|
)}
|
||||||
zebra={true}
|
zebra={true}
|
||||||
rows={structure.rows || []}
|
rows={structure.rows || []}
|
||||||
horizontallyScrollable={true}
|
horizontallyScrollable={true}
|
||||||
@@ -297,7 +314,7 @@ function renderDatabaseColumns(structure: ?Structure) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderDatabaseIndexes(structure: ?Structure) {
|
function renderDatabaseIndexes(structure: Structure | null) {
|
||||||
if (!structure) {
|
if (!structure) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -309,10 +326,11 @@ function renderDatabaseIndexes(structure: ?Structure) {
|
|||||||
key: name,
|
key: name,
|
||||||
visible: true,
|
visible: true,
|
||||||
}))}
|
}))}
|
||||||
columns={structure.indexesColumns.reduce((acc, val) => {
|
columns={structure.indexesColumns.reduce(
|
||||||
acc[val] = {value: val, resizable: true};
|
(acc, val) =>
|
||||||
return acc;
|
Object.assign({}, acc, {[val]: {value: val, resizable: true}}),
|
||||||
}, {})}
|
{},
|
||||||
|
)}
|
||||||
zebra={true}
|
zebra={true}
|
||||||
rows={structure.indexesValues || []}
|
rows={structure.indexesValues || []}
|
||||||
horizontallyScrollable={true}
|
horizontallyScrollable={true}
|
||||||
@@ -335,13 +353,13 @@ function renderQueryHistory(history: Array<Query>) {
|
|||||||
resizable: true,
|
resizable: true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
const rows = [];
|
const rows: TableRows = [];
|
||||||
if (history.length > 0) {
|
if (history.length > 0) {
|
||||||
for (const query of history) {
|
for (const query of history) {
|
||||||
const time = query.time;
|
const time = query.time;
|
||||||
const value = query.value;
|
const value = query.value;
|
||||||
rows.push({
|
rows.push({
|
||||||
key: query,
|
key: value,
|
||||||
columns: {time: {value: time}, query: {value: value}},
|
columns: {time: {value: time}, query: {value: value}},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -349,8 +367,7 @@ function renderQueryHistory(history: Array<Query>) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<FlexRow grow={true}>
|
<FlexRow grow={true}>
|
||||||
<ManagedTable
|
<QueryHistoryManagedTable
|
||||||
style={{paddingLeft: 16}}
|
|
||||||
floating={false}
|
floating={false}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
columnSizes={{time: 75}}
|
columnSizes={{time: 75}}
|
||||||
@@ -363,15 +380,15 @@ function renderQueryHistory(history: Array<Query>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type PageInfoProps = {
|
type PageInfoProps = {
|
||||||
currentRow: number,
|
currentRow: number;
|
||||||
count: number,
|
count: number;
|
||||||
totalRows: number,
|
totalRows: number;
|
||||||
onChange: (currentRow: number, count: number) => void,
|
onChange: (currentRow: number, count: number) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PageInfo extends Component<
|
class PageInfo extends Component<
|
||||||
PageInfoProps,
|
PageInfoProps,
|
||||||
{isOpen: boolean, inputValue: string},
|
{isOpen: boolean; inputValue: string}
|
||||||
> {
|
> {
|
||||||
constructor(props: PageInfoProps) {
|
constructor(props: PageInfoProps) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -382,11 +399,11 @@ class PageInfo extends Component<
|
|||||||
this.setState({isOpen: true});
|
this.setState({isOpen: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
onInputChanged(e) {
|
onInputChanged(e: ChangeEvent<any>) {
|
||||||
this.setState({inputValue: e.target.value});
|
this.setState({inputValue: e.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
onSubmit(e: SyntheticKeyboardEvent<>) {
|
onSubmit(e: KeyboardEvent) {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
const rowNumber = parseInt(this.state.inputValue, 10);
|
const rowNumber = parseInt(this.state.inputValue, 10);
|
||||||
this.props.onChange(rowNumber - 1, this.props.count);
|
this.props.onChange(rowNumber - 1, this.props.count);
|
||||||
@@ -396,7 +413,7 @@ class PageInfo extends Component<
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<FlexRow grow={true} alignItems={'center'}>
|
<PageInfoContainer grow={true}>
|
||||||
<div style={{flex: 1}} />
|
<div style={{flex: 1}} />
|
||||||
<Text>
|
<Text>
|
||||||
{this.props.count === this.props.totalRows
|
{this.props.count === this.props.totalRows
|
||||||
@@ -410,7 +427,7 @@ class PageInfo extends Component<
|
|||||||
{this.state.isOpen ? (
|
{this.state.isOpen ? (
|
||||||
<Input
|
<Input
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
placeholder={this.props.currentRow + 1}
|
placeholder={(this.props.currentRow + 1).toString()}
|
||||||
onChange={this.onInputChanged.bind(this)}
|
onChange={this.onInputChanged.bind(this)}
|
||||||
onKeyDown={this.onSubmit.bind(this)}
|
onKeyDown={this.onSubmit.bind(this)}
|
||||||
/>
|
/>
|
||||||
@@ -421,7 +438,7 @@ class PageInfo extends Component<
|
|||||||
Go To Row
|
Go To Row
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</FlexRow>
|
</PageInfoContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -429,6 +446,7 @@ class PageInfo extends Component<
|
|||||||
export default class DatabasesPlugin extends FlipperPlugin<
|
export default class DatabasesPlugin extends FlipperPlugin<
|
||||||
DatabasesPluginState,
|
DatabasesPluginState,
|
||||||
Actions,
|
Actions,
|
||||||
|
{}
|
||||||
> {
|
> {
|
||||||
databaseClient: DatabaseClient;
|
databaseClient: DatabaseClient;
|
||||||
|
|
||||||
@@ -451,7 +469,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
queryHistory: [],
|
queryHistory: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
reducers = [
|
reducers = ([
|
||||||
[
|
[
|
||||||
'UpdateDatabases',
|
'UpdateDatabases',
|
||||||
(
|
(
|
||||||
@@ -648,7 +666,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
'NextPage',
|
'NextPage',
|
||||||
(
|
(
|
||||||
state: DatabasesPluginState,
|
state: DatabasesPluginState,
|
||||||
event: UpdatePageEvent,
|
_event: UpdatePageEvent,
|
||||||
): DatabasesPluginState => {
|
): DatabasesPluginState => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -661,7 +679,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
'PreviousPage',
|
'PreviousPage',
|
||||||
(
|
(
|
||||||
state: DatabasesPluginState,
|
state: DatabasesPluginState,
|
||||||
event: UpdatePageEvent,
|
_event: UpdatePageEvent,
|
||||||
): DatabasesPluginState => {
|
): DatabasesPluginState => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -674,7 +692,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
'Execute',
|
'Execute',
|
||||||
(
|
(
|
||||||
state: DatabasesPluginState,
|
state: DatabasesPluginState,
|
||||||
results: ExecuteEvent,
|
_results: ExecuteEvent,
|
||||||
): DatabasesPluginState => {
|
): DatabasesPluginState => {
|
||||||
const timeBefore = Date.now();
|
const timeBefore = Date.now();
|
||||||
if (
|
if (
|
||||||
@@ -756,7 +774,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
'Refresh',
|
'Refresh',
|
||||||
(
|
(
|
||||||
state: DatabasesPluginState,
|
state: DatabasesPluginState,
|
||||||
event: RefreshEvent,
|
_event: RefreshEvent,
|
||||||
): DatabasesPluginState => {
|
): DatabasesPluginState => {
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -831,7 +849,30 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
].reduce((acc, val) => {
|
] as Array<
|
||||||
|
[
|
||||||
|
string,
|
||||||
|
(
|
||||||
|
state: DatabasesPluginState,
|
||||||
|
event: UpdateQueryEvent,
|
||||||
|
) => DatabasesPluginState,
|
||||||
|
]
|
||||||
|
>).reduce(
|
||||||
|
(
|
||||||
|
acc: {
|
||||||
|
[name: string]: (
|
||||||
|
state: DatabasesPluginState,
|
||||||
|
event: UpdateQueryEvent,
|
||||||
|
) => DatabasesPluginState;
|
||||||
|
},
|
||||||
|
val: [
|
||||||
|
string,
|
||||||
|
(
|
||||||
|
state: DatabasesPluginState,
|
||||||
|
event: UpdateQueryEvent,
|
||||||
|
) => DatabasesPluginState,
|
||||||
|
],
|
||||||
|
) => {
|
||||||
const name = val[0];
|
const name = val[0];
|
||||||
const f = val[1];
|
const f = val[1];
|
||||||
|
|
||||||
@@ -841,7 +882,9 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
return newState;
|
return newState;
|
||||||
};
|
};
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
onStateChanged(
|
onStateChanged(
|
||||||
previousState: DatabasesPluginState,
|
previousState: DatabasesPluginState,
|
||||||
@@ -938,6 +981,12 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// to keep eslint happy
|
||||||
|
constructor(props: FlipperPluginProps<{}>) {
|
||||||
|
super(props);
|
||||||
|
this.databaseClient = new DatabaseClient(this.client);
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.databaseClient = new DatabaseClient(this.client);
|
this.databaseClient = new DatabaseClient(this.client);
|
||||||
this.databaseClient.getDatabases({}).then((databases) => {
|
this.databaseClient.getDatabases({}).then((databases) => {
|
||||||
@@ -1026,7 +1075,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
this.setState({query: selected.target.value});
|
this.setState({query: selected.target.value});
|
||||||
};
|
};
|
||||||
|
|
||||||
onGoToRow = (row: number, count: number) => {
|
onGoToRow = (row: number, _count: number) => {
|
||||||
this.dispatchAction({type: 'GoToRow', row: row});
|
this.dispatchAction({type: 'GoToRow', row: row});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1092,7 +1141,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
sidebarRows = (id: number, table: QueriedTable) => {
|
sidebarRows(id: number, table: QueriedTable): TableRows {
|
||||||
const columns = table.columns;
|
const columns = table.columns;
|
||||||
const row = table.rows[id];
|
const row = table.rows[id];
|
||||||
if (columns.length === 1) {
|
if (columns.length === 1) {
|
||||||
@@ -1116,14 +1165,14 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
}
|
}
|
||||||
return sidebarArray;
|
return sidebarArray;
|
||||||
} else {
|
} else {
|
||||||
return columns.map<Object>((column, i) =>
|
return columns.map((column, i) =>
|
||||||
this.buildSidebarRow(columns[i], row.columns[columns[i]].value),
|
this.buildSidebarRow(columns[i], row.columns[columns[i]].value),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
buildSidebarRow = (key: string, val: any) => {
|
buildSidebarRow(key: string, val: any): TableBodyRow {
|
||||||
let output = '';
|
let output: any = '';
|
||||||
// TODO(T60896483): Narrow the scope of this try/catch block.
|
// TODO(T60896483): Narrow the scope of this try/catch block.
|
||||||
try {
|
try {
|
||||||
const parsed = JSON.parse(val.props.children);
|
const parsed = JSON.parse(val.props.children);
|
||||||
@@ -1147,9 +1196,9 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
},
|
},
|
||||||
key: key,
|
key: key,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
renderQuery(query: ?QueryResult) {
|
renderQuery(query: QueryResult | null) {
|
||||||
if (!query || query === null) {
|
if (!query || query === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1170,10 +1219,11 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
key: name,
|
key: name,
|
||||||
visible: true,
|
visible: true,
|
||||||
}))}
|
}))}
|
||||||
columns={columns.reduce((acc, val) => {
|
columns={columns.reduce(
|
||||||
acc[val] = {value: val, resizable: true};
|
(acc, val) =>
|
||||||
return acc;
|
Object.assign({}, acc, {[val]: {value: val, resizable: true}}),
|
||||||
}, {})}
|
{},
|
||||||
|
)}
|
||||||
zebra={true}
|
zebra={true}
|
||||||
rows={rows}
|
rows={rows}
|
||||||
horizontallyScrollable={true}
|
horizontallyScrollable={true}
|
||||||
@@ -1183,7 +1233,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
table: {
|
table: {
|
||||||
columns: columns,
|
columns: columns,
|
||||||
rows: rows,
|
rows: rows,
|
||||||
highlightedRows: highlightedRows,
|
highlightedRows: highlightedRows.map(parseInt),
|
||||||
},
|
},
|
||||||
id: null,
|
id: null,
|
||||||
count: null,
|
count: null,
|
||||||
@@ -1270,10 +1320,10 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
<Select
|
<Select
|
||||||
options={this.state.databases
|
options={this.state.databases
|
||||||
.map((x) => x.name)
|
.map((x) => x.name)
|
||||||
.reduce((obj, item) => {
|
.reduce(
|
||||||
obj[item] = item;
|
(obj, item) => Object.assign({}, obj, {[item]: item}),
|
||||||
return obj;
|
{},
|
||||||
}, {})}
|
)}
|
||||||
selected={
|
selected={
|
||||||
this.state.databases[this.state.selectedDatabase - 1]?.name
|
this.state.databases[this.state.selectedDatabase - 1]?.name
|
||||||
}
|
}
|
||||||
@@ -1296,10 +1346,10 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
<Select
|
<Select
|
||||||
options={this.state.databases
|
options={this.state.databases
|
||||||
.map((x) => x.name)
|
.map((x) => x.name)
|
||||||
.reduce((obj, item) => {
|
.reduce(
|
||||||
obj[item] = item;
|
(obj, item) => Object.assign({}, obj, {[item]: item}),
|
||||||
return obj;
|
{},
|
||||||
}, {})}
|
)}
|
||||||
selected={
|
selected={
|
||||||
this.state.databases[this.state.selectedDatabase - 1]?.name
|
this.state.databases[this.state.selectedDatabase - 1]?.name
|
||||||
}
|
}
|
||||||
@@ -1323,7 +1373,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
this.state.query !== null &&
|
this.state.query !== null &&
|
||||||
typeof this.state.query !== 'undefined'
|
typeof this.state.query !== 'undefined'
|
||||||
? this.state.query.value
|
? this.state.query.value
|
||||||
: null
|
: undefined
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
@@ -1333,7 +1383,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
<ButtonGroup>
|
<ButtonGroup>
|
||||||
<Button
|
<Button
|
||||||
icon={'star'}
|
icon={'star'}
|
||||||
iconSize={14}
|
iconSize={12}
|
||||||
iconVariant={
|
iconVariant={
|
||||||
this.state.query !== null &&
|
this.state.query !== null &&
|
||||||
typeof this.state.query !== 'undefined' &&
|
typeof this.state.query !== 'undefined' &&
|
||||||
@@ -1386,15 +1436,7 @@ export default class DatabasesPlugin extends FlipperPlugin<
|
|||||||
? this.renderQuery(this.state.queryResult)
|
? this.renderQuery(this.state.queryResult)
|
||||||
: null}
|
: null}
|
||||||
{this.state.viewMode === 'tableInfo' ? (
|
{this.state.viewMode === 'tableInfo' ? (
|
||||||
<Textarea
|
<TableInfoTextArea
|
||||||
style={{
|
|
||||||
width: '98%',
|
|
||||||
height: '100%',
|
|
||||||
marginLeft: '1%',
|
|
||||||
marginTop: '1%',
|
|
||||||
marginBottom: '1%',
|
|
||||||
readOnly: true,
|
|
||||||
}}
|
|
||||||
value={sqlFormatter.format(this.state.tableInfo)}
|
value={sqlFormatter.format(this.state.tableInfo)}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
@@ -3,12 +3,18 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"title": "Databases",
|
"title": "Databases",
|
||||||
"icon": "internet",
|
"icon": "internet",
|
||||||
"main": "index.js",
|
"main": "index.tsx",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": ["flipper-plugin"],
|
"keywords": [
|
||||||
|
"flipper-plugin"
|
||||||
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sql-formatter": "^2.3.3",
|
"dateformat": "^3.0.3",
|
||||||
"dateformat": "^3.0.3"
|
"sql-formatter": "^2.3.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/dateformat": "^3.0.1",
|
||||||
|
"@types/sql-formatter": "^2.3.0"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"email": "oncall+flipper@xmail.facebook.com",
|
"email": "oncall+flipper@xmail.facebook.com",
|
||||||
|
|||||||
@@ -1854,6 +1854,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/d3-path" "*"
|
"@types/d3-path" "*"
|
||||||
|
|
||||||
|
"@types/dateformat@^3.0.1":
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
|
||||||
|
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
|
||||||
|
|
||||||
"@types/debug@^4.1.5":
|
"@types/debug@^4.1.5":
|
||||||
version "4.1.5"
|
version "4.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
|
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
|
||||||
@@ -2261,6 +2266,11 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/sql-formatter@^2.3.0":
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/sql-formatter/-/sql-formatter-2.3.0.tgz#d2584c54f865fd57a7fe7e88ee8ed3623b23da33"
|
||||||
|
integrity sha512-Xh9kEOaKWhm3vYD5lUjYFFiSfpN4y3/iQCJUAVwFaQ1rVvHs4WXTa5C8E7gyF3kxwsMS8KgttW7WBAPtFlsvAg==
|
||||||
|
|
||||||
"@types/stack-utils@^1.0.1":
|
"@types/stack-utils@^1.0.1":
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
|
||||||
|
|||||||
Reference in New Issue
Block a user