TableNativePlugin
Summary: _typescript_ Reviewed By: priteshrnandgaonkar Differential Revision: D16828096 fbshipit-source-id: 5850ac4dbf120d2e6b38761701b44d20565d00e7
This commit is contained in:
committed by
Facebook Github Bot
parent
3730167b77
commit
0ebacecaf6
@@ -246,7 +246,7 @@ export default class Client extends EventEmitter {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
this.store.dispatch(registerPlugins(nativeplugins));
|
this.store.dispatch(registerPlugins(nativeplugins as any));
|
||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,89 +5,86 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import ManagedDataInspector from '../ui/components/data-inspector/ManagedDataInspector';
|
||||||
ManagedDataInspector,
|
import Panel from '../ui/components/Panel';
|
||||||
Panel,
|
import {colors} from '../ui/components/colors';
|
||||||
colors,
|
import styled from 'react-emotion';
|
||||||
styled,
|
import Text from '../ui/components/Text';
|
||||||
Text,
|
import Toolbar from '../ui/components/Toolbar';
|
||||||
Toolbar,
|
import Spacer from '../ui/components/Toolbar';
|
||||||
Spacer,
|
import Button from '../ui/components/Button';
|
||||||
Button,
|
import Select from '../ui/components/Select';
|
||||||
Select,
|
|
||||||
} from 'flipper';
|
|
||||||
import ErrorBlock from '../ui/components/ErrorBlock';
|
import ErrorBlock from '../ui/components/ErrorBlock';
|
||||||
import FlexColumn from '../ui/components/FlexColumn';
|
import FlexColumn from '../ui/components/FlexColumn';
|
||||||
import DetailSidebar from '../chrome/DetailSidebar.tsx';
|
|
||||||
import {FlipperPlugin} from '../plugin.tsx';
|
|
||||||
import SearchableTable from '../ui/components/searchable/SearchableTable';
|
import SearchableTable from '../ui/components/searchable/SearchableTable';
|
||||||
import textContent from '../utils/textContent.tsx';
|
import TableHighlightedRows from '../ui/components/table/types';
|
||||||
import createPaste from '../fb-stubs/createPaste.tsx';
|
import TableRows from '../ui/components/table/types';
|
||||||
|
import TableColumnSizes from '../ui/components/table/types';
|
||||||
import type {Node} from 'react';
|
import TableColumns from '../ui/components/table/types';
|
||||||
import type {
|
import TableColumnOrderVal from '../ui/components/table/types';
|
||||||
TableHighlightedRows,
|
import TableBodyRow from '../ui/components/table/types';
|
||||||
TableRows,
|
import DetailSidebar from '../chrome/DetailSidebar';
|
||||||
TableColumnSizes,
|
import {FlipperPlugin} from '../plugin';
|
||||||
TableColumns,
|
import textContent from '../utils/textContent';
|
||||||
TableColumnOrderVal,
|
import createPaste from '../fb-stubs/createPaste';
|
||||||
TableBodyRow,
|
import {ReactNode} from 'react';
|
||||||
} from 'flipper';
|
import React from 'react';
|
||||||
|
import {KeyboardActions} from 'src/MenuBar';
|
||||||
|
|
||||||
type ID = string;
|
type ID = string;
|
||||||
|
|
||||||
type TableMetadata = {
|
type TableMetadata = {
|
||||||
topToolbar?: ToolbarSection,
|
topToolbar?: ToolbarSection;
|
||||||
bottomToolbar?: ToolbarSection,
|
bottomToolbar?: ToolbarSection;
|
||||||
columns: TableColumns,
|
columns: TableColumns;
|
||||||
columnSizes?: TableColumnSizes,
|
columnSizes?: TableColumnSizes;
|
||||||
columnOrder?: Array<TableColumnOrderVal>,
|
columnOrder?: Array<TableColumnOrderVal>;
|
||||||
filterableColumns?: Set<string>,
|
filterableColumns?: Set<string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PersistedState = {|
|
type PersistedState = {
|
||||||
rows: TableRows,
|
rows: TableRows;
|
||||||
datas: {[key: ID]: NumberedRowData},
|
datas: {[key: string]: NumberedRowData};
|
||||||
tableMetadata: ?TableMetadata,
|
tableMetadata: TableMetadata | null | undefined;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type State = {|
|
type State = {
|
||||||
selectedIds: Array<ID>,
|
selectedIds: Array<ID>;
|
||||||
error: ?string,
|
error: string | null | undefined;
|
||||||
|};
|
};
|
||||||
|
|
||||||
type RowData = {
|
type RowData = {
|
||||||
id: string,
|
id: string;
|
||||||
columns: {[key: string]: any},
|
columns: {[key: string]: any};
|
||||||
sidebar?: Array<SidebarSection>,
|
sidebar?: Array<SidebarSection>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type NumberedRowData = {
|
type NumberedRowData = {
|
||||||
id: string,
|
id: string;
|
||||||
columns: {[key: string]: any},
|
columns: {[key: string]: any};
|
||||||
sidebar?: Array<SidebarSection>,
|
sidebar?: Array<SidebarSection>;
|
||||||
rowNumber: number,
|
rowNumber: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type SidebarSection = JsonSection | ToolbarSection;
|
type SidebarSection = JsonSection | ToolbarSection;
|
||||||
type JsonSection = {
|
type JsonSection = {
|
||||||
type: 'json',
|
type: 'json';
|
||||||
title: string,
|
title: string;
|
||||||
content: string,
|
content: string;
|
||||||
};
|
};
|
||||||
type ToolbarSection = {
|
type ToolbarSection = {
|
||||||
type: 'toolbar',
|
type: 'toolbar';
|
||||||
items: Array<ToolbarItem>,
|
items: Array<ToolbarItem>;
|
||||||
};
|
};
|
||||||
type ToolbarItem =
|
type ToolbarItem =
|
||||||
| {type: 'link', destination: string, label: string}
|
| {type: 'link'; destination: string; label: string}
|
||||||
| {
|
| {
|
||||||
type: 'input',
|
type: 'input';
|
||||||
inputType: 'select',
|
inputType: 'select';
|
||||||
id: string,
|
id: string;
|
||||||
label: string,
|
label: string;
|
||||||
options: Array<string>,
|
options: Array<string>;
|
||||||
value: string,
|
value: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const NonWrappingText = styled(Text)({
|
const NonWrappingText = styled(Text)({
|
||||||
@@ -97,7 +94,7 @@ const NonWrappingText = styled(Text)({
|
|||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
});
|
});
|
||||||
|
|
||||||
const BooleanValue = styled(NonWrappingText)(props => ({
|
const BooleanValue = styled(NonWrappingText)((props: {active?: boolean}) => ({
|
||||||
'&::before': {
|
'&::before': {
|
||||||
content: '""',
|
content: '""',
|
||||||
display: 'inline-block',
|
display: 'inline-block',
|
||||||
@@ -110,7 +107,7 @@ const BooleanValue = styled(NonWrappingText)(props => ({
|
|||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const Label = styled('Span')({
|
const Label = styled('span')({
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: '#90949c',
|
color: '#90949c',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
@@ -119,7 +116,7 @@ const Label = styled('Span')({
|
|||||||
marginRight: 12,
|
marginRight: 12,
|
||||||
});
|
});
|
||||||
|
|
||||||
function renderValue({type, value}: {type: string, value: any}) {
|
function renderValue({type, value}: {type: string; value: any}) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'boolean':
|
case 'boolean':
|
||||||
return (
|
return (
|
||||||
@@ -132,7 +129,10 @@ function renderValue({type, value}: {type: string, value: any}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildRow(rowData: RowData, previousRowData: ?RowData): TableBodyRow {
|
function buildRow(
|
||||||
|
rowData: RowData,
|
||||||
|
previousRowData: RowData | null | undefined,
|
||||||
|
): TableBodyRow {
|
||||||
if (!rowData.columns) {
|
if (!rowData.columns) {
|
||||||
throw new Error('defaultBuildRow used with incorrect data format.');
|
throw new Error('defaultBuildRow used with incorrect data format.');
|
||||||
}
|
}
|
||||||
@@ -140,8 +140,13 @@ function buildRow(rowData: RowData, previousRowData: ?RowData): TableBodyRow {
|
|||||||
previousRowData && previousRowData.columns
|
previousRowData && previousRowData.columns
|
||||||
? Object.keys(previousRowData.columns).reduce((map, key) => {
|
? Object.keys(previousRowData.columns).reduce((map, key) => {
|
||||||
if (key !== 'id') {
|
if (key !== 'id') {
|
||||||
|
let value = null;
|
||||||
|
if (previousRowData && previousRowData.columns) {
|
||||||
|
value = previousRowData.columns[key].value;
|
||||||
|
}
|
||||||
|
|
||||||
map[key] = {
|
map[key] = {
|
||||||
value: (previousRowData?.columns || {})[key].value,
|
value,
|
||||||
isFilterable: true,
|
isFilterable: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -183,7 +188,7 @@ function renderToolbar(section: ToolbarSection) {
|
|||||||
obj[item] = item;
|
obj[item] = item;
|
||||||
return obj;
|
return obj;
|
||||||
}, {})}
|
}, {})}
|
||||||
value={item.value}
|
selected={item.value}
|
||||||
onChange={() => {}}
|
onChange={() => {}}
|
||||||
/>,
|
/>,
|
||||||
];
|
];
|
||||||
@@ -197,7 +202,7 @@ function renderToolbar(section: ToolbarSection) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSidebarForRow(rowData: RowData): Node {
|
function renderSidebarForRow(rowData: RowData): ReactNode {
|
||||||
if (!rowData.sidebar) {
|
if (!rowData.sidebar) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -207,7 +212,10 @@ function renderSidebarForRow(rowData: RowData): Node {
|
|||||||
return rowData.sidebar.map(renderSidebarSection);
|
return rowData.sidebar.map(renderSidebarSection);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSidebarSection(section: SidebarSection, index: number): Node {
|
function renderSidebarSection(
|
||||||
|
section: SidebarSection,
|
||||||
|
index: number,
|
||||||
|
): ReactNode {
|
||||||
switch (section.type) {
|
switch (section.type) {
|
||||||
case 'json':
|
case 'json':
|
||||||
return (
|
return (
|
||||||
@@ -227,12 +235,13 @@ function renderSidebarSection(section: SidebarSection, index: number): Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type IncomingMessage =
|
type IncomingMessage =
|
||||||
| {method: 'updateRows', data: Array<RowData>}
|
| {method: 'updateRows'; data: Array<RowData>}
|
||||||
| {method: 'clearTable'};
|
| {method: 'clearTable'};
|
||||||
|
|
||||||
export default function createTableNativePlugin(id: string, title: string) {
|
export default function createTableNativePlugin(id: string, title: string) {
|
||||||
return class extends FlipperPlugin<State, *, PersistedState> {
|
// @ts-ignore
|
||||||
static keyboardActions = ['clear', 'createPaste'];
|
return class extends FlipperPlugin<State, any, PersistedState> {
|
||||||
|
static keyboardActions: KeyboardActions = ['clear', 'createPaste'];
|
||||||
static id = id || '';
|
static id = id || '';
|
||||||
static title = title || '';
|
static title = title || '';
|
||||||
|
|
||||||
@@ -245,7 +254,7 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
static typedPersistedStateReducer = (
|
static typedPersistedStateReducer = (
|
||||||
persistedState: PersistedState,
|
persistedState: PersistedState,
|
||||||
message: IncomingMessage,
|
message: IncomingMessage,
|
||||||
): $Shape<PersistedState> => {
|
): Partial<PersistedState> => {
|
||||||
if (message.method === 'updateRows') {
|
if (message.method === 'updateRows') {
|
||||||
const newRows = [];
|
const newRows = [];
|
||||||
const newData = {};
|
const newData = {};
|
||||||
@@ -256,7 +265,7 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
`updateRows: row is missing id: ${JSON.stringify(rowData)}`,
|
`updateRows: row is missing id: ${JSON.stringify(rowData)}`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const previousRowData: ?NumberedRowData =
|
const previousRowData: NumberedRowData | null | undefined =
|
||||||
persistedState.datas[rowData.id];
|
persistedState.datas[rowData.id];
|
||||||
const newRow: TableBodyRow = buildRow(rowData, previousRowData);
|
const newRow: TableBodyRow = buildRow(rowData, previousRowData);
|
||||||
if (persistedState.datas[rowData.id] == null) {
|
if (persistedState.datas[rowData.id] == null) {
|
||||||
@@ -292,14 +301,20 @@ export default function createTableNativePlugin(id: string, title: string) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static persistedStateReducer = (
|
static persistedStateReducer(
|
||||||
persistedState: PersistedState,
|
persistedState: PersistedState,
|
||||||
method: string,
|
method: 'updateRows' | 'clearTable',
|
||||||
data: any,
|
data: Array<RowData> | undefined,
|
||||||
): $Shape<PersistedState> => {
|
): Partial<PersistedState> {
|
||||||
// $FlowFixMe Unsafely treat the recieved message as what we're expecting.
|
const message: IncomingMessage =
|
||||||
return this.typedPersistedStateReducer(persistedState, {method, data});
|
method === 'updateRows'
|
||||||
};
|
? {
|
||||||
|
method,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
: {method};
|
||||||
|
return this.typedPersistedStateReducer(persistedState, message);
|
||||||
|
}
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
selectedIds: [],
|
selectedIds: [],
|
||||||
Reference in New Issue
Block a user