Skip to content

Commit 4e12a7f

Browse files
committed
Searchbar feature and data node selection
1 parent 740ba7c commit 4e12a7f

26 files changed

Lines changed: 488 additions & 227 deletions

File tree

576 Bytes
Loading
614 Bytes
Loading

packages/react-native-query-devtool/src/components/CloseButton/index.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1-
import React from 'react';
1+
import React from "react";
22

3-
import { Pressable, StyleSheet, View } from 'react-native';
3+
import { Pressable, StyleSheet, View } from "react-native";
44

5-
const CloseButton: React.FC<{ onPress: () => void }> = ({ onPress }) => {
5+
interface Props {
6+
onPress: () => void;
7+
}
8+
9+
const CloseButton: React.FC<Props> = ({ onPress }) => {
610
return (
711
<Pressable style={styles.container} onPress={onPress}>
812
<View style={styles.close} />
@@ -14,15 +18,15 @@ const styles = StyleSheet.create({
1418
container: {
1519
width: 40,
1620
height: 20,
17-
alignContent: 'center',
18-
justifyContent: 'center',
21+
alignContent: "center",
22+
justifyContent: "center",
1923
},
2024
close: {
2125
width: 20,
22-
alignSelf: 'flex-end',
26+
alignSelf: "flex-end",
2327
borderWidth: 2,
2428
borderRadius: 3,
25-
borderColor: 'white',
29+
borderColor: "white",
2630
},
2731
});
2832

packages/react-native-query-devtool/src/components/CopyButton/index.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import React from "react";
2+
23
import { Image, Pressable, StyleSheet } from "react-native";
34

4-
const CopyButton: React.FC<{ onPress?: () => void }> = ({ onPress }) => {
5+
interface Props {
6+
onPress?: () => void;
7+
}
8+
9+
const CopyButton: React.FC<Props> = ({ onPress }) => {
510
return (
611
<Pressable onPress={onPress}>
712
<Image

packages/react-native-query-devtool/src/components/DataExplorer/index.jsx

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React from "react";
2+
3+
import { View } from "react-native";
4+
5+
import JSONTreeData from "../JSONTreeData";
6+
import { styles } from "./style";
7+
8+
interface Props {
9+
selectedQueryData: any;
10+
searchTerm: string;
11+
onSelectedNode: (nodeTitle: string, node: any) => void;
12+
}
13+
14+
const DataExplorer: React.FC<Props> = ({
15+
selectedQueryData,
16+
searchTerm,
17+
onSelectedNode,
18+
}) => {
19+
if (!selectedQueryData) return null;
20+
21+
return (
22+
<View style={styles.container}>
23+
<JSONTreeData
24+
data={selectedQueryData}
25+
searchTerm={searchTerm}
26+
onSelectedNode={onSelectedNode}
27+
/>
28+
</View>
29+
);
30+
};
31+
32+
export default DataExplorer;

packages/react-native-query-devtool/src/components/Devtool/index.tsx

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React from "react";
22

3-
import { ScrollView, Text, View, FlatList } from "react-native";
3+
import { FlatList, ScrollView, Text, View } from "react-native";
44

55
import { ScrollView as ActionsheetScrollview } from "react-native-actions-sheet";
66

@@ -17,28 +17,48 @@ const Devtool: React.FC<QueryDevtoolProps> = (props) => {
1717
const {
1818
filteredQueries,
1919
selectedQuery,
20-
filter,
2120
flalistRef,
22-
setFilter,
21+
filteredData,
22+
searchRef,
23+
searchStringQueries,
24+
searchStringData,
25+
setSearchStringQueries,
26+
handleChangeSearchQueryData,
2327
handleSelectedRow,
28+
handleOnselectedNode,
29+
dataToLookup,
2430
} = useDevtoolData(props);
2531

2632
const renderHeader = () => (
2733
<View style={styles.searchbarContainer}>
28-
<Searchbar filter={filter} setFilter={setFilter} />
34+
<Searchbar
35+
filter={searchStringQueries}
36+
setFilter={setSearchStringQueries}
37+
placeholder="Filter queries"
38+
/>
2939
</View>
3040
);
3141

3242
const renderDataExplorerHeader = () => {
3343
if (!selectedQuery) return null;
3444

3545
return (
36-
<>
37-
<View style={styles.headerContainer}>
46+
<View style={styles.headerContainer}>
47+
<View style={styles.headerTitleContainer}>
3848
<Text style={styles.headerText}>Data Explorer</Text>
3949
<CloseButton onPress={() => handleSelectedRow()} />
4050
</View>
41-
</>
51+
<Searchbar
52+
ref={searchRef}
53+
filter={searchStringData}
54+
setFilter={handleChangeSearchQueryData}
55+
placeholder={
56+
dataToLookup?.nodeTitle
57+
? `Search in '${dataToLookup?.nodeTitle}'`
58+
: "Search in 'data'"
59+
}
60+
/>
61+
</View>
4262
);
4363
};
4464

@@ -47,7 +67,11 @@ const Devtool: React.FC<QueryDevtoolProps> = (props) => {
4767

4868
return (
4969
<View style={styles.dataExplorerContainer}>
50-
<DataExplorer selectedQuery={selectedQuery?.data} />
70+
<DataExplorer
71+
searchTerm={searchStringData}
72+
selectedQueryData={filteredData ?? selectedQuery?.data}
73+
onSelectedNode={handleOnselectedNode}
74+
/>
5175
</View>
5276
);
5377
};

packages/react-native-query-devtool/src/components/Devtool/styles.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,14 @@ export const styles = StyleSheet.create({
1111
paddingBottom: 1,
1212
},
1313
headerContainer: {
14+
backgroundColor: "#132337",
15+
},
16+
headerTitleContainer: {
1417
flexDirection: "row",
1518
justifyContent: "space-between",
1619
alignItems: "center",
17-
backgroundColor: "#132337",
1820
padding: 10,
21+
paddingBottom: 0,
1922
borderTopLeftRadius: 10,
2023
borderTopRightRadius: 10,
2124
},

packages/react-native-query-devtool/src/components/Devtool/useDevtoolData.ts

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,43 @@
11
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
22

3-
import { FlatList } from "react-native";
3+
import { FlatList, TextInput } from "react-native";
44

55
import {
66
ListenerEventType,
77
QueryDevtoolData,
88
QueryDevtoolProps,
99
QueryKey,
1010
} from "../../types";
11+
import fuzzySearch from "../../utils/fuzzySearch";
1112
import {
1213
getQueryDevtoolData,
1314
handleQueryDevtoolData,
1415
} from "../../utils/queryListener";
1516

17+
import useDebounce from "../../hooks/useDebounce";
18+
1619
const useDevtoolData = (props: QueryDevtoolProps) => {
1720
const { queryClient, version = "v5" } = props;
1821

1922
const isInitialized = useRef(false);
20-
const flalistRef = useRef<FlatList>();
23+
const flalistRef = useRef<FlatList>(null);
2124
const timeoutRef = useRef<NodeJS.Timeout>();
25+
const searchRef = useRef<TextInput>(null);
2226

2327
const [queries, setQueries] = useState<QueryDevtoolData[]>([]);
2428
const [selectedQueryKey, setSelectedQueryKey] = useState<QueryKey>();
25-
const [filter, setFilter] = useState("");
29+
30+
const [searchStringQueries, setSearchStringQueries] = useState("");
31+
const [searchStringData, setSearchStringData] = useState("");
32+
33+
// State to determine where to search (2nd Searchbar)
34+
const [dataToLookup, setDataToLookup] = useState<{
35+
nodeTitle: string;
36+
nodeData: any;
37+
}>();
38+
39+
// State to show query data filtered
40+
const [filteredData, setFilteredData] = useState<any>();
2641

2742
useEffect(() => {
2843
if (isInitialized.current) return;
@@ -60,15 +75,15 @@ const useDevtoolData = (props: QueryDevtoolProps) => {
6075

6176
setQueries((prevData) => {
6277
const queryKeyIndex = prevData.findIndex(
63-
(item) => item.queryKey === queryKey
78+
(item) => item.queryKey === queryKey,
6479
);
6580

6681
return handleQueryDevtoolData(
6782
version,
6883
listenerType,
6984
queryKeyIndex,
7085
query,
71-
[...prevData]
86+
[...prevData],
7287
);
7388
});
7489
});
@@ -82,17 +97,20 @@ const useDevtoolData = (props: QueryDevtoolProps) => {
8297
() =>
8398
queries.find(
8499
(query) =>
85-
JSON.stringify(query?.queryKey) === JSON.stringify(selectedQueryKey)
100+
JSON.stringify(query?.queryKey) === JSON.stringify(selectedQueryKey),
86101
),
87-
[selectedQueryKey, queries]
102+
[selectedQueryKey, queries],
88103
);
89104

90105
const filteredQueries = useMemo(
91106
() =>
92107
queries.filter((query) =>
93-
query.queryKey?.toString().toLowerCase().includes(filter.toLowerCase())
108+
query.queryKey
109+
?.toString()
110+
.toLowerCase()
111+
.includes(searchStringQueries.toLowerCase()),
94112
),
95-
[queries, filter]
113+
[queries, searchStringQueries],
96114
);
97115

98116
const handleSelectedRow = useCallback(
@@ -102,32 +120,64 @@ const useDevtoolData = (props: QueryDevtoolProps) => {
102120
return;
103121
}
104122

105-
const queriesSource = filter.length > 0 ? filteredQueries : queries;
123+
const queriesSource =
124+
searchStringQueries.length > 0 ? filteredQueries : queries;
106125
const queryKey = queriesSource[indexRow].queryKey;
107126

108127
setSelectedQueryKey((prev) => (prev !== queryKey ? queryKey : undefined));
109-
110-
timeoutRef.current = setTimeout(
111-
() =>
112-
flalistRef.current.scrollToIndex({
113-
index: indexRow,
114-
animated: true,
115-
viewPosition: 1,
116-
}),
117-
200
118-
);
128+
setSearchStringData("");
129+
setDataToLookup(undefined);
130+
131+
timeoutRef.current = setTimeout(() => {
132+
searchRef.current?.focus();
133+
134+
flalistRef.current?.scrollToIndex({
135+
index: indexRow,
136+
animated: true,
137+
viewPosition: 1,
138+
});
139+
}, 200);
119140
},
120-
[queries, filteredQueries, filter]
141+
[queries, filteredQueries, searchStringQueries],
121142
);
122143

144+
const handleSearch = useDebounce((term) => {
145+
const whereToSearch = dataToLookup?.nodeData
146+
? dataToLookup.nodeData
147+
: selectedQuery?.data;
148+
149+
setFilteredData(fuzzySearch(term, whereToSearch));
150+
}, 500);
151+
152+
const handleChangeSearchQueryData = (searchTerm: string) => {
153+
setSearchStringData(searchTerm);
154+
155+
if (searchTerm.trim() === "" || searchTerm.trim().length <= 2) {
156+
setFilteredData(undefined);
157+
} else {
158+
handleSearch(searchTerm);
159+
}
160+
};
161+
162+
const handleOnselectedNode = (nodeTitle: string, nodeData: any) => {
163+
setDataToLookup({ nodeTitle, nodeData });
164+
searchRef.current?.focus();
165+
};
166+
123167
return {
124168
selectedQueryKey,
125169
selectedQuery,
126-
filter,
170+
searchStringQueries,
127171
filteredQueries,
128172
flalistRef,
129-
setFilter,
173+
searchRef,
174+
searchStringData,
175+
filteredData,
176+
dataToLookup,
177+
setSearchStringQueries,
178+
handleChangeSearchQueryData,
130179
handleSelectedRow,
180+
handleOnselectedNode,
131181
};
132182
};
133183

packages/react-native-query-devtool/src/components/FloatingButton/index.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ import { Image, TouchableOpacity } from "react-native";
44

55
import { styles } from "./styles";
66

7-
const FloatingButton: React.FC<{ onPress: () => void }> = ({ onPress }) => {
7+
interface Props {
8+
onPress: () => void;
9+
}
10+
11+
const FloatingButton: React.FC<Props> = ({ onPress }) => {
812
return (
913
<TouchableOpacity
1014
activeOpacity={0.8}

0 commit comments

Comments
 (0)