From 649688db2a67dab8904adc43ea8ba52993855ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=BCchele?= Date: Mon, 18 Feb 2019 04:53:55 -0800 Subject: [PATCH] Sidebar Summary: This is mostly only moving the Sidebar from the old LayoutInspctor to a separate file. The old file was part of the UI component, however, it was super specific to the layout inspector, so I felt it makes sense moving it there. Here is a diff between the new `src/plugins/layout/layout2/InspectorSidebar.js` and `src/ui/components/elements-inspector/sidebar.js`: P60951781 The old file is still kept around, as long as the old and new layout inspector are run side by side. Reviewed By: passy Differential Revision: D14100537 fbshipit-source-id: b5a6fbae9866732800bb9b2b8fb1b996b9861db6 --- .../layout/layout2/InspectorSidebar.js | 193 ++++++++++++++++++ src/plugins/layout/layout2/index.js | 21 ++ src/plugins/layout/package.json | 1 + src/plugins/layout/yarn.lock | 5 + 4 files changed, 220 insertions(+) create mode 100644 src/plugins/layout/layout2/InspectorSidebar.js diff --git a/src/plugins/layout/layout2/InspectorSidebar.js b/src/plugins/layout/layout2/InspectorSidebar.js new file mode 100644 index 000000000..247351cf3 --- /dev/null +++ b/src/plugins/layout/layout2/InspectorSidebar.js @@ -0,0 +1,193 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ + +import type {Element} from 'flipper'; +import type {PluginClient} from 'flipper'; +import type Client from '../../../Client.js'; +import type {Logger} from '../../../fb-interfaces/Logger.js'; + +import { + GK, + ManagedDataInspector, + Console, + Panel, + FlexCenter, + styled, + colors, +} from 'flipper'; +import {Component} from 'react'; + +const deepEqual = require('deep-equal'); + +const NoData = styled(FlexCenter)({ + fontSize: 18, + color: colors.macOSTitleBarIcon, +}); + +type OnValueChanged = (path: Array, val: any) => void; + +type InspectorSidebarSectionProps = { + data: any, + id: string, + onValueChanged: ?OnValueChanged, + tooltips?: Object, +}; + +class InspectorSidebarSection extends Component { + setValue = (path: Array, value: any) => { + if (this.props.onValueChanged) { + this.props.onValueChanged([this.props.id, ...path], value); + } + }; + + shouldComponentUpdate(nextProps: InspectorSidebarSectionProps) { + return ( + !deepEqual(nextProps, this.props) || + this.props.id !== nextProps.id || + this.props.onValueChanged !== nextProps.onValueChanged + ); + } + + extractValue = (val: any, depth: number) => { + if (val && val.__type__) { + return { + mutable: Boolean(val.__mutable__), + type: val.__type__ === 'auto' ? typeof val.value : val.__type__, + value: val.value, + }; + } else { + return { + mutable: typeof val === 'object', + type: typeof val, + value: val, + }; + } + }; + + render() { + const {id} = this.props; + return ( + + + + ); + } +} + +type Props = {| + element: ?Element, + tooltips?: Object, + onValueChanged: ?OnValueChanged, + client: PluginClient, + realClient: Client, + logger: Logger, + extensions?: Array, +|}; + +type State = {| + isConsoleEnabled: boolean, +|}; + +export default class Sidebar extends Component { + state = { + isConsoleEnabled: false, + }; + + constructor(props: Props) { + super(props); + this.checkIfConsoleIsEnabled(); + } + + componentDidUpdate(prevProps: Props, prevState: State) { + if (prevProps.client !== this.props.client) { + this.checkIfConsoleIsEnabled(); + } + } + + checkIfConsoleIsEnabled() { + this.props.client + .call('isConsoleEnabled') + .then((result: {isEnabled: boolean}) => { + this.setState({isConsoleEnabled: result.isEnabled}); + }); + } + + render() { + const {element, extensions} = this.props; + if (!element || !element.data) { + return No data; + } + + const sections: Array = + (extensions && + extensions.map(ext => + ext( + this.props.client, + this.props.realClient, + element.id, + this.props.logger, + ), + )) || + []; + + for (const key in element.data) { + if (key === 'Extra Sections') { + for (const extraSection in element.data[key]) { + let data = element.data[key][extraSection]; + + // data might be sent as stringified JSON, we want to parse it for a nicer persentation. + if (typeof data === 'string') { + try { + data = JSON.parse(data); + } catch (e) { + // data was not a valid JSON, type is required to be an object + console.error( + `ElementsInspector unable to parse extra section: ${extraSection}`, + ); + data = {}; + } + } + sections.push( + , + ); + } + } else { + sections.push( + , + ); + } + } + + if (GK.get('sonar_show_console_plugin') && this.state.isConsoleEnabled) { + sections.push( + + element.id} /> + , + ); + } + return sections; + } +} diff --git a/src/plugins/layout/layout2/index.js b/src/plugins/layout/layout2/index.js index 11cd0533c..e3d07e479 100644 --- a/src/plugins/layout/layout2/index.js +++ b/src/plugins/layout/layout2/index.js @@ -15,9 +15,11 @@ import { Sidebar, Link, Glyph, + DetailSidebar, } from 'flipper'; import Inspector from './Inspector'; import ToolbarIcon from './ToolbarIcon'; +import InspectorSidebar from './InspectorSidebar'; type State = {| init: boolean, @@ -116,6 +118,15 @@ export default class Layout extends FlipperPlugin { onDataValueChanged: this.onDataValueChanged, }; + let element; + if (this.state.inAXMode && this.state.selectedAXElement) { + element = this.props.persistedState.AXelements[ + this.state.selectedAXElement + ]; + } else if (this.state.selectedElement) { + element = this.props.persistedState.elements[this.state.selectedElement]; + } + return ( {this.state.init && ( @@ -162,8 +173,18 @@ export default class Layout extends FlipperPlugin { )} + + + )} + {/* TODO: Remove this when rolling out publicly */}   Version 2.0:  Provide feedback about this plugin diff --git a/src/plugins/layout/package.json b/src/plugins/layout/package.json index e1055fd47..d48c85449 100644 --- a/src/plugins/layout/package.json +++ b/src/plugins/layout/package.json @@ -4,6 +4,7 @@ "main": "index.js", "license": "MIT", "dependencies": { + "deep-equal": "^1.0.1", "lodash.debounce": "^4.0.8" }, "title": "Layout", diff --git a/src/plugins/layout/yarn.lock b/src/plugins/layout/yarn.lock index d1a61d5bd..0c31eed10 100644 --- a/src/plugins/layout/yarn.lock +++ b/src/plugins/layout/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"