/** * 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 {DataInspector} from 'flipper-plugin'; import Panel from '../ui/components/Panel'; import {colors} from '../ui/components/colors'; import styled from '@emotion/styled'; import Text from '../ui/components/Text'; import Toolbar from '../ui/components/Toolbar'; import Spacer from '../ui/components/Toolbar'; import Button from '../ui/components/Button'; import Select from '../ui/components/Select'; import ErrorBlock from '../ui/components/ErrorBlock'; import FlexColumn from '../ui/components/FlexColumn'; import SearchableTable from '../ui/components/searchable/SearchableTable'; import { TableHighlightedRows, TableRows, TableColumnSizes, TableColumns, TableColumnOrderVal, TableBodyRow, } from '../ui/components/table/types'; import {DetailSidebar} from 'flipper-plugin'; import {FlipperPlugin} from '../plugin'; import textContent from '../utils/textContent'; import createPaste from '../fb-stubs/createPaste'; import {ReactNode} from 'react'; import React from 'react'; import {KeyboardActions} from '../MenuBar'; import {BundledPluginDetails} from 'flipper-plugin-lib'; type ID = string; type TableMetadata = { topToolbar?: ToolbarSection; bottomToolbar?: ToolbarSection; columns: TableColumns; columnSizes?: TableColumnSizes; columnOrder?: Array; filterableColumns?: Set; }; type PersistedState = { rows: TableRows; datas: {[key: string]: NumberedRowData}; tableMetadata: TableMetadata | null | undefined; }; type State = { selectedIds: Array; error: string | null | undefined; }; type RowData = { id: string; columns: {[key: string]: any}; sidebar?: Array; }; type NumberedRowData = { id: string; columns: {[key: string]: any}; sidebar?: Array; rowNumber: number; }; type SidebarSection = JsonSection | ToolbarSection; type JsonSection = { type: 'json'; title: string; content: string; }; type ToolbarSection = { type: 'toolbar'; items: Array; }; type ToolbarItem = | {type: 'link'; destination: string; label: string} | { type: 'input'; inputType: 'select'; id: string; label: string; options: Array; value: string; }; const NonWrappingText = styled(Text)({ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', }); const BooleanValue = styled(NonWrappingText)<{active?: boolean}>((props) => ({ '&::before': { content: '""', display: 'inline-block', width: 8, height: 8, borderRadius: 4, backgroundColor: props.active ? colors.green : colors.red, marginRight: 5, marginTop: 1, }, })); const Label = styled.span({ fontSize: 12, color: '#90949c', fontWeight: 'bold', textTransform: 'uppercase', marginLeft: 5, marginRight: 12, }); function renderValue({type, value}: {type: string; value: any}) { switch (type) { case 'boolean': return ( {value.toString()} ); default: return value; } } function buildRow( rowData: RowData, previousRowData: RowData | null | undefined, ): TableBodyRow { if (!rowData.columns) { throw new Error('defaultBuildRow used with incorrect data format.'); } const oldColumns = previousRowData && previousRowData.columns ? Object.keys(previousRowData.columns).reduce( (map: {[key: string]: {value: any; isFilterable: boolean}}, key) => { if (key !== 'id') { let value = null; if (previousRowData && previousRowData.columns) { value = previousRowData.columns[key].value; } map[key] = { value, isFilterable: true, }; } return map; }, {}, ) : {}; const columns = Object.keys(rowData.columns).reduce((map, key) => { if (rowData.columns && key !== 'id') { const renderedValue = renderValue(rowData.columns[key]); map[key] = { value: renderedValue, isFilterable: true, }; } return map; }, oldColumns); return { columns, key: rowData.id, copyText: () => JSON.stringify(rowData), filterValue: rowData.id, }; } function renderToolbar(section: ToolbarSection) { const toolbarComponents = section.items.map((item, index) => { switch (item.type) { case 'link': return ( ); case 'input': return ( <>