diff --git a/android/src/main/java/com/facebook/flipper/plugins/sections/ChangesetDebug.java b/android/src/main/java/com/facebook/flipper/plugins/sections/ChangesetDebug.java index 06ebafa8a..777d88c8c 100644 --- a/android/src/main/java/com/facebook/flipper/plugins/sections/ChangesetDebug.java +++ b/android/src/main/java/com/facebook/flipper/plugins/sections/ChangesetDebug.java @@ -235,6 +235,7 @@ public class ChangesetDebug implements ChangesetDebugListener { nodeBuilder.put( "parent", section.getParent() == null ? null : section.getParent().getGlobalKey()); nodeBuilder.put("removed", true); + nodeBuilder.put("isSection", true); tree.put(nodeBuilder.build()); } } @@ -380,22 +381,30 @@ public class ChangesetDebug implements ChangesetDebugListener { dataObject.put("inserted", operation == Change.INSERT || operation == Change.INSERT_RANGE); dataObject.put("removed", operation == Change.DELETE || operation == Change.DELETE_RANGE); dataObject.put("updated", operation == Change.UPDATE || operation == Change.UPDATE_RANGE); + dataObject.put("isDataModel", true); tree.put(dataObject.build()); } } private static void createSectionTree( Section rootSection, FlipperArray.Builder tree, Section oldRootSection) { - createSectionTreeRecursive(rootSection, "", tree, oldRootSection); + createSectionTreeRecursive(rootSection, "", tree, oldRootSection, 0); addRemovedSectionNodes(oldRootSection, rootSection, tree); } private static void createSectionTreeRecursive( - Section rootSection, String parentKey, FlipperArray.Builder tree, Section oldRootSection) { + Section rootSection, + String parentKey, + FlipperArray.Builder tree, + Section oldRootSection, + int startIndex) { if (rootSection == null) { return; } + int endIndex = startIndex + ChangesetDebugConfiguration.getSectionCount(rootSection) - 1; + final String name = "[" + startIndex + ", " + endIndex + "] " + rootSection.getSimpleName(); + final String globalKey = rootSection.getGlobalKey(); final FlipperObject.Builder nodeBuilder = new FlipperObject.Builder(); @@ -403,11 +412,12 @@ public class ChangesetDebug implements ChangesetDebugListener { final boolean isDirty = ChangesetDebugConfiguration.isSectionDirty(oldSection, rootSection); nodeBuilder.put("identifier", globalKey); - nodeBuilder.put("name", rootSection.getSimpleName()); + nodeBuilder.put("name", name); nodeBuilder.put("parent", parentKey); nodeBuilder.put("isDirty", isDirty); nodeBuilder.put("isReused", !isDirty); nodeBuilder.put("didTriggerStateUpdate", false); // TODO + nodeBuilder.put("isSection", true); tree.put(nodeBuilder.build()); if (rootSection.getChildren() == null) { @@ -415,7 +425,12 @@ public class ChangesetDebug implements ChangesetDebugListener { } for (int i = 0; i < rootSection.getChildren().size(); i++) { - createSectionTreeRecursive(rootSection.getChildren().get(i), globalKey, tree, oldRootSection); + if (i > 0) { + startIndex += + ChangesetDebugConfiguration.getSectionCount(rootSection.getChildren().get(i - 1)); + } + createSectionTreeRecursive( + rootSection.getChildren().get(i), globalKey, tree, oldRootSection, startIndex); } } } diff --git a/src/plugins/sections/DetailsPanel.js b/src/plugins/sections/DetailsPanel.js index 2e3a774d1..4b024684b 100644 --- a/src/plugins/sections/DetailsPanel.js +++ b/src/plugins/sections/DetailsPanel.js @@ -32,6 +32,7 @@ type Props = {| onFocusChangeSet: ( focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload, ) => void, + selectedNodeInfo: ?Object, |}; export default class DetailsPanel extends Component { @@ -82,6 +83,14 @@ export default class DetailsPanel extends Component { /> )} + {this.props.selectedNodeInfo && ( + + + + )} ); } diff --git a/src/plugins/sections/Models.js b/src/plugins/sections/Models.js index c0d90e7f8..dee7377aa 100644 --- a/src/plugins/sections/Models.js +++ b/src/plugins/sections/Models.js @@ -36,6 +36,8 @@ export type UpdateTreeGenerationHierarchyGenerationPayload = {| removed?: boolean, updated?: boolean, unchanged?: boolean, + isSection?: boolean, + isDataModel?: boolean, }>, |}; diff --git a/src/plugins/sections/Tree.js b/src/plugins/sections/Tree.js index 11475ee10..4a6a06976 100644 --- a/src/plugins/sections/Tree.js +++ b/src/plugins/sections/Tree.js @@ -66,6 +66,7 @@ type TreeData = Array<{ type Props = { data: TreeData | SectionComponentHierarchy, + nodeClickHandler?: (node, evt) => void, }; type State = { @@ -227,6 +228,7 @@ export default class extends PureComponent { }, }} nodeSize={{x: 300, y: 100}} + onClick={this.props.nodeClickHandler} /> )} diff --git a/src/plugins/sections/index.js b/src/plugins/sections/index.js index 0ef602e72..67cee8754 100644 --- a/src/plugins/sections/index.js +++ b/src/plugins/sections/index.js @@ -59,6 +59,7 @@ const InfoBox = styled('div')(props => ({ type State = { focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload, userSelectedGenerationId: ?string, + selectedTreeNode: ?Object, }; type PersistedState = { @@ -149,12 +150,14 @@ export default class extends FlipperPlugin { state = { focusedChangeSet: null, userSelectedGenerationId: null, + selectedTreeNode: null, }; onTreeGenerationFocused = (focusedGenerationId: ?string) => { this.setState({ focusedChangeSet: null, userSelectedGenerationId: focusedGenerationId, + selectedTreeNode: null, }); }; @@ -163,20 +166,50 @@ export default class extends FlipperPlugin { ) => { this.setState({ focusedChangeSet, + selectedTreeNode: null, + }); + }; + + onNodeClicked = (targetNode, evt) => { + if (targetNode.attributes.isSection) { + this.setState({ + selectedTreeNode: null, + }); + return; + } + + let dataModel; + const selectedTreeNode = {}; + // Not all models can be parsed. + if (targetNode.attributes.isDataModel) { + try { + dataModel = JSON.parse(targetNode.attributes.identifier); + } catch (e) { + dataModel = targetNode.attributes.identifier; + } + } + + this.setState({ + selectedTreeNode: {dataModel}, }); }; renderTreeHierarchy = (generation: ?TreeGeneration) => { if (generation && generation.tree && generation.tree.length > 0) { // Display component tree hierarchy, if any - return ; + return ( + + ); } else if ( this.state.focusedChangeSet && this.state.focusedChangeSet.section_component_hierarchy ) { // Display section component hierarchy for specific changeset return ( - + ); } else { return this.renderWaiting(); @@ -258,6 +291,7 @@ export default class extends FlipperPlugin { changeSets={focusedTreeGeneration?.changeSets} onFocusChangeSet={this.onFocusChangeSet} focusedChangeSet={this.state.focusedChangeSet} + selectedNodeInfo={this.state.selectedTreeNode} />