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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
9030a98c6e
commit
53c557f923
@@ -72,7 +72,6 @@
|
|||||||
"rsocket-types": "^0.0.25",
|
"rsocket-types": "^0.0.25",
|
||||||
"semver": "^7.3.5",
|
"semver": "^7.3.5",
|
||||||
"split2": "^3.2.2",
|
"split2": "^3.2.2",
|
||||||
"string-natural-compare": "^3.0.0",
|
|
||||||
"tmp": "^0.2.1",
|
"tmp": "^0.2.1",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"which": "^2.0.1",
|
"which": "^2.0.1",
|
||||||
|
|||||||
@@ -95,15 +95,14 @@ export {
|
|||||||
export {
|
export {
|
||||||
DataValueExtractor,
|
DataValueExtractor,
|
||||||
DataInspectorExpanded,
|
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,
|
DataDescriptionType,
|
||||||
|
DataDescription,
|
||||||
|
DataInspector,
|
||||||
|
MarkerTimeline,
|
||||||
} from 'flipper-plugin';
|
} 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 Tabs} from './ui/components/Tabs';
|
||||||
export {default as Tab} from './ui/components/Tab';
|
export {default as Tab} from './ui/components/Tab';
|
||||||
export {default as Input} from './ui/components/Input';
|
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 Label} from './ui/components/Label';
|
||||||
export {default as Heading} from './ui/components/Heading';
|
export {default as Heading} from './ui/components/Heading';
|
||||||
export {Filter} from './ui/components/filter/types';
|
export {Filter} from './ui/components/filter/types';
|
||||||
export {default as MarkerTimeline} from './ui/components/MarkerTimeline';
|
|
||||||
export {default as StackTrace} from './ui/components/StackTrace';
|
export {default as StackTrace} from './ui/components/StackTrace';
|
||||||
export {
|
export {
|
||||||
SearchBox,
|
SearchBox,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ManagedDataInspector from '../ui/components/data-inspector/ManagedDataInspector';
|
import {DataInspector} from 'flipper-plugin';
|
||||||
import Panel from '../ui/components/Panel';
|
import Panel from '../ui/components/Panel';
|
||||||
import {colors} from '../ui/components/colors';
|
import {colors} from '../ui/components/colors';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@@ -232,7 +232,7 @@ function renderSidebarSection(
|
|||||||
case 'json':
|
case 'json':
|
||||||
return (
|
return (
|
||||||
<Panel floating={false} heading={section.title} key={index}>
|
<Panel floating={false} heading={section.title} key={index}>
|
||||||
<ManagedDataInspector data={section.content} expandRoot={true} />
|
<DataInspector data={section.content} expandRoot={true} />
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
case 'toolbar':
|
case 'toolbar':
|
||||||
@@ -240,7 +240,7 @@ function renderSidebarSection(
|
|||||||
default:
|
default:
|
||||||
return (
|
return (
|
||||||
<Panel floating={false} heading={'Details'} key={index}>
|
<Panel floating={false} heading={'Details'} key={index}>
|
||||||
<ManagedDataInspector data={section} expandRoot={true} />
|
<DataInspector data={section} expandRoot={true} />
|
||||||
</Panel>
|
</Panel>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ type Props<C> = {
|
|||||||
* to show menu items.
|
* to show menu items.
|
||||||
*
|
*
|
||||||
* Separators can be added by `{type: 'separator'}`
|
* Separators can be added by `{type: 'separator'}`
|
||||||
|
* @depreacted https://ant.design/components/dropdown/#components-dropdown-demo-context-menu
|
||||||
*/
|
*/
|
||||||
export default forwardRef(function ContextMenu<C>(
|
export default forwardRef(function ContextMenu<C>(
|
||||||
{items, buildItems, component, children, ...otherProps}: Props<C>,
|
{items, buildItems, component, children, ...otherProps}: Props<C>,
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ export const ContextMenuContext = createContext<ContextMenuManager | undefined>(
|
|||||||
/**
|
/**
|
||||||
* Flipper's root is already wrapped with this component, so plugins should not
|
* 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.
|
* 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({
|
const ContextMenuProvider: React.FC<{}> = memo(function ContextMenuProvider({
|
||||||
children,
|
children,
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ type Props = {
|
|||||||
forceOpts?: Opts;
|
forceOpts?: Opts;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use Popover from antd
|
||||||
|
*/
|
||||||
export default class Popover extends PureComponent<Props> {
|
export default class Popover extends PureComponent<Props> {
|
||||||
_ref?: Element | null;
|
_ref?: Element | null;
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import {PopoverContext} from './PopoverProvider';
|
|||||||
* UI framework.
|
* UI framework.
|
||||||
* I don't recommend using this, as it will likely be removed in future.
|
* 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.
|
* 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: {
|
export default function Popover2(props: {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {colors} from './colors';
|
|||||||
import ManagedTable from './table/ManagedTable';
|
import ManagedTable from './table/ManagedTable';
|
||||||
import FlexColumn from './FlexColumn';
|
import FlexColumn from './FlexColumn';
|
||||||
import Text from './Text';
|
import Text from './Text';
|
||||||
import ManagedDataInspector from './data-inspector/ManagedDataInspector';
|
import {DataInspector} from 'flipper-plugin';
|
||||||
import Input from './Input';
|
import Input from './Input';
|
||||||
import View from './View';
|
import View from './View';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
@@ -160,7 +160,7 @@ export class Console extends Component<Props, State> {
|
|||||||
columns: {
|
columns: {
|
||||||
command: {
|
command: {
|
||||||
value: result.isSuccess ? (
|
value: result.isSuccess ? (
|
||||||
<ManagedDataInspector
|
<DataInspector
|
||||||
data={result.value}
|
data={result.value}
|
||||||
expandRoot={true}
|
expandRoot={true}
|
||||||
collapsed={true}
|
collapsed={true}
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import debounceRender from 'react-debounce-render';
|
import debounceRender from 'react-debounce-render';
|
||||||
|
|
||||||
import ManagedDataInspector, {
|
import {DataInspector} from 'flipper-plugin';
|
||||||
ManagedDataInspectorProps,
|
|
||||||
} from './ManagedDataInspector';
|
|
||||||
import Searchable, {SearchableProps} from '../searchable/Searchable';
|
import Searchable, {SearchableProps} from '../searchable/Searchable';
|
||||||
|
|
||||||
|
type ManagedDataInspectorProps = any; // TODO!
|
||||||
|
|
||||||
type Props = ManagedDataInspectorProps & SearchableProps;
|
type Props = ManagedDataInspectorProps & SearchableProps;
|
||||||
|
|
||||||
function filter(data: any, searchTerm: string): any {
|
function filter(data: any, searchTerm: string): any {
|
||||||
@@ -35,10 +35,7 @@ function filter(data: any, searchTerm: string): any {
|
|||||||
// Naive shallow filters matching wrapper for ManagedDataInspector
|
// Naive shallow filters matching wrapper for ManagedDataInspector
|
||||||
function SearchableDataInspector(props: Props) {
|
function SearchableDataInspector(props: Props) {
|
||||||
return (
|
return (
|
||||||
<ManagedDataInspector
|
<DataInspector {...props} data={filter(props.data, props.searchTerm)} />
|
||||||
{...props}
|
|
||||||
data={filter(props.data, props.searchTerm)}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import {PluginClient} from '../../../plugin';
|
|||||||
import Client from '../../../Client';
|
import Client from '../../../Client';
|
||||||
import {Logger} from '../../../fb-interfaces/Logger';
|
import {Logger} from '../../../fb-interfaces/Logger';
|
||||||
import Panel from '../Panel';
|
import Panel from '../Panel';
|
||||||
import ManagedDataInspector from '../data-inspector/ManagedDataInspector';
|
import {DataInspector} from 'flipper-plugin';
|
||||||
import {Component} from 'react';
|
import {Component} from 'react';
|
||||||
import {Console} from '../console';
|
import {Console} from '../console';
|
||||||
import GK from '../../../fb-stubs/GK';
|
import GK from '../../../fb-stubs/GK';
|
||||||
@@ -64,7 +64,7 @@ class InspectorSidebarSection extends Component<InspectorSidebarSectionProps> {
|
|||||||
const {id} = this.props;
|
const {id} = this.props;
|
||||||
return (
|
return (
|
||||||
<Panel heading={id} floating={false} grow={false}>
|
<Panel heading={id} floating={false} grow={false}>
|
||||||
<ManagedDataInspector
|
<DataInspector
|
||||||
data={this.props.data}
|
data={this.props.data}
|
||||||
setValue={this.props.onValueChanged ? this.setValue : undefined}
|
setValue={this.props.onValueChanged ? this.setValue : undefined}
|
||||||
extractValue={this.extractValue}
|
extractValue={this.extractValue}
|
||||||
|
|||||||
@@ -43,12 +43,8 @@ export {ManagedTableProps_immutable} from './components/table/ManagedTable_immut
|
|||||||
export {Value} from './components/table/TypeBasedValueRenderer';
|
export {Value} from './components/table/TypeBasedValueRenderer';
|
||||||
export {renderValue} from './components/table/TypeBasedValueRenderer';
|
export {renderValue} from './components/table/TypeBasedValueRenderer';
|
||||||
|
|
||||||
export {
|
export {DataValueExtractor, DataInspectorExpanded} from 'flipper-plugin';
|
||||||
DataValueExtractor,
|
export {DataInspector as ManagedDataInspector} from 'flipper-plugin';
|
||||||
DataInspectorExpanded,
|
|
||||||
} from './components/data-inspector/DataInspector';
|
|
||||||
export {default as DataInspector} from './components/data-inspector/DataInspector';
|
|
||||||
export {default as ManagedDataInspector} from './components/data-inspector/ManagedDataInspector';
|
|
||||||
export {default as SearchableDataInspector} from './components/data-inspector/SearchableDataInspector';
|
export {default as SearchableDataInspector} from './components/data-inspector/SearchableDataInspector';
|
||||||
|
|
||||||
// tabs
|
// tabs
|
||||||
@@ -130,8 +126,6 @@ export {default as Heading} from './components/Heading';
|
|||||||
// filters
|
// filters
|
||||||
export {Filter} from './components/filter/types';
|
export {Filter} from './components/filter/types';
|
||||||
|
|
||||||
export {default as MarkerTimeline} from './components/MarkerTimeline';
|
|
||||||
|
|
||||||
export {default as StackTrace} from './components/StackTrace';
|
export {default as StackTrace} from './components/StackTrace';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"react-color": "^2.19.3",
|
"react-color": "^2.19.3",
|
||||||
"react-element-to-jsx-string": "^14.3.2",
|
"react-element-to-jsx-string": "^14.3.2",
|
||||||
"react-virtual": "^2.6.1"
|
"react-virtual": "^2.6.1",
|
||||||
|
"string-natural-compare": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^26.0.22",
|
"@types/jest": "^26.0.22",
|
||||||
|
"@types/string-natural-compare": "^3.0.0",
|
||||||
"jest-mock-console": "^1.0.1",
|
"jest-mock-console": "^1.0.1",
|
||||||
"typescript": "^4.1.2"
|
"typescript": "^4.1.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -28,11 +28,14 @@ test('Correct top level API exposed', () => {
|
|||||||
// Note, all `exposedAPIs` should be documented in `flipper-plugin.mdx`
|
// Note, all `exposedAPIs` should be documented in `flipper-plugin.mdx`
|
||||||
expect(exposedAPIs.sort()).toMatchInlineSnapshot(`
|
expect(exposedAPIs.sort()).toMatchInlineSnapshot(`
|
||||||
Array [
|
Array [
|
||||||
|
"DataDescription",
|
||||||
"DataFormatter",
|
"DataFormatter",
|
||||||
|
"DataInspector",
|
||||||
"DataSource",
|
"DataSource",
|
||||||
"DataTable",
|
"DataTable",
|
||||||
"DetailSidebar",
|
"DetailSidebar",
|
||||||
"Layout",
|
"Layout",
|
||||||
|
"MarkerTimeline",
|
||||||
"NUX",
|
"NUX",
|
||||||
"TestUtils",
|
"TestUtils",
|
||||||
"Tracked",
|
"Tracked",
|
||||||
@@ -58,8 +61,10 @@ test('Correct top level API exposed', () => {
|
|||||||
Array [
|
Array [
|
||||||
"Atom",
|
"Atom",
|
||||||
"DataDescriptionType",
|
"DataDescriptionType",
|
||||||
|
"DataInspectorExpanded",
|
||||||
"DataTableColumn",
|
"DataTableColumn",
|
||||||
"DataTableManager",
|
"DataTableManager",
|
||||||
|
"DataValueExtractor",
|
||||||
"DefaultKeyboardAction",
|
"DefaultKeyboardAction",
|
||||||
"Device",
|
"Device",
|
||||||
"DeviceLogEntry",
|
"DeviceLogEntry",
|
||||||
@@ -68,6 +73,7 @@ test('Correct top level API exposed', () => {
|
|||||||
"DeviceType",
|
"DeviceType",
|
||||||
"Draft",
|
"Draft",
|
||||||
"FlipperLib",
|
"FlipperLib",
|
||||||
|
"HighlightManager",
|
||||||
"Idler",
|
"Idler",
|
||||||
"LogLevel",
|
"LogLevel",
|
||||||
"LogTypes",
|
"LogTypes",
|
||||||
|
|||||||
@@ -85,22 +85,22 @@ export {createDataSource, DataSource} from './state/DataSource';
|
|||||||
export {DataTable, DataTableColumn} from './ui/data-table/DataTable';
|
export {DataTable, DataTableColumn} from './ui/data-table/DataTable';
|
||||||
export {DataTableManager} from './ui/data-table/DataTableManager';
|
export {DataTableManager} from './ui/data-table/DataTableManager';
|
||||||
|
|
||||||
export {
|
|
||||||
HighlightContext as _HighlightContext,
|
|
||||||
HighlightProvider as _HighlightProvider,
|
|
||||||
HighlightManager as _HighlightManager,
|
|
||||||
useHighlighter as _useHighlighter,
|
|
||||||
} from './ui/Highlight';
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Interactive as _Interactive,
|
Interactive as _Interactive,
|
||||||
InteractiveProps as _InteractiveProps,
|
InteractiveProps as _InteractiveProps,
|
||||||
} from './ui/Interactive';
|
} from './ui/Interactive';
|
||||||
|
|
||||||
|
export {HighlightManager} from './ui/Highlight';
|
||||||
|
export {
|
||||||
|
DataValueExtractor,
|
||||||
|
DataInspectorExpanded,
|
||||||
|
} from './ui/data-inspector/DataInspector';
|
||||||
export {
|
export {
|
||||||
DataDescription as _DataDescription,
|
|
||||||
DataDescriptionType,
|
DataDescriptionType,
|
||||||
|
DataDescription,
|
||||||
} from './ui/data-inspector/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';
|
export {useMemoize} from './utils/useMemoize';
|
||||||
|
|
||||||
|
|||||||
@@ -17,10 +17,9 @@ import React, {
|
|||||||
useContext,
|
useContext,
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import {debounce} from 'lodash';
|
import {debounce} from 'lodash';
|
||||||
import {theme} from './theme';
|
|
||||||
|
|
||||||
const Highlighted = styled.span({
|
const Highlighted = styled.span({
|
||||||
backgroundColor: theme.textColorActive,
|
backgroundColor: '#fcd872',
|
||||||
});
|
});
|
||||||
|
|
||||||
export interface HighlightManager {
|
export interface HighlightManager {
|
||||||
|
|||||||
@@ -7,12 +7,12 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
import {Component} from 'react';
|
import {Component} from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import Text from './Text';
|
import {theme} from './theme';
|
||||||
import FlexRow from './FlexRow';
|
import {Layout} from './Layout';
|
||||||
import {colors} from './colors';
|
import {Typography} from 'antd';
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
type DataPoint = {
|
type DataPoint = {
|
||||||
time: number;
|
time: number;
|
||||||
@@ -40,7 +40,7 @@ const Markers = styled.div<{totalTime: number}>((props) => ({
|
|||||||
'::before': {
|
'::before': {
|
||||||
content: '""',
|
content: '""',
|
||||||
width: 1,
|
width: 1,
|
||||||
borderLeft: `1px dotted ${colors.light30}`,
|
borderLeft: `1px dotted ${theme.disabledColor}`,
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
top: 5,
|
top: 5,
|
||||||
bottom: 20,
|
bottom: 20,
|
||||||
@@ -49,7 +49,7 @@ const Markers = styled.div<{totalTime: number}>((props) => ({
|
|||||||
}));
|
}));
|
||||||
Markers.displayName = 'MarkerTimeline:Markers';
|
Markers.displayName = 'MarkerTimeline:Markers';
|
||||||
|
|
||||||
const Point = styled(FlexRow)<{
|
const Point = styled(Layout.Horizontal)<{
|
||||||
positionY: number;
|
positionY: number;
|
||||||
onClick: MouseEventHandler | undefined;
|
onClick: MouseEventHandler | undefined;
|
||||||
number: number | undefined;
|
number: number | undefined;
|
||||||
@@ -91,7 +91,7 @@ const Point = styled(FlexRow)<{
|
|||||||
marginRight: 6,
|
marginRight: 6,
|
||||||
zIndex: 3,
|
zIndex: 3,
|
||||||
boxShadow: props.selected
|
boxShadow: props.selected
|
||||||
? `0 0 0 2px ${colors.macOSTitleBarIconSelected}`
|
? `0 0 0 2px ${theme.backgroundTransparentHover}`
|
||||||
: undefined,
|
: undefined,
|
||||||
},
|
},
|
||||||
'::after': {
|
'::after': {
|
||||||
@@ -101,23 +101,23 @@ const Point = styled(FlexRow)<{
|
|||||||
top: -20,
|
top: -20,
|
||||||
left: 0,
|
left: 0,
|
||||||
height: 2,
|
height: 2,
|
||||||
background: colors.white,
|
background: theme.backgroundDefault,
|
||||||
borderTop: `1px solid ${colors.light30}`,
|
borderTop: `1px solid ${theme.dividerColor}`,
|
||||||
borderBottom: `1px solid ${colors.light30}`,
|
borderBottom: `1px solid ${theme.dividerColor}`,
|
||||||
transform: `skewY(-10deg)`,
|
transform: `skewY(-10deg)`,
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
Point.displayName = 'MakerTimeline:Point';
|
Point.displayName = 'MakerTimeline:Point';
|
||||||
|
|
||||||
const Time = styled.span({
|
const Time = styled.span({
|
||||||
color: colors.light30,
|
color: theme.dividerColor,
|
||||||
fontWeight: 300,
|
fontWeight: 300,
|
||||||
marginRight: 4,
|
marginRight: 4,
|
||||||
marginTop: -2,
|
marginTop: -2,
|
||||||
});
|
});
|
||||||
Time.displayName = 'MakerTimeline:Time';
|
Time.displayName = 'MakerTimeline:Time';
|
||||||
|
|
||||||
const Code = styled(Text)({
|
const Code = styled(Typography.Text)({
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
textOverflow: 'ellipsis',
|
textOverflow: 'ellipsis',
|
||||||
marginTop: -1,
|
marginTop: -1,
|
||||||
@@ -137,7 +137,7 @@ type State = {
|
|||||||
timePoints: Array<TimePoint>;
|
timePoints: Array<TimePoint>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class MarkerTimeline extends Component<Props, State> {
|
export class MarkerTimeline extends Component<Props, State> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
lineHeight: 22,
|
lineHeight: 22,
|
||||||
maxGap: 100,
|
maxGap: 100,
|
||||||
@@ -172,7 +172,7 @@ export default class MarkerTimeline extends Component<Props, State> {
|
|||||||
for (let i = 0; i < sortedMarkers.length; i++) {
|
for (let i = 0; i < sortedMarkers.length; i++) {
|
||||||
const [timestamp, points] = sortedMarkers[i];
|
const [timestamp, points] = sortedMarkers[i];
|
||||||
let isCut = false;
|
let isCut = false;
|
||||||
const color = sortedMarkers[i][1][0].color || colors.white;
|
const color = sortedMarkers[i][1][0].color || theme.backgroundDefault;
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
const relativeTimestamp = timestamp - sortedMarkers[i - 1][0];
|
const relativeTimestamp = timestamp - sortedMarkers[i - 1][0];
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import MarkerTimeline from '../MarkerTimeline';
|
import {MarkerTimeline} from '../MarkerTimeline';
|
||||||
|
|
||||||
test('merges points with same timestamp', () => {
|
test('merges points with same timestamp', () => {
|
||||||
const points = [
|
const points = [
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {TestUtils} from 'flipper-plugin';
|
import {TestUtils} from '../../';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {getNuxKey} from '../NUX';
|
import {getNuxKey} from '../NUX';
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {render, fireEvent} from '@testing-library/react';
|
import {render, fireEvent} from '@testing-library/react';
|
||||||
import {TestUtils} from 'flipper-plugin';
|
import {TestUtils} from '../../';
|
||||||
import {sleep} from '../../utils/sleep';
|
import {sleep} from '../../utils/sleep';
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
exports[`handles single point 1`] = `
|
exports[`handles single point 1`] = `
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
"color": "#ffffff",
|
"color": "var(--flipper-background-default)",
|
||||||
"isCut": false,
|
"isCut": false,
|
||||||
"markerKeys": Array [
|
"markerKeys": Array [
|
||||||
"1",
|
"1",
|
||||||
@@ -8,24 +8,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Typography, Popover, Input, Select, Checkbox} from 'antd';
|
import {Typography, Popover, Input, Select, Checkbox} from 'antd';
|
||||||
// TODO: restore import {DataInspectorSetValue} from './DataInspector';
|
import {DataInspectorSetValue} from './DataInspector';
|
||||||
import {PureComponent} from 'react';
|
import {PureComponent} from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {SketchPicker, CompactPicker} from 'react-color';
|
import {SketchPicker, CompactPicker} from 'react-color';
|
||||||
import React, {KeyboardEvent} from 'react';
|
import React, {KeyboardEvent} from 'react';
|
||||||
import {HighlightContext} from '../Highlight';
|
import {HighlightContext} from '../Highlight';
|
||||||
import {parseColor} from '../../utils/parseColor';
|
import {parseColor} from '../../utils/parseColor';
|
||||||
// import TimelineDataDescription from './TimelineDataDescription'; TODO:
|
import {TimelineDataDescription} from './TimelineDataDescription';
|
||||||
import {theme} from '../theme';
|
import {theme} from '../theme';
|
||||||
import {EditOutlined} from '@ant-design/icons';
|
import {EditOutlined} from '@ant-design/icons';
|
||||||
import type {CheckboxChangeEvent} from 'antd/lib/checkbox';
|
import type {CheckboxChangeEvent} from 'antd/lib/checkbox';
|
||||||
|
|
||||||
const {Link} = Typography;
|
const {Link} = Typography;
|
||||||
|
|
||||||
type DataInspectorSetValue = (path: Array<string>, val: any) => void;
|
|
||||||
|
|
||||||
// Based on FIG UI Core, TODO: does that still makes sense?
|
// 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
|
blue: '#4267b2', // Blue - Active-state nav glyphs, nav bars, links, buttons
|
||||||
green: '#42b72a', // Green - Confirmation, success, commerce and status
|
green: '#42b72a', // Green - Confirmation, success, commerce and status
|
||||||
red: '#FC3A4B', // Red - Badges, error states
|
red: '#FC3A4B', // Red - Badges, error states
|
||||||
@@ -214,6 +212,7 @@ class NumberTextEditor extends PureComponent<{
|
|||||||
ref={this.onNumberTextRef}
|
ref={this.onNumberTextRef}
|
||||||
onBlur={this.onNumberTextBlur}
|
onBlur={this.onNumberTextBlur}
|
||||||
value={this.props.value}
|
value={this.props.value}
|
||||||
|
style={{fontSize: 11}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -547,24 +546,22 @@ class DataDescriptionContainer extends PureComponent<{
|
|||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'timeline': {
|
case 'timeline': {
|
||||||
return null;
|
return (
|
||||||
// TODO:
|
<>
|
||||||
// return (
|
<TimelineDataDescription
|
||||||
// <>
|
canSetCurrent={editable}
|
||||||
// <TimelineDataDescription
|
timeline={JSON.parse(val)}
|
||||||
// canSetCurrent={editable}
|
onClick={(id) => {
|
||||||
// timeline={JSON.parse(val)}
|
this.props.commit({
|
||||||
// onClick={(id) => {
|
value: id,
|
||||||
// this.props.commit({
|
keep: true,
|
||||||
// value: id,
|
clear: false,
|
||||||
// keep: true,
|
set: true,
|
||||||
// clear: false,
|
});
|
||||||
// set: true,
|
}}
|
||||||
// });
|
/>
|
||||||
// }}
|
</>
|
||||||
// />
|
);
|
||||||
// </>
|
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'number':
|
case 'number':
|
||||||
@@ -632,6 +629,8 @@ class DataDescriptionContainer extends PureComponent<{
|
|||||||
set: true,
|
set: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
size="small"
|
||||||
|
style={{fontSize: 11}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,27 +7,30 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {_DataDescription} from 'flipper-plugin';
|
import {DataDescription} from './DataDescription';
|
||||||
import {MenuTemplate} from '../ContextMenu';
|
import {
|
||||||
import {memo, useMemo, useRef, useState, useEffect, useCallback} from 'react';
|
memo,
|
||||||
import ContextMenu from '../ContextMenu';
|
useMemo,
|
||||||
import Tooltip from '../Tooltip';
|
useRef,
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
useCallback,
|
||||||
|
createContext,
|
||||||
|
useContext,
|
||||||
|
} from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import createPaste from '../../../fb-stubs/createPaste';
|
|
||||||
import {reportInteraction} from '../../../utils/InteractionTracker';
|
|
||||||
import DataPreview, {DataValueExtractor, InspectorName} from './DataPreview';
|
import DataPreview, {DataValueExtractor, InspectorName} from './DataPreview';
|
||||||
import {getSortedKeys} from './utils';
|
import {getSortedKeys} from './utils';
|
||||||
import {colors} from '../colors';
|
|
||||||
import {clipboard} from 'electron';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {TooltipOptions} from '../TooltipProvider';
|
import {useHighlighter, HighlightManager} from '../Highlight';
|
||||||
import {
|
import {Dropdown, Menu, Tooltip} from 'antd';
|
||||||
_useHighlighter as useHighlighter,
|
import {tryGetFlipperLibImplementation} from '../../plugin/FlipperLib';
|
||||||
_HighlightManager,
|
import {safeStringify} from '../../utils/safeStringify';
|
||||||
} from 'flipper-plugin';
|
|
||||||
|
|
||||||
export {DataValueExtractor} from './DataPreview';
|
export {DataValueExtractor} from './DataPreview';
|
||||||
|
|
||||||
|
export const RootDataContext = createContext<() => any>(() => ({}));
|
||||||
|
|
||||||
const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>(
|
const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>(
|
||||||
(props) => ({
|
(props) => ({
|
||||||
fontFamily: 'Menlo, monospace',
|
fontFamily: 'Menlo, monospace',
|
||||||
@@ -42,7 +45,7 @@ const BaseContainer = styled.div<{depth?: number; disabled?: boolean}>(
|
|||||||
BaseContainer.displayName = 'DataInspector:BaseContainer';
|
BaseContainer.displayName = 'DataInspector:BaseContainer';
|
||||||
|
|
||||||
const RecursiveBaseWrapper = styled.span({
|
const RecursiveBaseWrapper = styled.span({
|
||||||
color: colors.red,
|
color: '#FC3A4B',
|
||||||
});
|
});
|
||||||
RecursiveBaseWrapper.displayName = 'DataInspector:RecursiveBaseWrapper';
|
RecursiveBaseWrapper.displayName = 'DataInspector:RecursiveBaseWrapper';
|
||||||
|
|
||||||
@@ -66,18 +69,13 @@ const ExpandControl = styled.span({
|
|||||||
ExpandControl.displayName = 'DataInspector:ExpandControl';
|
ExpandControl.displayName = 'DataInspector:ExpandControl';
|
||||||
|
|
||||||
const Added = styled.div({
|
const Added = styled.div({
|
||||||
backgroundColor: colors.tealTint70,
|
backgroundColor: '#d2f0ea',
|
||||||
});
|
});
|
||||||
|
|
||||||
const Removed = styled.div({
|
const Removed = styled.div({
|
||||||
backgroundColor: colors.cherryTint70,
|
backgroundColor: '#fbccd2',
|
||||||
});
|
});
|
||||||
|
|
||||||
const nameTooltipOptions: TooltipOptions = {
|
|
||||||
position: 'toLeft',
|
|
||||||
showTail: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DataInspectorSetValue = (path: Array<string>, val: any) => void;
|
export type DataInspectorSetValue = (path: Array<string>, val: any) => void;
|
||||||
|
|
||||||
export type DataInspectorDeleteValue = (path: Array<string>) => void;
|
export type DataInspectorDeleteValue = (path: Array<string>) => void;
|
||||||
@@ -145,7 +143,7 @@ type DataInspectorProps = {
|
|||||||
onRenderName?: (
|
onRenderName?: (
|
||||||
path: Array<string>,
|
path: Array<string>,
|
||||||
name: string,
|
name: string,
|
||||||
highlighter: _HighlightManager,
|
highlighter: HighlightManager,
|
||||||
) => React.ReactElement;
|
) => React.ReactElement;
|
||||||
/**
|
/**
|
||||||
* Render callback that can be used to customize the rendering of object values.
|
* 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<
|
function getRootContextMenu(root: Object) {
|
||||||
Object,
|
const lib = tryGetFlipperLibImplementation();
|
||||||
Array<Electron.MenuItemConstructorOptions>
|
return (
|
||||||
> = new WeakMap();
|
<Menu>
|
||||||
|
<Menu.Item
|
||||||
function getRootContextMenu(
|
key="copyClipboard"
|
||||||
data: Object,
|
onClick={() => {
|
||||||
): Array<Electron.MenuItemConstructorOptions> {
|
lib?.writeTextToClipboard(safeStringify(root));
|
||||||
const cached = rootContextMenuCache.get(data);
|
}}>
|
||||||
if (cached != null) {
|
Copy tree
|
||||||
return cached;
|
</Menu.Item>
|
||||||
}
|
<Menu.Divider />
|
||||||
|
{lib?.isFB && (
|
||||||
let stringValue: string;
|
<Menu.Item
|
||||||
try {
|
key="createPaste"
|
||||||
stringValue = JSON.stringify(data, null, 2);
|
onClick={() => {
|
||||||
} catch (e) {
|
lib?.createPaste(safeStringify(root));
|
||||||
stringValue = '<circular structure>';
|
}}>
|
||||||
}
|
Create paste from tree
|
||||||
const menu: Array<Electron.MenuItemConstructorOptions> = [
|
</Menu.Item>
|
||||||
{
|
)}
|
||||||
label: 'Copy entire tree',
|
</Menu>
|
||||||
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 isPureObject(obj: Object) {
|
function isPureObject(obj: Object) {
|
||||||
@@ -345,6 +322,7 @@ const DataInspector: React.FC<DataInspectorProps> = memo(
|
|||||||
setValue: setValueProp,
|
setValue: setValueProp,
|
||||||
}) {
|
}) {
|
||||||
const highlighter = useHighlighter();
|
const highlighter = useHighlighter();
|
||||||
|
const getRoot = useContext(RootDataContext);
|
||||||
|
|
||||||
const shouldExpand = useRef(false);
|
const shouldExpand = useRef(false);
|
||||||
const expandHandle = useRef(undefined as any);
|
const expandHandle = useRef(undefined as any);
|
||||||
@@ -434,10 +412,6 @@ const DataInspector: React.FC<DataInspectorProps> = memo(
|
|||||||
const handleClick = useCallback(() => {
|
const handleClick = useCallback(() => {
|
||||||
cancelIdleCallback(expandHandle.current);
|
cancelIdleCallback(expandHandle.current);
|
||||||
const isExpanded = shouldBeExpanded(expandedPaths, path, collapsed);
|
const isExpanded = shouldBeExpanded(expandedPaths, path, collapsed);
|
||||||
reportInteraction('DataInspector', path.join(':'))(
|
|
||||||
isExpanded ? 'collapsed' : 'expanded',
|
|
||||||
undefined,
|
|
||||||
);
|
|
||||||
setExpanded(path, !isExpanded);
|
setExpanded(path, !isExpanded);
|
||||||
}, [expandedPaths, path, collapsed]);
|
}, [expandedPaths, path, collapsed]);
|
||||||
|
|
||||||
@@ -534,11 +508,7 @@ const DataInspector: React.FC<DataInspectorProps> = memo(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (expandRoot === true) {
|
if (expandRoot === true) {
|
||||||
return (
|
return <>{propertyNodesContainer}</>;
|
||||||
<ContextMenu component="span" items={getRootContextMenu(data)}>
|
|
||||||
{propertyNodesContainer}
|
|
||||||
</ContextMenu>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create name components
|
// create name components
|
||||||
@@ -551,7 +521,7 @@ const DataInspector: React.FC<DataInspectorProps> = memo(
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
title={tooltips != null && tooltips[name]}
|
title={tooltips != null && tooltips[name]}
|
||||||
key="name"
|
key="name"
|
||||||
options={nameTooltipOptions}>
|
placement="left">
|
||||||
<InspectorName>{text}</InspectorName>
|
<InspectorName>{text}</InspectorName>
|
||||||
</Tooltip>,
|
</Tooltip>,
|
||||||
);
|
);
|
||||||
@@ -562,7 +532,7 @@ const DataInspector: React.FC<DataInspectorProps> = memo(
|
|||||||
let descriptionOrPreview;
|
let descriptionOrPreview;
|
||||||
if (renderExpanded || !isExpandable) {
|
if (renderExpanded || !isExpandable) {
|
||||||
descriptionOrPreview = (
|
descriptionOrPreview = (
|
||||||
<_DataDescription
|
<DataDescription
|
||||||
path={path}
|
path={path}
|
||||||
setValue={setValue}
|
setValue={setValue}
|
||||||
type={type}
|
type={type}
|
||||||
@@ -607,50 +577,58 @@ const DataInspector: React.FC<DataInspectorProps> = memo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const contextMenuItems: MenuTemplate = [];
|
function getContextMenu() {
|
||||||
|
const lib = tryGetFlipperLibImplementation();
|
||||||
if (isExpandable) {
|
return (
|
||||||
contextMenuItems.push(
|
<Menu>
|
||||||
{
|
<Menu.Item
|
||||||
label: shouldExpand.current ? 'Collapse' : 'Expand',
|
key="copyClipboard"
|
||||||
click: handleClick,
|
onClick={() => {
|
||||||
},
|
lib?.writeTextToClipboard(safeStringify(getRoot()));
|
||||||
{
|
}}>
|
||||||
type: 'separator',
|
Copy tree
|
||||||
},
|
</Menu.Item>
|
||||||
|
{lib?.isFB && (
|
||||||
|
<Menu.Item
|
||||||
|
key="createPaste"
|
||||||
|
onClick={() => {
|
||||||
|
lib?.createPaste(safeStringify(getRoot()));
|
||||||
|
}}>
|
||||||
|
Create paste from tree
|
||||||
|
</Menu.Item>
|
||||||
|
)}
|
||||||
|
<Menu.Divider />
|
||||||
|
<Menu.Item
|
||||||
|
key="copyValue"
|
||||||
|
onClick={() => {
|
||||||
|
lib?.writeTextToClipboard(safeStringify(data));
|
||||||
|
}}>
|
||||||
|
Copy value
|
||||||
|
</Menu.Item>
|
||||||
|
{!isExpandable && onDelete ? (
|
||||||
|
<Menu.Item
|
||||||
|
key="delete"
|
||||||
|
onClick={() => {
|
||||||
|
handleDelete(path);
|
||||||
|
}}>
|
||||||
|
Delete
|
||||||
|
</Menu.Item>
|
||||||
|
) : null}
|
||||||
|
</Menu>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (
|
return (
|
||||||
<BaseContainer
|
<BaseContainer
|
||||||
depth={depth}
|
depth={depth}
|
||||||
disabled={!!setValueProp && !!setValue === false}>
|
disabled={!!setValueProp && !!setValue === false}>
|
||||||
<ContextMenu component="span" items={contextMenuItems}>
|
<Dropdown overlay={getContextMenu} trigger={['contextMenu']}>
|
||||||
<PropertyContainer onClick={isExpandable ? handleClick : undefined}>
|
<PropertyContainer onClick={isExpandable ? handleClick : undefined}>
|
||||||
{expandedPaths && <ExpandControl>{expandGlyph}</ExpandControl>}
|
{expandedPaths && <ExpandControl>{expandGlyph}</ExpandControl>}
|
||||||
{descriptionOrPreview}
|
{descriptionOrPreview}
|
||||||
{wrapperStart}
|
{wrapperStart}
|
||||||
</PropertyContainer>
|
</PropertyContainer>
|
||||||
</ContextMenu>
|
</Dropdown>
|
||||||
{propertyNodesContainer}
|
{propertyNodesContainer}
|
||||||
{wrapperEnd}
|
{wrapperEnd}
|
||||||
</BaseContainer>
|
</BaseContainer>
|
||||||
@@ -7,12 +7,11 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {DataDescriptionType, _DataDescription} from 'flipper-plugin';
|
import {DataDescriptionType, DataDescription} from './DataDescription';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import {getSortedKeys} from './utils';
|
import {getSortedKeys} from './utils';
|
||||||
import {PureComponent} from 'react';
|
import {PureComponent} from 'react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {colors} from '../colors';
|
|
||||||
|
|
||||||
export type DataValueExtractor = (
|
export type DataValueExtractor = (
|
||||||
value: any,
|
value: any,
|
||||||
@@ -29,7 +28,7 @@ export type DataValueExtractor = (
|
|||||||
| null;
|
| null;
|
||||||
|
|
||||||
export const InspectorName = styled.span({
|
export const InspectorName = styled.span({
|
||||||
color: colors.grapeDark1,
|
color: '#7b64c0',
|
||||||
});
|
});
|
||||||
InspectorName.displayName = 'DataInspector:InspectorName';
|
InspectorName.displayName = 'DataInspector:InspectorName';
|
||||||
|
|
||||||
@@ -79,7 +78,7 @@ export default class DataPreview extends PureComponent<{
|
|||||||
|
|
||||||
const {type, value} = res;
|
const {type, value} = res;
|
||||||
return (
|
return (
|
||||||
<_DataDescription
|
<DataDescription
|
||||||
key={index}
|
key={index}
|
||||||
type={type}
|
type={type}
|
||||||
value={value}
|
value={value}
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {DataInspectorExpanded} from './DataInspector';
|
import {DataInspectorExpanded, RootDataContext} from './DataInspector';
|
||||||
import {PureComponent} from 'react';
|
import {PureComponent} from 'react';
|
||||||
import DataInspector from './DataInspector';
|
import DataInspector from './DataInspector';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {DataValueExtractor} from './DataPreview';
|
import {DataValueExtractor} from './DataPreview';
|
||||||
import {_HighlightProvider, _HighlightManager} from 'flipper-plugin';
|
import {HighlightProvider, HighlightManager} from '../Highlight';
|
||||||
|
|
||||||
export type ManagedDataInspectorProps = {
|
export type ManagedDataInspectorProps = {
|
||||||
/**
|
/**
|
||||||
@@ -47,7 +47,7 @@ export type ManagedDataInspectorProps = {
|
|||||||
onRenderName?: (
|
onRenderName?: (
|
||||||
path: Array<string>,
|
path: Array<string>,
|
||||||
name: string,
|
name: string,
|
||||||
highlighter: _HighlightManager,
|
highlighter: HighlightManager,
|
||||||
) => React.ReactElement;
|
) => React.ReactElement;
|
||||||
/**
|
/**
|
||||||
* Render callback that can be used to customize the rendering of object values.
|
* 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`
|
* If you require lower level access to the state then use `DataInspector`
|
||||||
* directly.
|
* directly.
|
||||||
*/
|
*/
|
||||||
export default class ManagedDataInspector extends PureComponent<
|
export class ManagedDataInspector extends PureComponent<
|
||||||
ManagedDataInspectorProps,
|
ManagedDataInspectorProps,
|
||||||
ManagedDataInspectorState
|
ManagedDataInspectorState
|
||||||
> {
|
> {
|
||||||
@@ -171,9 +171,15 @@ 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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<_HighlightProvider text={this.props.filter}>
|
<RootDataContext.Provider value={this.getRootData}>
|
||||||
|
<HighlightProvider text={this.props.filter}>
|
||||||
<DataInspector
|
<DataInspector
|
||||||
data={this.props.data}
|
data={this.props.data}
|
||||||
diff={this.props.diff}
|
diff={this.props.diff}
|
||||||
@@ -191,7 +197,8 @@ export default class ManagedDataInspector extends PureComponent<
|
|||||||
depth={0}
|
depth={0}
|
||||||
parentAncestry={EMPTY_ARRAY}
|
parentAncestry={EMPTY_ARRAY}
|
||||||
/>
|
/>
|
||||||
</_HighlightProvider>
|
</HighlightProvider>
|
||||||
|
</RootDataContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,12 +7,12 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ManagedDataInspector from './ManagedDataInspector';
|
import {ManagedDataInspector} from './ManagedDataInspector';
|
||||||
import {Component, ReactNode} from 'react';
|
import {Component, ReactNode} from 'react';
|
||||||
import {colors} from '../colors';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import MarkerTimeline from '../MarkerTimeline';
|
import {MarkerTimeline} from '../MarkerTimeline';
|
||||||
import Button from '../Button';
|
import {Button} from 'antd';
|
||||||
|
import {presetColors} from './DataDescription';
|
||||||
|
|
||||||
type TimePoint = {
|
type TimePoint = {
|
||||||
moment: number;
|
moment: number;
|
||||||
@@ -37,7 +37,7 @@ type State = {
|
|||||||
selected: string;
|
selected: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default class TimelineDataDescription extends Component<Props, State> {
|
export class TimelineDataDescription extends Component<Props, State> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {selected: props.timeline.current};
|
this.state = {selected: props.timeline.current};
|
||||||
@@ -50,7 +50,7 @@ export default class TimelineDataDescription extends Component<Props, State> {
|
|||||||
label: value.display,
|
label: value.display,
|
||||||
time: value.moment - firstMoment,
|
time: value.moment - firstMoment,
|
||||||
color:
|
color:
|
||||||
Object.entries(colors).find(([k, _]) => k === value.color)?.[1] ??
|
Object.entries(presetColors).find(([k, _]) => k === value.color)?.[1] ??
|
||||||
value.color,
|
value.color,
|
||||||
key: value.key,
|
key: value.key,
|
||||||
}));
|
}));
|
||||||
@@ -10,8 +10,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {render, fireEvent, waitFor, act} from '@testing-library/react';
|
import {render, fireEvent, waitFor, act} from '@testing-library/react';
|
||||||
|
|
||||||
import ManagedDataInspector from '../ManagedDataInspector';
|
import {ManagedDataInspector} from '../ManagedDataInspector';
|
||||||
import {sleep} from '../../../../utils';
|
import {sleep} from '../../../utils/sleep';
|
||||||
|
|
||||||
const mocks = {
|
const mocks = {
|
||||||
requestIdleCallback(fn: Function) {
|
requestIdleCallback(fn: Function) {
|
||||||
@@ -124,7 +124,7 @@ test('can filter for data', async () => {
|
|||||||
<span>
|
<span>
|
||||||
"j
|
"j
|
||||||
<span
|
<span
|
||||||
class="css-zr1u3c-Highlighted eiud9hg0"
|
class="css-i709sw-Highlighted eiud9hg0"
|
||||||
>
|
>
|
||||||
son
|
son
|
||||||
</span>
|
</span>
|
||||||
1
desktop/types/index.d.ts
vendored
1
desktop/types/index.d.ts
vendored
@@ -26,4 +26,3 @@
|
|||||||
/// <reference path="nodejs.d.ts" />
|
/// <reference path="nodejs.d.ts" />
|
||||||
/// <reference path="npm-api.d.ts" />
|
/// <reference path="npm-api.d.ts" />
|
||||||
/// <reference path="openssl-wrapper.d.ts" />
|
/// <reference path="openssl-wrapper.d.ts" />
|
||||||
/// <reference path="string-natural-compare.d.ts" />
|
|
||||||
|
|||||||
12
desktop/types/string-natural-compare.d.ts
vendored
12
desktop/types/string-natural-compare.d.ts
vendored
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -2982,6 +2982,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
|
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff"
|
||||||
integrity sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==
|
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":
|
"@types/tar@^4.0.3":
|
||||||
version "4.0.3"
|
version "4.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489"
|
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489"
|
||||||
|
|||||||
@@ -781,6 +781,9 @@ See `View > Flipper Style Guide` inside the Flipper application for more details
|
|||||||
|
|
||||||
### DataTable
|
### DataTable
|
||||||
### DataFormatter
|
### DataFormatter
|
||||||
|
### DataInspector
|
||||||
|
### DataDescription
|
||||||
|
### MarkerTimeline
|
||||||
|
|
||||||
Coming soon.
|
Coming soon.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user