Display data model in side panel

Summary:
This displays the data models passed to the Sections in the side panel when a data node is clicked. This does not change the collapse behaviour when a Section node is clicked.
To make it easier to associate a section with its changesets, appended the global indexes a Section is responsible for to the node label.

Reviewed By: passy

Differential Revision: D16283820

fbshipit-source-id: f1149f47dff448de05d919f7f8d16a2aba53bbb0
This commit is contained in:
Mihaela Ogrezeanu
2019-07-17 06:25:39 -07:00
committed by Facebook Github Bot
parent a9e90aa9b2
commit 11198e003e
5 changed files with 68 additions and 6 deletions

View File

@@ -235,6 +235,7 @@ public class ChangesetDebug implements ChangesetDebugListener {
nodeBuilder.put( nodeBuilder.put(
"parent", section.getParent() == null ? null : section.getParent().getGlobalKey()); "parent", section.getParent() == null ? null : section.getParent().getGlobalKey());
nodeBuilder.put("removed", true); nodeBuilder.put("removed", true);
nodeBuilder.put("isSection", true);
tree.put(nodeBuilder.build()); 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("inserted", operation == Change.INSERT || operation == Change.INSERT_RANGE);
dataObject.put("removed", operation == Change.DELETE || operation == Change.DELETE_RANGE); dataObject.put("removed", operation == Change.DELETE || operation == Change.DELETE_RANGE);
dataObject.put("updated", operation == Change.UPDATE || operation == Change.UPDATE_RANGE); dataObject.put("updated", operation == Change.UPDATE || operation == Change.UPDATE_RANGE);
dataObject.put("isDataModel", true);
tree.put(dataObject.build()); tree.put(dataObject.build());
} }
} }
private static void createSectionTree( private static void createSectionTree(
Section rootSection, FlipperArray.Builder tree, Section oldRootSection) { Section rootSection, FlipperArray.Builder tree, Section oldRootSection) {
createSectionTreeRecursive(rootSection, "", tree, oldRootSection); createSectionTreeRecursive(rootSection, "", tree, oldRootSection, 0);
addRemovedSectionNodes(oldRootSection, rootSection, tree); addRemovedSectionNodes(oldRootSection, rootSection, tree);
} }
private static void createSectionTreeRecursive( 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) { if (rootSection == null) {
return; return;
} }
int endIndex = startIndex + ChangesetDebugConfiguration.getSectionCount(rootSection) - 1;
final String name = "[" + startIndex + ", " + endIndex + "] " + rootSection.getSimpleName();
final String globalKey = rootSection.getGlobalKey(); final String globalKey = rootSection.getGlobalKey();
final FlipperObject.Builder nodeBuilder = new FlipperObject.Builder(); final FlipperObject.Builder nodeBuilder = new FlipperObject.Builder();
@@ -403,11 +412,12 @@ public class ChangesetDebug implements ChangesetDebugListener {
final boolean isDirty = ChangesetDebugConfiguration.isSectionDirty(oldSection, rootSection); final boolean isDirty = ChangesetDebugConfiguration.isSectionDirty(oldSection, rootSection);
nodeBuilder.put("identifier", globalKey); nodeBuilder.put("identifier", globalKey);
nodeBuilder.put("name", rootSection.getSimpleName()); nodeBuilder.put("name", name);
nodeBuilder.put("parent", parentKey); nodeBuilder.put("parent", parentKey);
nodeBuilder.put("isDirty", isDirty); nodeBuilder.put("isDirty", isDirty);
nodeBuilder.put("isReused", !isDirty); nodeBuilder.put("isReused", !isDirty);
nodeBuilder.put("didTriggerStateUpdate", false); // TODO nodeBuilder.put("didTriggerStateUpdate", false); // TODO
nodeBuilder.put("isSection", true);
tree.put(nodeBuilder.build()); tree.put(nodeBuilder.build());
if (rootSection.getChildren() == null) { if (rootSection.getChildren() == null) {
@@ -415,7 +425,12 @@ public class ChangesetDebug implements ChangesetDebugListener {
} }
for (int i = 0; i < rootSection.getChildren().size(); i++) { 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);
} }
} }
} }

View File

