Tree generation search

Summary:
Added the ability to search tree generations for a particular component. As soon as you start typing in the search bar, only relevant timeline tracks would be displayed.

Currently, I'm looking for the search string in `component_class_name` of the payload and among all nodes in the tree.

Reviewed By: fabiomassimo

Differential Revision: D21175734

fbshipit-source-id: 642c628350192697980becd20352d303200a031e
This commit is contained in:
Andrey Mishanin
2020-04-22 05:14:03 -07:00
committed by Facebook GitHub Bot
parent 7e768f3e1f
commit e4ea3ecec6

View File

@@ -33,6 +33,9 @@ import {
Spacer, Spacer,
colors, colors,
DetailSidebar, DetailSidebar,
SearchInput,
SearchBox,
SearchIcon,
} from 'flipper'; } from 'flipper';
const Waiting = styled(FlexBox)((props) => ({ const Waiting = styled(FlexBox)((props) => ({
@@ -62,6 +65,7 @@ type State = {
focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload, focusedChangeSet: ?UpdateTreeGenerationChangesetApplicationPayload,
userSelectedGenerationId: ?string, userSelectedGenerationId: ?string,
selectedTreeNode: ?Object, selectedTreeNode: ?Object,
searchString: string,
}; };
type PersistedState = { type PersistedState = {
@@ -153,6 +157,7 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
focusedChangeSet: null, focusedChangeSet: null,
userSelectedGenerationId: null, userSelectedGenerationId: null,
selectedTreeNode: null, selectedTreeNode: null,
searchString: '',
}; };
onTreeGenerationFocused = (focusedGenerationId: ?string) => { onTreeGenerationFocused = (focusedGenerationId: ?string) => {
@@ -239,6 +244,54 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
}); });
}; };
onChange = (e: any) => {
this.setState({searchString: e.target.value});
};
generationValues = () => {
const {generations} = this.props.persistedState;
const generationKeys = Object.keys(generations);
return (generationKeys.map(
(key) => generations[key],
): Array<TreeGeneration>);
};
matchesCurrentSearchString = (s: string) => {
return s.toLowerCase().includes(this.state.searchString.toLowerCase());
};
matchingGenerationKeys = () => {
const matchingKeys: Array<string> = this.generationValues()
.filter((g) => {
if (g.payload) {
const componentClassName: ?string = g.payload['component_class_name'];
if (componentClassName) {
return this.matchesCurrentSearchString(componentClassName);
}
}
return g.tree?.some((node) => {
return this.matchesCurrentSearchString(node.name);
});
})
.map((g) => {
return g.surface_key;
});
return new Set<string>(matchingKeys);
};
filteredGenerations = () => {
if (this.state.searchString.length <= 0) {
return Object.values(this.props.persistedState.generations);
}
const matchingKeys = this.matchingGenerationKeys();
return (this.generationValues().filter((g) => {
return matchingKeys.has(g.surface_key);
}): Array<TreeGeneration>);
};
render() { render() {
const {generations} = this.props.persistedState; const {generations} = this.props.persistedState;
if (Object.values(this.props.persistedState.generations).length === 0) { if (Object.values(this.props.persistedState.generations).length === 0) {
@@ -256,6 +309,18 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
return ( return (
<React.Fragment> <React.Fragment>
<Toolbar> <Toolbar>
<SearchBox tabIndex={-1}>
<SearchIcon
name="magnifying-glass"
color={colors.macOSTitleBarIcon}
size={16}
/>
<SearchInput
placeholder={'Search'}
onChange={this.onChange}
value={this.state.searchString}
/>
</SearchBox>
<Spacer /> <Spacer />
{this.props.persistedState.recording ? ( {this.props.persistedState.recording ? (
<Button <Button
@@ -276,7 +341,7 @@ export default class extends FlipperPlugin<State, *, PersistedState> {
</Toolbar> </Toolbar>
<Sidebar position="top" minHeight={80} height={80}> <Sidebar position="top" minHeight={80} height={80}>
<EventTable <EventTable
generations={Object.values(generations)} generations={this.filteredGenerations()}
focusedGenerationId={focusedGenerationId} focusedGenerationId={focusedGenerationId}
onClick={this.onTreeGenerationFocused} onClick={this.onTreeGenerationFocused}
/> />