Undo nativeplugin changes to createTablePlugin.js
Summary: Now that it has been inlined into TableNativePlugin, I'm reverting it back to it was before to keep it simple. Reviewed By: passy Differential Revision: D14800383 fbshipit-source-id: 81725134b6598c03e3ddfb1eb9269d463815dc82
This commit is contained in:
committed by
Facebook Github Bot
parent
287cad2f4b
commit
40b1c569ad
@@ -8,39 +8,28 @@
|
||||
import {createTablePlugin} from '../createTablePlugin.js';
|
||||
import {FlipperPlugin} from '../plugin.js';
|
||||
|
||||
const KNOWN_METADATA_PROPS = {
|
||||
const PROPS = {
|
||||
method: 'method',
|
||||
resetMethod: 'resetMethod',
|
||||
columns: {},
|
||||
columnSizes: {},
|
||||
renderSidebar: () => {},
|
||||
buildRow: () => {
|
||||
return {columns: {}, key: 'someKey'};
|
||||
},
|
||||
};
|
||||
|
||||
const DYNAMIC_METADATA_PROPS = {
|
||||
method: 'method',
|
||||
resetMethod: 'resetMethod',
|
||||
id: 'testytest',
|
||||
title: 'TestPlugin',
|
||||
renderSidebar: () => {},
|
||||
buildRow: () => {
|
||||
return {columns: {}, key: 'someKey'};
|
||||
},
|
||||
buildRow: () => {},
|
||||
};
|
||||
|
||||
test('createTablePlugin returns FlipperPlugin', () => {
|
||||
const tablePlugin = createTablePlugin({...KNOWN_METADATA_PROPS});
|
||||
const tablePlugin = createTablePlugin({...PROPS});
|
||||
expect(tablePlugin.prototype).toBeInstanceOf(FlipperPlugin);
|
||||
});
|
||||
|
||||
test('persistedStateReducer is resetting data', () => {
|
||||
const resetMethod = 'resetMethod';
|
||||
const tablePlugin = createTablePlugin({...KNOWN_METADATA_PROPS, resetMethod});
|
||||
const tablePlugin = createTablePlugin({...PROPS, resetMethod});
|
||||
|
||||
const ps = {
|
||||
datas: {'1': {id: '1', rowNumber: 0}},
|
||||
// $FlowFixMe persistedStateReducer exists for createTablePlugin
|
||||
const {rows, datas} = tablePlugin.persistedStateReducer(
|
||||
{
|
||||
datas: {'1': {id: '1'}},
|
||||
rows: [
|
||||
{
|
||||
key: '1',
|
||||
@@ -51,14 +40,10 @@ test('persistedStateReducer is resetting data', () => {
|
||||
},
|
||||
},
|
||||
],
|
||||
tableMetadata: null,
|
||||
};
|
||||
|
||||
if (!tablePlugin.persistedStateReducer) {
|
||||
expect(tablePlugin.persistedStateReducer).toBeDefined();
|
||||
return;
|
||||
}
|
||||
const {rows, datas} = tablePlugin.persistedStateReducer(ps, resetMethod, {});
|
||||
},
|
||||
resetMethod,
|
||||
{},
|
||||
);
|
||||
|
||||
expect(datas).toEqual({});
|
||||
expect(rows).toEqual([]);
|
||||
@@ -66,44 +51,18 @@ test('persistedStateReducer is resetting data', () => {
|
||||
|
||||
test('persistedStateReducer is adding data', () => {
|
||||
const method = 'method';
|
||||
const tablePlugin = createTablePlugin({...KNOWN_METADATA_PROPS, method});
|
||||
const tablePlugin = createTablePlugin({...PROPS, method});
|
||||
const id = '1';
|
||||
|
||||
const ps = {
|
||||
// $FlowFixMe persistedStateReducer exists for createTablePlugin
|
||||
const {rows, datas} = tablePlugin.persistedStateReducer(
|
||||
{
|
||||
datas: {},
|
||||
rows: [],
|
||||
tableMetadata: null,
|
||||
};
|
||||
|
||||
if (!tablePlugin.persistedStateReducer) {
|
||||
expect(tablePlugin.persistedStateReducer).toBeDefined();
|
||||
return;
|
||||
}
|
||||
const {rows, datas} = tablePlugin.persistedStateReducer(ps, method, {id});
|
||||
|
||||
expect(rows.length).toBe(1);
|
||||
expect(Object.keys(datas)).toEqual([id]);
|
||||
});
|
||||
|
||||
test('dyn persistedStateReducer is adding data', () => {
|
||||
const method = 'method';
|
||||
const tablePlugin = createTablePlugin({...DYNAMIC_METADATA_PROPS, method});
|
||||
const id = '1';
|
||||
|
||||
const ps = {
|
||||
datas: {},
|
||||
rows: [],
|
||||
tableMetadata: null,
|
||||
};
|
||||
|
||||
if (!tablePlugin.persistedStateReducer) {
|
||||
expect(tablePlugin.persistedStateReducer).toBeDefined();
|
||||
return;
|
||||
}
|
||||
const {rows, datas} = tablePlugin.persistedStateReducer(ps, method, {
|
||||
id,
|
||||
columns: {},
|
||||
});
|
||||
},
|
||||
method,
|
||||
{id},
|
||||
);
|
||||
|
||||
expect(rows.length).toBe(1);
|
||||
expect(Object.keys(datas)).toEqual([id]);
|
||||
|
||||
@@ -10,9 +10,6 @@ import type {
|
||||
TableRows,
|
||||
TableColumnSizes,
|
||||
TableColumns,
|
||||
TableColumnOrder,
|
||||
TableColumnOrderVal,
|
||||
TableBodyRow,
|
||||
} from 'flipper';
|
||||
|
||||
import FlexColumn from './ui/components/FlexColumn';
|
||||
@@ -27,45 +24,20 @@ type ID = string;
|
||||
|
||||
type RowData = {
|
||||
id: ID,
|
||||
columns?: {[key: string]: any},
|
||||
details?: Object,
|
||||
};
|
||||
|
||||
type Numbered<T> = {
|
||||
...T,
|
||||
id: ID,
|
||||
rowNumber: number,
|
||||
};
|
||||
|
||||
type TableMetadata = {
|
||||
columns: TableColumns,
|
||||
columnSizes?: TableColumnSizes,
|
||||
columnOrder?: Array<TableColumnOrderVal>,
|
||||
filterableColumns?: Set<string>,
|
||||
};
|
||||
|
||||
type Props<T> = {|
|
||||
method: string,
|
||||
resetMethod?: string,
|
||||
...
|
||||
| {|
|
||||
columns: TableColumns,
|
||||
columnSizes?: TableColumnSizes,
|
||||
columnOrder?: TableColumnOrder,
|
||||
filterableColumns?: Set<string>,
|
||||
|}
|
||||
| {|
|
||||
id: string,
|
||||
title: string,
|
||||
|},
|
||||
columnSizes: TableColumnSizes,
|
||||
renderSidebar: (row: T) => any,
|
||||
buildRow: (row: T, previousData: ?T) => TableBodyRow,
|
||||
buildRow: (row: T) => any,
|
||||
|};
|
||||
|
||||
type PersistedState<T> = {|
|
||||
rows: TableRows,
|
||||
datas: {[key: ID]: Numbered<T>},
|
||||
tableMetadata: ?TableMetadata,
|
||||
datas: {[key: ID]: T},
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
@@ -81,9 +53,6 @@ type State = {|
|
||||
* of data objects or a single data object. Each data object represents a row in the table which is
|
||||
* build by calling the `buildRow` function argument.
|
||||
*
|
||||
* The component can be constructed directly with the table metadata in props,
|
||||
or if omitted, will call the mobile plugin to dynamically determine the table metadata.
|
||||
*
|
||||
* An optional resetMethod argument can be provided which will replace the current rows with the
|
||||
* data provided. This is useful when connecting to Flipper for this first time, or reconnecting to
|
||||
* the client in an unknown state.
|
||||
@@ -91,27 +60,17 @@ type State = {|
|
||||
export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
return class extends FlipperPlugin<State, *, PersistedState<T>> {
|
||||
static keyboardActions = ['clear', 'createPaste'];
|
||||
static id = props.id || '';
|
||||
static title = props.title || '';
|
||||
|
||||
static defaultPersistedState: PersistedState<T> = {
|
||||
rows: [],
|
||||
datas: {},
|
||||
tableMetadata: props.columns
|
||||
? {
|
||||
columns: props.columns,
|
||||
columnSizes: props.columnSizes,
|
||||
columnOrder: props.columnOrder,
|
||||
filterableColumns: props.filterableColumns,
|
||||
}
|
||||
: null,
|
||||
};
|
||||
|
||||
static persistedStateReducer = (
|
||||
persistedState: PersistedState<T>,
|
||||
method: string,
|
||||
payload: T | Array<T>,
|
||||
): $Shape<PersistedState<T>> => {
|
||||
): $Shape<PersistedState<RowData>> => {
|
||||
if (method === props.method) {
|
||||
const newRows = [];
|
||||
const newData = {};
|
||||
@@ -121,33 +80,17 @@ export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
if (data.id == null) {
|
||||
console.warn('The data sent did not contain an ID.', data);
|
||||
}
|
||||
const previousRowData: ?Numbered<T> = persistedState.datas[data.id];
|
||||
const newRow = props.buildRow(data, previousRowData);
|
||||
if (persistedState.datas[data.id] == null) {
|
||||
newData[data.id] = {
|
||||
...data,
|
||||
rowNumber: persistedState.rows.length + newRows.length,
|
||||
};
|
||||
newRows.push(newRow);
|
||||
} else {
|
||||
persistedState.rows = persistedState.rows
|
||||
.slice(0, persistedState.datas[data.id].rowNumber)
|
||||
.concat(
|
||||
[newRow],
|
||||
persistedState.rows.slice(
|
||||
persistedState.datas[data.id].rowNumber + 1,
|
||||
),
|
||||
);
|
||||
newData[data.id] = data;
|
||||
newRows.push(props.buildRow(data));
|
||||
}
|
||||
}
|
||||
return {
|
||||
...persistedState,
|
||||
datas: {...persistedState.datas, ...newData},
|
||||
rows: [...persistedState.rows, ...newRows],
|
||||
};
|
||||
} else if (method === props.resetMethod) {
|
||||
return {
|
||||
...persistedState,
|
||||
rows: [],
|
||||
datas: {},
|
||||
};
|
||||
@@ -160,23 +103,6 @@ export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
selectedIds: [],
|
||||
};
|
||||
|
||||
init() {
|
||||
this.getTableMetadata();
|
||||
}
|
||||
|
||||
getTableMetadata = () => {
|
||||
if (!this.props.persistedState.tableMetadata) {
|
||||
this.client.call('getMetadata').then(metadata => {
|
||||
this.props.setPersistedState({
|
||||
tableMetadata: {
|
||||
...metadata,
|
||||
filterableColumns: new Set(metadata.filterableColumns),
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
onKeyboardAction = (action: string) => {
|
||||
if (action === 'clear') {
|
||||
this.clear();
|
||||
@@ -196,16 +122,9 @@ export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
};
|
||||
|
||||
createPaste = () => {
|
||||
if (!this.props.persistedState.tableMetadata) {
|
||||
return;
|
||||
}
|
||||
let paste = '';
|
||||
const mapFn = row =>
|
||||
(
|
||||
(this.props.persistedState.tableMetadata &&
|
||||
Object.keys(this.props.persistedState.tableMetadata.columns)) ||
|
||||
[]
|
||||
)
|
||||
Object.keys(props.columns)
|
||||
.map(key => textContent(row.columns[key].value))
|
||||
.join('\t');
|
||||
|
||||
@@ -228,36 +147,8 @@ export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
});
|
||||
};
|
||||
|
||||
// We don't necessarily have the table metadata at the time when buildRow
|
||||
// is being used. This includes presentation layer info like which
|
||||
// columns should be filterable. This does a pass over the built rows and
|
||||
// applies that presentation layer information.
|
||||
applyMetadataToRows(rows: TableRows): TableRows {
|
||||
if (!this.props.persistedState.tableMetadata) {
|
||||
console.error(
|
||||
'applyMetadataToRows called without tableMetadata present',
|
||||
);
|
||||
return rows;
|
||||
}
|
||||
return rows.map(r => {
|
||||
return {
|
||||
...r,
|
||||
columns: Object.keys(r.columns).reduce((map, columnName) => {
|
||||
map[columnName].isFilterable =
|
||||
this.props.persistedState.tableMetadata &&
|
||||
this.props.persistedState.tableMetadata.filterableColumns
|
||||
? this.props.persistedState.tableMetadata.filterableColumns.has(
|
||||
columnName,
|
||||
)
|
||||
: false;
|
||||
return map;
|
||||
}, r.columns),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
renderSidebar = () => {
|
||||
const renderSidebar = props.renderSidebar;
|
||||
const {renderSidebar} = props;
|
||||
const {selectedIds} = this.state;
|
||||
const {datas} = this.props.persistedState;
|
||||
const selectedId = selectedIds.length !== 1 ? null : selectedIds[0];
|
||||
@@ -270,14 +161,7 @@ export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
};
|
||||
|
||||
render() {
|
||||
if (!this.props.persistedState.tableMetadata) {
|
||||
return 'Loading...';
|
||||
}
|
||||
const {
|
||||
columns,
|
||||
columnSizes,
|
||||
columnOrder,
|
||||
} = this.props.persistedState.tableMetadata;
|
||||
const {columns, columnSizes} = props;
|
||||
const {rows} = this.props.persistedState;
|
||||
|
||||
return (
|
||||
@@ -288,11 +172,10 @@ export function createTablePlugin<T: RowData>(props: Props<T>) {
|
||||
floating={false}
|
||||
multiline={true}
|
||||
columnSizes={columnSizes}
|
||||
columnOrder={columnOrder}
|
||||
columns={columns}
|
||||
onRowHighlighted={this.onRowHighlighted}
|
||||
multiHighlight={true}
|
||||
rows={this.applyMetadataToRows(rows)}
|
||||
rows={rows}
|
||||
stickyBottom={true}
|
||||
actions={<Button onClick={this.clear}>Clear Table</Button>}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user