@@ -32,6 +32,7 @@ type Props = {|
onFocusChangeSet: ( onFocusChangeSet: (
focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload, focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload,
) => void, ) => void,
selectedNodeInfo: ?Object,
|}; |};
export default class DetailsPanel extends Component<Props> { export default class DetailsPanel extends Component<Props> {
@@ -82,6 +83,14 @@ export default class DetailsPanel extends Component<Props> {
/> />
</Panel> </Panel>
)} )}
{this.props.selectedNodeInfo && (
<Panel floating={false} heading="Selected Node Info">
<ManagedDataInspector
data={this.props.selectedNodeInfo}
expandRoot={true}
/>
</Panel>
)}
</React.Fragment> </React.Fragment>
); );
} }

View File

@@ -36,6 +36,8 @@ export type UpdateTreeGenerationHierarchyGenerationPayload = {|
removed?: boolean, removed?: boolean,
updated?: boolean, updated?: boolean,
unchanged?: boolean, unchanged?: boolean,
isSection?: boolean,
isDataModel?: boolean,
}>, }>,
|}; |};

View File

@@ -66,6 +66,7 @@ type TreeData = Array<{
type Props = { type Props = {
data: TreeData | SectionComponentHierarchy, data: TreeData | SectionComponentHierarchy,
nodeClickHandler?: (node, evt) => void,
}; };
type State = { type State = {
@@ -227,6 +228,7 @@ export default class extends PureComponent<Props, State> {
}, },
}} }}
nodeSize={{x: 300, y: 100}} nodeSize={{x: 300, y: 100}}
onClick={this.props.nodeClickHandler}
/> />
)} )}
</Container> </Container>

View File

@@ -59,6 +59,7 @@ const InfoBox = styled('div')(props => ({
type State = { type State = {
focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload, focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload,
userSelectedGenerationId: ?string, userSelectedGenerationId: ?string,
selectedTreeNode: ?Object,
}; };
type PersistedState = { type PersistedState = {
@@ -149,12 +150,14 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
state = { state = {
focusedChangeSet: null, focusedChangeSet: null,
userSelectedGenerationId: null, userSelectedGenerationId: null,
selectedTreeNode: null,
}; };
onTreeGenerationFocused = (focusedGenerationId: ?string) => { onTreeGenerationFocused = (focusedGenerationId: ?string) => {
this.setState({ this.setState({
focusedChangeSet: null, focusedChangeSet: null,
userSelectedGenerationId: focusedGenerationId, userSelectedGenerationId: focusedGenerationId,
selectedTreeNode: null,
}); });
}; };
@@ -163,20 +166,50 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
) => { ) => {
this.setState({ this.setState({
focusedChangeSet, 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) => { renderTreeHierarchy = (generation: ?TreeGeneration) => {
if (generation && generation.tree && generation.tree.length > 0) { if (generation && generation.tree && generation.tree.length > 0) {
// Display component tree hierarchy, if any // Display component tree hierarchy, if any
return <Tree data={generation.tree} />; return (
<Tree data={generation.tree} nodeClickHandler={this.onNodeClicked} />
);
} else if ( } else if (
this.state.focusedChangeSet && this.state.focusedChangeSet &&
this.state.focusedChangeSet.section_component_hierarchy this.state.focusedChangeSet.section_component_hierarchy
) { ) {
// Display section component hierarchy for specific changeset // Display section component hierarchy for specific changeset
return ( return (
<Tree data={this.state.focusedChangeSet.section_component_hierarchy} /> <Tree
data={this.state.focusedChangeSet.section_component_hierarchy}
nodeClickHandler={this.onNodeClicked}
/>
); );
} else { } else {
return this.renderWaiting(); return this.renderWaiting();
@@ -258,6 +291,7 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
changeSets={focusedTreeGeneration?.changeSets} changeSets={focusedTreeGeneration?.changeSets}
onFocusChangeSet={this.onFocusChangeSet} onFocusChangeSet={this.onFocusChangeSet}
focusedChangeSet={this.state.focusedChangeSet} focusedChangeSet={this.state.focusedChangeSet}
selectedNodeInfo={this.state.selectedTreeNode}
/> />
</DetailSidebar> </DetailSidebar>
</React.Fragment> </React.Fragment>