From 53c557f923968bb9d4d429f5f5d427eae3bf4b8d Mon Sep 17 00:00:00 2001 From: Michel Weststrate Date: Wed, 7 Apr 2021 07:52:47 -0700 Subject: [PATCH] Move DataInspector to flipper-plugin Summary: This diff moves the rest of the DataInspector jungle to flipper-plugin. No actual improvements are made yet, but the code is decoupled from Electron and the legacy theming. For example by using Antd based context menus. Note that `ManagedDataInspector` is now rebranded `DataInspector`, as that is the only variation that should (and is) used publicly. For the interactionTracker removal, see next diff. SearchableDataInspector will be addressed in a next diff Reviewed By: passy Differential Revision: D27603125 fbshipit-source-id: 188bd000260e4e4704202ce02c7fc98319f0bc22 --- desktop/app/package.json | 1 - desktop/app/src/index.tsx | 14 +- desktop/app/src/plugins/TableNativePlugin.tsx | 6 +- desktop/app/src/ui/components/ContextMenu.tsx | 1 + .../src/ui/components/ContextMenuProvider.tsx | 1 + desktop/app/src/ui/components/Popover.tsx | 3 + desktop/app/src/ui/components/Popover2.tsx | 1 + desktop/app/src/ui/components/console.tsx | 4 +- .../SearchableDataInspector.tsx | 11 +- .../components/elements-inspector/sidebar.tsx | 4 +- desktop/app/src/ui/index.tsx | 10 +- desktop/flipper-plugin/package.json | 4 +- .../flipper-plugin/src/__tests__/api.node.tsx | 6 + desktop/flipper-plugin/src/index.ts | 16 +- desktop/flipper-plugin/src/ui/Highlight.tsx | 3 +- .../src/ui}/MarkerTimeline.tsx | 28 +-- .../src/ui}/__tests__/MarkerTimeline.node.tsx | 2 +- .../src/ui/__tests__/NUX.node.tsx | 2 +- .../src/ui/__tests__/Tracked.node.tsx | 2 +- .../MarkerTimeline.node.tsx.snap | 2 +- .../src/ui/data-inspector/DataDescription.tsx | 45 ++-- .../src/ui}/data-inspector/DataInspector.tsx | 198 ++++++++---------- .../src/ui}/data-inspector/DataPreview.tsx | 7 +- .../data-inspector/ManagedDataInspector.tsx | 53 +++-- .../TimelineDataDescription.tsx | 12 +- .../__tests__/DataInspector.node.tsx | 6 +- .../src/ui}/data-inspector/utils.tsx | 0 desktop/types/index.d.ts | 1 - desktop/types/string-natural-compare.d.ts | 12 -- desktop/yarn.lock | 5 + docs/extending/flipper-plugin.mdx | 3 + 31 files changed, 221 insertions(+), 242 deletions(-) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/MarkerTimeline.tsx (89%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/__tests__/MarkerTimeline.node.tsx (97%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap (86%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/data-inspector/DataInspector.tsx (84%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/data-inspector/DataPreview.tsx (94%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/data-inspector/ManagedDataInspector.tsx (76%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/data-inspector/TimelineDataDescription.tsx (84%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/data-inspector/__tests__/DataInspector.node.tsx (96%) rename desktop/{app/src/ui/components => flipper-plugin/src/ui}/data-inspector/utils.tsx (100%) delete mode 100644 desktop/types/string-natural-compare.d.ts diff --git a/desktop/app/package.json b/desktop/app/package.json index 7d807da66..c3b6a8442 100644 --- a/desktop/app/package.json +++ b/desktop/app/package.json @@ -72,7 +72,6 @@ "rsocket-types": "^0.0.25", "semver": "^7.3.5", "split2": "^3.2.2", - "string-natural-compare": "^3.0.0", "tmp": "^0.2.1", "uuid": "^8.3.2", "which": "^2.0.1", diff --git a/desktop/app/src/index.tsx b/desktop/app/src/index.tsx index c318ba8e5..58c38613c 100644 --- a/desktop/app/src/index.tsx +++ b/desktop/app/src/index.tsx @@ -95,15 +95,14 @@ export { export { DataValueExtractor, DataInspectorExpanded, -} from './ui/components/data-inspector/DataInspector'; -export {default as DataInspector} from './ui/components/data-inspector/DataInspector'; -export {default as ManagedDataInspector} from './ui/components/data-inspector/ManagedDataInspector'; -export {default as SearchableDataInspector} from './ui/components/data-inspector/SearchableDataInspector'; -export { - _DataDescription as DataDescription, DataDescriptionType, + DataDescription, + DataInspector, + MarkerTimeline, } from 'flipper-plugin'; -export {_HighlightManager as HighlightManager} from 'flipper-plugin'; +export {DataInspector as ManagedDataInspector} from 'flipper-plugin'; +export {default as SearchableDataInspector} from './ui/components/data-inspector/SearchableDataInspector'; +export {HighlightManager} from 'flipper-plugin'; export {default as Tabs} from './ui/components/Tabs'; export {default as Tab} from './ui/components/Tab'; export {default as Input} from './ui/components/Input'; @@ -160,7 +159,6 @@ export {default as VerticalRule} from './ui/components/VerticalRule'; export {default as Label} from './ui/components/Label'; export {default as Heading} from './ui/components/Heading'; export {Filter} from './ui/components/filter/types'; -export {default as MarkerTimeline} from './ui/components/MarkerTimeline'; export {default as StackTrace} from './ui/components/StackTrace'; export { SearchBox, diff --git a/desktop/app/src/plugins/TableNativePlugin.tsx b/desktop/app/src/plugins/TableNativePlugin.tsx index adec16687..019d1b814 100644 --- a/desktop/app/src/plugins/TableNativePlugin.tsx +++ b/desktop/app/src/plugins/TableNativePlugin.tsx @@ -7,7 +7,7 @@ * @format */ -import ManagedDataInspector from '../ui/components/data-inspector/ManagedDataInspector'; +import {DataInspector} from 'flipper-plugin'; import Panel from '../ui/components/Panel'; import {colors} from '../ui/components/colors'; import styled from '@emotion/styled'; @@ -232,7 +232,7 @@ function renderSidebarSection( case 'json': return ( - + ); case 'toolbar': @@ -240,7 +240,7 @@ function renderSidebarSection( default: return ( - + ); } diff --git a/desktop/app/src/ui/components/ContextMenu.tsx b/desktop/app/src/ui/components/ContextMenu.tsx index 4c047f5b2..772fb17e6 100644 --- a/desktop/app/src/ui/components/ContextMenu.tsx +++ b/desktop/app/src/ui/components/ContextMenu.tsx @@ -39,6 +39,7 @@ type Props = { * to show menu items. * * Separators can be added by `{type: 'separator'}` + * @depreacted https://ant.design/components/dropdown/#components-dropdown-demo-context-menu */ export default forwardRef(function ContextMenu( {items, buildItems, component, children, ...otherProps}: Props, diff --git a/desktop/app/src/ui/components/ContextMenuProvider.tsx b/desktop/app/src/ui/components/ContextMenuProvider.tsx index f419fc824..0c4e8bbdc 100644 --- a/desktop/app/src/ui/components/ContextMenuProvider.tsx +++ b/desktop/app/src/ui/components/ContextMenuProvider.tsx @@ -28,6 +28,7 @@ export const ContextMenuContext = createContext( /** * Flipper's root is already wrapped with this component, so plugins should not * need to use this. ContextMenu is what you probably want to use. + * @deprecated use https://ant.design/components/dropdown/#components-dropdown-demo-context-menu */ const ContextMenuProvider: React.FC<{}> = memo(function ContextMenuProvider({ children, diff --git a/desktop/app/src/ui/components/Popover.tsx b/desktop/app/src/ui/components/Popover.tsx index e9214d52f..4b88a1b40 100644 --- a/desktop/app/src/ui/components/Popover.tsx +++ b/desktop/app/src/ui/components/Popover.tsx @@ -65,6 +65,9 @@ type Props = { forceOpts?: Opts; }; +/** + * @deprecated use Popover from antd + */ export default class Popover extends PureComponent { _ref?: Element | null; diff --git a/desktop/app/src/ui/components/Popover2.tsx b/desktop/app/src/ui/components/Popover2.tsx index 12556221f..89bae6255 100644 --- a/desktop/app/src/ui/components/Popover2.tsx +++ b/desktop/app/src/ui/components/Popover2.tsx @@ -16,6 +16,7 @@ import {PopoverContext} from './PopoverProvider'; * UI framework. * I don't recommend using this, as it will likely be removed in future. * Must be nested under a PopoverProvider at some level, usually it is at the top level app so you shouldn't need to add it. + * @deprecated use Popover from Antd */ export default function Popover2(props: { id: string; diff --git a/desktop/app/src/ui/components/console.tsx b/desktop/app/src/ui/components/console.tsx index be326c89a..d44e04293 100644 --- a/desktop/app/src/ui/components/console.tsx +++ b/desktop/app/src/ui/components/console.tsx @@ -13,7 +13,7 @@ import {colors} from './colors'; import ManagedTable from './table/ManagedTable'; import FlexColumn from './FlexColumn'; import Text from './Text'; -import ManagedDataInspector from './data-inspector/ManagedDataInspector'; +import {DataInspector} from 'flipper-plugin'; import Input from './Input'; import View from './View'; import styled from '@emotion/styled'; @@ -160,7 +160,7 @@ export class Console extends Component { columns: { command: { value: result.isSuccess ? ( - + ); } diff --git a/desktop/app/src/ui/components/elements-inspector/sidebar.tsx b/desktop/app/src/ui/components/elements-inspector/sidebar.tsx index 1b7446981..bcac8fefc 100644 --- a/desktop/app/src/ui/components/elements-inspector/sidebar.tsx +++ b/desktop/app/src/ui/components/elements-inspector/sidebar.tsx @@ -12,7 +12,7 @@ import {PluginClient} from '../../../plugin'; import Client from '../../../Client'; import {Logger} from '../../../fb-interfaces/Logger'; import Panel from '../Panel'; -import ManagedDataInspector from '../data-inspector/ManagedDataInspector'; +import {DataInspector} from 'flipper-plugin'; import {Component} from 'react'; import {Console} from '../console'; import GK from '../../../fb-stubs/GK'; @@ -64,7 +64,7 @@ class InspectorSidebarSection extends Component { const {id} = this.props; return ( - { // Note, all `exposedAPIs` should be documented in `flipper-plugin.mdx` expect(exposedAPIs.sort()).toMatchInlineSnapshot(` Array [ + "DataDescription", "DataFormatter", + "DataInspector", "DataSource", "DataTable", "DetailSidebar", "Layout", + "MarkerTimeline", "NUX", "TestUtils", "Tracked", @@ -58,8 +61,10 @@ test('Correct top level API exposed', () => { Array [ "Atom", "DataDescriptionType", + "DataInspectorExpanded", "DataTableColumn", "DataTableManager", + "DataValueExtractor", "DefaultKeyboardAction", "Device", "DeviceLogEntry", @@ -68,6 +73,7 @@ test('Correct top level API exposed', () => { "DeviceType", "Draft", "FlipperLib", + "HighlightManager", "Idler", "LogLevel", "LogTypes", diff --git a/desktop/flipper-plugin/src/index.ts b/desktop/flipper-plugin/src/index.ts index 2b031a1f2..088b902d2 100644 --- a/desktop/flipper-plugin/src/index.ts +++ b/desktop/flipper-plugin/src/index.ts @@ -85,22 +85,22 @@ export {createDataSource, DataSource} from './state/DataSource'; export {DataTable, DataTableColumn} from './ui/data-table/DataTable'; export {DataTableManager} from './ui/data-table/DataTableManager'; -export { - HighlightContext as _HighlightContext, - HighlightProvider as _HighlightProvider, - HighlightManager as _HighlightManager, - useHighlighter as _useHighlighter, -} from './ui/Highlight'; - export { Interactive as _Interactive, InteractiveProps as _InteractiveProps, } from './ui/Interactive'; +export {HighlightManager} from './ui/Highlight'; +export { + DataValueExtractor, + DataInspectorExpanded, +} from './ui/data-inspector/DataInspector'; export { - DataDescription as _DataDescription, DataDescriptionType, + DataDescription, } from './ui/data-inspector/DataDescription'; +export {MarkerTimeline} from './ui/MarkerTimeline'; +export {ManagedDataInspector as DataInspector} from './ui/data-inspector/ManagedDataInspector'; export {useMemoize} from './utils/useMemoize'; diff --git a/desktop/flipper-plugin/src/ui/Highlight.tsx b/desktop/flipper-plugin/src/ui/Highlight.tsx index 2a91ab4df..cfb32a0dd 100644 --- a/desktop/flipper-plugin/src/ui/Highlight.tsx +++ b/desktop/flipper-plugin/src/ui/Highlight.tsx @@ -17,10 +17,9 @@ import React, { useContext, } from 'react'; import {debounce} from 'lodash'; -import {theme} from './theme'; const Highlighted = styled.span({ - backgroundColor: theme.textColorActive, + backgroundColor: '#fcd872', }); export interface HighlightManager { diff --git a/desktop/app/src/ui/components/MarkerTimeline.tsx b/desktop/flipper-plugin/src/ui/MarkerTimeline.tsx similarity index 89% rename from desktop/app/src/ui/components/MarkerTimeline.tsx rename to desktop/flipper-plugin/src/ui/MarkerTimeline.tsx index 04d0f29ed..62ed4817e 100644 --- a/desktop/app/src/ui/components/MarkerTimeline.tsx +++ b/desktop/flipper-plugin/src/ui/MarkerTimeline.tsx @@ -7,12 +7,12 @@ * @format */ +import React from 'react'; import {Component} from 'react'; import styled from '@emotion/styled'; -import Text from './Text'; -import FlexRow from './FlexRow'; -import {colors} from './colors'; -import React from 'react'; +import {theme} from './theme'; +import {Layout} from './Layout'; +import {Typography} from 'antd'; type DataPoint = { time: number; @@ -40,7 +40,7 @@ const Markers = styled.div<{totalTime: number}>((props) => ({ '::before': { content: '""', width: 1, - borderLeft: `1px dotted ${colors.light30}`, + borderLeft: `1px dotted ${theme.disabledColor}`, position: 'absolute', top: 5, bottom: 20, @@ -49,7 +49,7 @@ const Markers = styled.div<{totalTime: number}>((props) => ({ })); Markers.displayName = 'MarkerTimeline:Markers'; -const Point = styled(FlexRow)<{ +const Point = styled(Layout.Horizontal)<{ positionY: number; onClick: MouseEventHandler | undefined; number: number | undefined; @@ -91,7 +91,7 @@ const Point = styled(FlexRow)<{ marginRight: 6, zIndex: 3, boxShadow: props.selected - ? `0 0 0 2px ${colors.macOSTitleBarIconSelected}` + ? `0 0 0 2px ${theme.backgroundTransparentHover}` : undefined, }, '::after': { @@ -101,23 +101,23 @@ const Point = styled(FlexRow)<{ top: -20, left: 0, height: 2, - background: colors.white, - borderTop: `1px solid ${colors.light30}`, - borderBottom: `1px solid ${colors.light30}`, + background: theme.backgroundDefault, + borderTop: `1px solid ${theme.dividerColor}`, + borderBottom: `1px solid ${theme.dividerColor}`, transform: `skewY(-10deg)`, }, })); Point.displayName = 'MakerTimeline:Point'; const Time = styled.span({ - color: colors.light30, + color: theme.dividerColor, fontWeight: 300, marginRight: 4, marginTop: -2, }); Time.displayName = 'MakerTimeline:Time'; -const Code = styled(Text)({ +const Code = styled(Typography.Text)({ overflow: 'hidden', textOverflow: 'ellipsis', marginTop: -1, @@ -137,7 +137,7 @@ type State = { timePoints: Array; }; -export default class MarkerTimeline extends Component { +export class MarkerTimeline extends Component { static defaultProps = { lineHeight: 22, maxGap: 100, @@ -172,7 +172,7 @@ export default class MarkerTimeline extends Component { for (let i = 0; i < sortedMarkers.length; i++) { const [timestamp, points] = sortedMarkers[i]; let isCut = false; - const color = sortedMarkers[i][1][0].color || colors.white; + const color = sortedMarkers[i][1][0].color || theme.backgroundDefault; if (i > 0) { const relativeTimestamp = timestamp - sortedMarkers[i - 1][0]; diff --git a/desktop/app/src/ui/components/__tests__/MarkerTimeline.node.tsx b/desktop/flipper-plugin/src/ui/__tests__/MarkerTimeline.node.tsx similarity index 97% rename from desktop/app/src/ui/components/__tests__/MarkerTimeline.node.tsx rename to desktop/flipper-plugin/src/ui/__tests__/MarkerTimeline.node.tsx index 646e6a631..96e1793d2 100644 --- a/desktop/app/src/ui/components/__tests__/MarkerTimeline.node.tsx +++ b/desktop/flipper-plugin/src/ui/__tests__/MarkerTimeline.node.tsx @@ -7,7 +7,7 @@ * @format */ -import MarkerTimeline from '../MarkerTimeline'; +import {MarkerTimeline} from '../MarkerTimeline'; test('merges points with same timestamp', () => { const points = [ diff --git a/desktop/flipper-plugin/src/ui/__tests__/NUX.node.tsx b/desktop/flipper-plugin/src/ui/__tests__/NUX.node.tsx index 4724280db..f646fc9bb 100644 --- a/desktop/flipper-plugin/src/ui/__tests__/NUX.node.tsx +++ b/desktop/flipper-plugin/src/ui/__tests__/NUX.node.tsx @@ -7,7 +7,7 @@ * @format */ -import {TestUtils} from 'flipper-plugin'; +import {TestUtils} from '../../'; import React from 'react'; import {getNuxKey} from '../NUX'; diff --git a/desktop/flipper-plugin/src/ui/__tests__/Tracked.node.tsx b/desktop/flipper-plugin/src/ui/__tests__/Tracked.node.tsx index ac85a7cd6..9c5e69b83 100644 --- a/desktop/flipper-plugin/src/ui/__tests__/Tracked.node.tsx +++ b/desktop/flipper-plugin/src/ui/__tests__/Tracked.node.tsx @@ -8,7 +8,7 @@ */ import {render, fireEvent} from '@testing-library/react'; -import {TestUtils} from 'flipper-plugin'; +import {TestUtils} from '../../'; import {sleep} from '../../utils/sleep'; import React, {Component} from 'react'; import { diff --git a/desktop/app/src/ui/components/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap b/desktop/flipper-plugin/src/ui/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap similarity index 86% rename from desktop/app/src/ui/components/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap rename to desktop/flipper-plugin/src/ui/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap index 617d0581d..317353cff 100644 --- a/desktop/app/src/ui/components/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap +++ b/desktop/flipper-plugin/src/ui/__tests__/__snapshots__/MarkerTimeline.node.tsx.snap @@ -3,7 +3,7 @@ exports[`handles single point 1`] = ` Array [ Object { - "color": "#ffffff", + "color": "var(--flipper-background-default)", "isCut": false, "markerKeys": Array [ "1", diff --git a/desktop/flipper-plugin/src/ui/data-inspector/DataDescription.tsx b/desktop/flipper-plugin/src/ui/data-inspector/DataDescription.tsx index 75dd2dffa..8d3f898ed 100644 --- a/desktop/flipper-plugin/src/ui/data-inspector/DataDescription.tsx +++ b/desktop/flipper-plugin/src/ui/data-inspector/DataDescription.tsx @@ -8,24 +8,22 @@ */ import {Typography, Popover, Input, Select, Checkbox} from 'antd'; -// TODO: restore import {DataInspectorSetValue} from './DataInspector'; +import {DataInspectorSetValue} from './DataInspector'; import {PureComponent} from 'react'; import styled from '@emotion/styled'; import {SketchPicker, CompactPicker} from 'react-color'; import React, {KeyboardEvent} from 'react'; import {HighlightContext} from '../Highlight'; import {parseColor} from '../../utils/parseColor'; -// import TimelineDataDescription from './TimelineDataDescription'; TODO: +import {TimelineDataDescription} from './TimelineDataDescription'; import {theme} from '../theme'; import {EditOutlined} from '@ant-design/icons'; import type {CheckboxChangeEvent} from 'antd/lib/checkbox'; const {Link} = Typography; -type DataInspectorSetValue = (path: Array, val: any) => void; - // Based on FIG UI Core, TODO: does that still makes sense? -const presetColors = Object.values({ +export const presetColors = Object.values({ blue: '#4267b2', // Blue - Active-state nav glyphs, nav bars, links, buttons green: '#42b72a', // Green - Confirmation, success, commerce and status red: '#FC3A4B', // Red - Badges, error states @@ -214,6 +212,7 @@ class NumberTextEditor extends PureComponent<{ ref={this.onNumberTextRef} onBlur={this.onNumberTextBlur} value={this.props.value} + style={{fontSize: 11}} /> ); } @@ -547,24 +546,22 @@ class DataDescriptionContainer extends PureComponent<{ switch (type) { case 'timeline': { - return null; - // TODO: - // return ( - // <> - // { - // this.props.commit({ - // value: id, - // keep: true, - // clear: false, - // set: true, - // }); - // }} - // /> - // - // ); + return ( + <> + { + this.props.commit({ + value: id, + keep: true, + clear: false, + set: true, + }); + }} + /> + + ); } case 'number': @@ -632,6 +629,8 @@ class DataDescriptionContainer extends PureComponent<{ set: true, }) } + size="small" + style={{fontSize: 11}} /> ); } diff --git a/desktop/app/src/ui/components/data-inspector/DataInspector.tsx b/desktop/flipper-plugin/src/ui/data-inspector/DataInspector.tsx similarity index 84% rename from desktop/app/src/ui/components/data-inspector/DataInspector.tsx rename to desktop/flipper-plugin/src/ui/data-inspector/DataInspector.tsx index eb6972811..c1acef362 100644 --- a/desktop/app/src/ui/components/data-inspector/DataInspector.tsx +++ b/desktop/flipper-plugin/src/ui/data-inspector/DataInspector.tsx @@ -7,27 +7,30 @@ * @format */ -import {_DataDescription} from 'flipper-plugin'; -import {MenuTemplate} from '../ContextMenu'; -import {memo, useMemo, useRef, useState, useEffect, useCallback} from 'react'; -import ContextMenu from '../ContextMenu'; -import Tooltip from '../Tooltip'; +import {DataDescription} from './DataDescription'; +import { + memo, + useMemo, + useRef, + useState, + useEffect, + useCallback, + createContext, + useContext, +} from 'react'; import styled from '@emotion/styled'; -import createPaste from '../../../fb-stubs/createPaste'; -import {reportInteraction} from '../../../utils/InteractionTracker'; import DataPreview, {DataValueExtractor, InspectorName} from './DataPreview'; import {getSortedKeys} from './utils'; -import {colors} from '../colors'; -import {clipboard} from 'electron'; import React from 'react'; -import {TooltipOptions} from '../TooltipProvider'; -import { - _useHighlighter as useHighlighter, - _HighlightManager, -} from 'flipper-plugin'; +import {useHighlighter, HighlightManager} from '../Highlight'; +import {Dropdown, Menu, Tooltip} from 'antd'; +import {tryGetFlipperLibImplementation} from '../../plugin/FlipperLib'; +import {safeStringify} from '../../utils/safeStringify'; export {DataValueExtractor} from './DataPreview'; +export const RootDataContext = createContext<() => any>(() => ({})); + const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>( (props) => ({ fontFamily: 'Menlo, monospace', @@ -42,7 +45,7 @@ const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>( BaseContainer.displayName = 'DataInspector:BaseContainer'; const RecursiveBaseWrapper = styled.span({ - color: colors.red, + color: '#FC3A4B', }); RecursiveBaseWrapper.displayName = 'DataInspector:RecursiveBaseWrapper'; @@ -66,18 +69,13 @@ const ExpandControl = styled.span({ ExpandControl.displayName = 'DataInspector:ExpandControl'; const Added = styled.div({ - backgroundColor: colors.tealTint70, + backgroundColor: '#d2f0ea', }); const Removed = styled.div({ - backgroundColor: colors.cherryTint70, + backgroundColor: '#fbccd2', }); -const nameTooltipOptions: TooltipOptions = { - position: 'toLeft', - showTail: true, -}; - export type DataInspectorSetValue = (path: Array, val: any) => void; export type DataInspectorDeleteValue = (path: Array) => void; @@ -145,7 +143,7 @@ type DataInspectorProps = { onRenderName?: ( path: Array, name: string, - highlighter: _HighlightManager, + highlighter: HighlightManager, ) => React.ReactElement; /** * Render callback that can be used to customize the rendering of object values. @@ -205,50 +203,29 @@ const defaultValueExtractor: DataValueExtractor = (value: any) => { } }; -const rootContextMenuCache: WeakMap< - Object, - Array -> = new WeakMap(); - -function getRootContextMenu( - data: Object, -): Array { - const cached = rootContextMenuCache.get(data); - if (cached != null) { - return cached; - } - - let stringValue: string; - try { - stringValue = JSON.stringify(data, null, 2); - } catch (e) { - stringValue = ''; - } - const menu: Array = [ - { - label: 'Copy entire tree', - click: () => clipboard.writeText(stringValue), - }, - { - type: 'separator', - }, - { - label: 'Create paste', - click: () => { - createPaste(stringValue); - }, - }, - ]; - if (typeof data === 'object' && data !== null) { - rootContextMenuCache.set(data, menu); - } else { - console.error( - '[data-inspector] Ignoring unsupported data type for cache: ', - data, - typeof data, - ); - } - return menu; +function getRootContextMenu(root: Object) { + const lib = tryGetFlipperLibImplementation(); + return ( + + { + lib?.writeTextToClipboard(safeStringify(root)); + }}> + Copy tree + + + {lib?.isFB && ( + { + lib?.createPaste(safeStringify(root)); + }}> + Create paste from tree + + )} + + ); } function isPureObject(obj: Object) { @@ -345,6 +322,7 @@ const DataInspector: React.FC = memo( setValue: setValueProp, }) { const highlighter = useHighlighter(); + const getRoot = useContext(RootDataContext); const shouldExpand = useRef(false); const expandHandle = useRef(undefined as any); @@ -434,10 +412,6 @@ const DataInspector: React.FC = memo( const handleClick = useCallback(() => { cancelIdleCallback(expandHandle.current); const isExpanded = shouldBeExpanded(expandedPaths, path, collapsed); - reportInteraction('DataInspector', path.join(':'))( - isExpanded ? 'collapsed' : 'expanded', - undefined, - ); setExpanded(path, !isExpanded); }, [expandedPaths, path, collapsed]); @@ -534,11 +508,7 @@ const DataInspector: React.FC = memo( } if (expandRoot === true) { - return ( - - {propertyNodesContainer} - - ); + return <>{propertyNodesContainer}; } // create name components @@ -551,7 +521,7 @@ const DataInspector: React.FC = memo( + placement="left"> {text} , ); @@ -562,7 +532,7 @@ const DataInspector: React.FC = memo( let descriptionOrPreview; if (renderExpanded || !isExpandable) { descriptionOrPreview = ( - <_DataDescription + = memo( } } - const contextMenuItems: MenuTemplate = []; - - if (isExpandable) { - contextMenuItems.push( - { - label: shouldExpand.current ? 'Collapse' : 'Expand', - click: handleClick, - }, - { - type: 'separator', - }, + function getContextMenu() { + const lib = tryGetFlipperLibImplementation(); + return ( + + { + lib?.writeTextToClipboard(safeStringify(getRoot())); + }}> + Copy tree + + {lib?.isFB && ( + { + lib?.createPaste(safeStringify(getRoot())); + }}> + Create paste from tree + + )} + + { + lib?.writeTextToClipboard(safeStringify(data)); + }}> + Copy value + + {!isExpandable && onDelete ? ( + { + handleDelete(path); + }}> + Delete + + ) : null} + ); } - contextMenuItems.push( - { - label: 'Copy', - click: () => - clipboard.writeText((window.getSelection() || '').toString()), - }, - { - label: 'Copy value', - click: () => clipboard.writeText(JSON.stringify(data, null, 2)), - }, - ); - - if (!isExpandable && onDelete) { - contextMenuItems.push({ - label: 'Delete', - click: () => handleDelete(path), - }); - } - return ( - + {expandedPaths && {expandGlyph}} {descriptionOrPreview} {wrapperStart} - + {propertyNodesContainer} {wrapperEnd} diff --git a/desktop/app/src/ui/components/data-inspector/DataPreview.tsx b/desktop/flipper-plugin/src/ui/data-inspector/DataPreview.tsx similarity index 94% rename from desktop/app/src/ui/components/data-inspector/DataPreview.tsx rename to desktop/flipper-plugin/src/ui/data-inspector/DataPreview.tsx index c74b54dd5..24c51e5d9 100755 --- a/desktop/app/src/ui/components/data-inspector/DataPreview.tsx +++ b/desktop/flipper-plugin/src/ui/data-inspector/DataPreview.tsx @@ -7,12 +7,11 @@ * @format */ -import {DataDescriptionType, _DataDescription} from 'flipper-plugin'; +import {DataDescriptionType, DataDescription} from './DataDescription'; import styled from '@emotion/styled'; import {getSortedKeys} from './utils'; import {PureComponent} from 'react'; import React from 'react'; -import {colors} from '../colors'; export type DataValueExtractor = ( value: any, @@ -29,7 +28,7 @@ export type DataValueExtractor = ( | null; export const InspectorName = styled.span({ - color: colors.grapeDark1, + color: '#7b64c0', }); InspectorName.displayName = 'DataInspector:InspectorName'; @@ -79,7 +78,7 @@ export default class DataPreview extends PureComponent<{ const {type, value} = res; return ( - <_DataDescription + , name: string, - highlighter: _HighlightManager, + highlighter: HighlightManager, ) => React.ReactElement; /** * Render callback that can be used to customize the rendering of object values. @@ -83,7 +83,7 @@ const EMPTY_ARRAY: any[] = []; * If you require lower level access to the state then use `DataInspector` * directly. */ -export default class ManagedDataInspector extends PureComponent< +export class ManagedDataInspector extends PureComponent< ManagedDataInspectorProps, ManagedDataInspectorState > { @@ -171,27 +171,34 @@ export default class ManagedDataInspector extends PureComponent< }); }; + // make sure this fn is a stable ref to not invalidate the whole tree on new data + getRootData = () => { + return this.props.data; + }; + render() { return ( - <_HighlightProvider text={this.props.filter}> - - + + + + + ); } } diff --git a/desktop/app/src/ui/components/data-inspector/TimelineDataDescription.tsx b/desktop/flipper-plugin/src/ui/data-inspector/TimelineDataDescription.tsx similarity index 84% rename from desktop/app/src/ui/components/data-inspector/TimelineDataDescription.tsx rename to desktop/flipper-plugin/src/ui/data-inspector/TimelineDataDescription.tsx index 9d6c985e0..84e918613 100644 --- a/desktop/app/src/ui/components/data-inspector/TimelineDataDescription.tsx +++ b/desktop/flipper-plugin/src/ui/data-inspector/TimelineDataDescription.tsx @@ -7,12 +7,12 @@ * @format */ -import ManagedDataInspector from './ManagedDataInspector'; +import {ManagedDataInspector} from './ManagedDataInspector'; import {Component, ReactNode} from 'react'; -import {colors} from '../colors'; import React from 'react'; -import MarkerTimeline from '../MarkerTimeline'; -import Button from '../Button'; +import {MarkerTimeline} from '../MarkerTimeline'; +import {Button} from 'antd'; +import {presetColors} from './DataDescription'; type TimePoint = { moment: number; @@ -37,7 +37,7 @@ type State = { selected: string; }; -export default class TimelineDataDescription extends Component { +export class TimelineDataDescription extends Component { constructor(props: Props) { super(props); this.state = {selected: props.timeline.current}; @@ -50,7 +50,7 @@ export default class TimelineDataDescription extends Component { label: value.display, time: value.moment - firstMoment, color: - Object.entries(colors).find(([k, _]) => k === value.color)?.[1] ?? + Object.entries(presetColors).find(([k, _]) => k === value.color)?.[1] ?? value.color, key: value.key, })); diff --git a/desktop/app/src/ui/components/data-inspector/__tests__/DataInspector.node.tsx b/desktop/flipper-plugin/src/ui/data-inspector/__tests__/DataInspector.node.tsx similarity index 96% rename from desktop/app/src/ui/components/data-inspector/__tests__/DataInspector.node.tsx rename to desktop/flipper-plugin/src/ui/data-inspector/__tests__/DataInspector.node.tsx index f8c346c37..88f114b63 100644 --- a/desktop/app/src/ui/components/data-inspector/__tests__/DataInspector.node.tsx +++ b/desktop/flipper-plugin/src/ui/data-inspector/__tests__/DataInspector.node.tsx @@ -10,8 +10,8 @@ import * as React from 'react'; import {render, fireEvent, waitFor, act} from '@testing-library/react'; -import ManagedDataInspector from '../ManagedDataInspector'; -import {sleep} from '../../../../utils'; +import {ManagedDataInspector} from '../ManagedDataInspector'; +import {sleep} from '../../../utils/sleep'; const mocks = { requestIdleCallback(fn: Function) { @@ -124,7 +124,7 @@ test('can filter for data', async () => { "j son diff --git a/desktop/app/src/ui/components/data-inspector/utils.tsx b/desktop/flipper-plugin/src/ui/data-inspector/utils.tsx similarity index 100% rename from desktop/app/src/ui/components/data-inspector/utils.tsx rename to desktop/flipper-plugin/src/ui/data-inspector/utils.tsx diff --git a/desktop/types/index.d.ts b/desktop/types/index.d.ts index 12664c672..41b409a7e 100644 --- a/desktop/types/index.d.ts +++ b/desktop/types/index.d.ts @@ -26,4 +26,3 @@ /// /// /// -/// diff --git a/desktop/types/string-natural-compare.d.ts b/desktop/types/string-natural-compare.d.ts deleted file mode 100644 index bd24b0582..000000000 --- a/desktop/types/string-natural-compare.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * 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 - */ - -declare module 'string-natural-compare' { - export default function naturalCompare(a: string, b: string): number; -} diff --git a/desktop/yarn.lock b/desktop/yarn.lock index af3c3a67c..b290e7e12 100644 --- a/desktop/yarn.lock +++ b/desktop/yarn.lock @@ -2982,6 +2982,11 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw== +"@types/string-natural-compare@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/string-natural-compare/-/string-natural-compare-3.0.0.tgz#44d0970987df4b89697993015d4447a26d1f2d66" + integrity sha512-fXFxr8Isabw+XVgZ1Clsi7slyv2cGTIK/U9niVkUCva5O96eiC1CjdOPLKQnxrOVvVYJPeAEkLT3VPTlgOnz0w== + "@types/tar@^4.0.3": version "4.0.3" resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489" diff --git a/docs/extending/flipper-plugin.mdx b/docs/extending/flipper-plugin.mdx index a9dee8869..c8cd3e688 100644 --- a/docs/extending/flipper-plugin.mdx +++ b/docs/extending/flipper-plugin.mdx @@ -781,6 +781,9 @@ See `View > Flipper Style Guide` inside the Flipper application for more details ### DataTable ### DataFormatter +### DataInspector +### DataDescription +### MarkerTimeline Coming soon.