Skip to content

Commit 28e01dc

Browse files
authored
Feature: Json Tree searcheable (#2)
* Searcheable implementation in json tree * Json tree styling * Json tree overflow:auto * Readme updated
1 parent af0f4a3 commit 28e01dc

File tree

9 files changed

+126
-41
lines changed

9 files changed

+126
-41
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import React from "react";
2+
import { JSONTree } from "react-json-tree";
3+
import theme from "./treeTheme";
4+
import JSONTreeSearcheableProps from "./types";
5+
import Searchbar from "../Searchbar";
6+
import useTreeSearcheableData from "./useTreeSearcheableData";
7+
8+
const JSONTreeSearcheable: React.FC<JSONTreeSearcheableProps> = ({ data }) => {
9+
const {
10+
searchTerm,
11+
setSearchTerm,
12+
getItemString,
13+
highlightLabel,
14+
highlightValue,
15+
} = useTreeSearcheableData();
16+
17+
return (
18+
<div>
19+
<div className="json-tree-header">
20+
<Searchbar value={searchTerm} setValue={setSearchTerm} />
21+
</div>
22+
<div className="json-tree-header-container">
23+
<JSONTree
24+
data={data}
25+
theme={theme}
26+
shouldExpandNodeInitially={() => true}
27+
getItemString={() => (
28+
<span dangerouslySetInnerHTML={{ __html: getItemString(data) }} />
29+
)}
30+
labelRenderer={([key]) => (
31+
<span dangerouslySetInnerHTML={{ __html: highlightLabel(key) }} />
32+
)}
33+
valueRenderer={(value: string) => (
34+
<span dangerouslySetInnerHTML={{ __html: highlightValue(value) }} />
35+
)}
36+
/>
37+
</div>
38+
</div>
39+
);
40+
};
41+
42+
export default JSONTreeSearcheable;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
interface JSONTreeSearcheableProps {
2+
data: unknown;
3+
}
4+
5+
export default JSONTreeSearcheableProps;
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { useState } from "react";
2+
3+
const useTreeSearcheableData = () => {
4+
const [searchTerm, setSearchTerm] = useState("");
5+
6+
const getItemString = (data: unknown) => {
7+
const size = Object.keys(data).length;
8+
9+
if (size === 0) {
10+
return null;
11+
}
12+
13+
const pluralize = size > 1 ? "items" : "item";
14+
const displayText = `${size} ${pluralize}`;
15+
16+
return `<span style={{ fontSize: 11 }}>${displayText}</span>`;
17+
};
18+
19+
const highlightLabel = (label: string | number) => {
20+
if (!searchTerm.trim()) return label;
21+
22+
const regex = new RegExp(searchTerm, "gi");
23+
return label
24+
.toString()
25+
.replace(
26+
regex,
27+
(match) => `<span style="background-color: purple">${match}</span>`
28+
);
29+
};
30+
31+
const highlightValue = (value: string) => {
32+
if (!searchTerm.trim()) return value;
33+
34+
const regex = new RegExp(searchTerm, "gi");
35+
return value
36+
.toString()
37+
.replace(
38+
regex,
39+
(match) => `<span style="background-color: yellow">${match}</span>`
40+
);
41+
};
42+
43+
return {
44+
searchTerm,
45+
setSearchTerm,
46+
getItemString,
47+
highlightLabel,
48+
highlightValue,
49+
};
50+
};
51+
52+
export default useTreeSearcheableData;

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

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,13 @@
1-
import * as React from "react";
1+
import React from "react";
22
import TitleHeader from "../TitleHeader";
33
import LabelValueText from "../LabelValueText";
4-
import { JSONTree } from "react-json-tree";
54
import QueryDetailsProps from "./types";
6-
import theme from "./treeTheme";
5+
import JSONTreeSearcheable from "../JSONTreeSearcheable";
76

87
const QueryDetails: React.FC<QueryDetailsProps> = ({
98
selectedQuery,
109
queryLastUpdated,
1110
}) => {
12-
const getItemString = (data: unknown) => {
13-
const size = Object.keys(data).length;
14-
15-
if (size === 0) {
16-
return null;
17-
}
18-
19-
const pluralize = size > 1 ? "items" : "item";
20-
const displayText = `${size} ${pluralize}`;
21-
22-
return <span style={{ fontSize: 11 }}>{displayText}</span>;
23-
};
24-
2511
if (selectedQuery) {
2612
return (
2713
<div className="column">
@@ -43,15 +29,8 @@ const QueryDetails: React.FC<QueryDetailsProps> = ({
4329

4430
<div style={{ marginBottom: 20 }} />
4531

46-
<div>
47-
<TitleHeader title="Data Explorer" />
48-
<JSONTree
49-
data={selectedQuery?.data}
50-
theme={theme}
51-
shouldExpandNodeInitially={() => true}
52-
getItemString={(_, data) => getItemString(data)}
53-
/>
54-
</div>
32+
<TitleHeader title="Data Explorer" />
33+
<JSONTreeSearcheable data={selectedQuery?.data} />
5534
</div>
5635
</div>
5736
);

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

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ import SearchbarProps from "./types";
33

44
const Searchbar: React.FC<SearchbarProps> = ({ value, setValue }) => {
55
return (
6-
<div className="searchbar-container">
7-
<input
8-
className="searchbar-input"
9-
type="search"
10-
placeholder="Filter"
11-
value={value}
12-
onChange={(event) => setValue(event.target.value)}
13-
/>
14-
</div>
6+
<input
7+
className="searchbar-input"
8+
type="search"
9+
placeholder="Filter"
10+
value={value}
11+
onChange={(event) => setValue(event.target.value)}
12+
/>
1513
);
1614
};
1715

packages/react-native-query-devtool-app/src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
6-
<title>Query Debugger Tool</title>
6+
<title>React Query Devtool</title>
77
</head>
88
<body>
99
<div id="root"></div>

packages/react-native-query-devtool-app/src/pages/QueryDevtool/style.css

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,22 @@
7676
background-color: #172335;
7777
}
7878

79-
.searchbar-container {
80-
flex: 1;
81-
}
82-
8379
.searchbar-input {
8480
box-sizing: border-box;
8581
height: 25px;
8682
width: 300px;
8783
font-size: medium;
8884
}
85+
86+
.json-tree-header {
87+
display: flex;
88+
align-items: center;
89+
justify-content: space-between;
90+
padding-inline: 5px;
91+
margin-bottom: 5px;
92+
}
93+
94+
.json-tree-header-container {
95+
overflow: auto;
96+
height: 540px;
97+
}

packages/react-native-query-devtool-app/src/server/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ const createServer = (mainWindow: BrowserWindow) => {
6666
server.close();
6767
res.end("Server closed.");
6868

69-
console.info(`Query Debugger Tool server closed`);
69+
console.info(`React Native Query Devtool server closed`);
7070
}
7171
});
7272

7373
//start server
7474
server.listen(port, () => {
75-
console.info(`Query Debugger Tool listening on port: ${port}`);
75+
console.info(`React Native Query Devtool listening on port: ${port}`);
7676
});
7777
};
7878

0 commit comments

Comments
 (0)