Skip to content

Commit 4d4cd7f

Browse files
committed
feat(ui): cleanup details panel UI and add field and type info to details for better context
1 parent 325a7f1 commit 4d4cd7f

File tree

6 files changed

+187
-76
lines changed

6 files changed

+187
-76
lines changed
Lines changed: 105 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,117 @@
1-
import React from 'react';
2-
import { ReportField } from './reportTypes';
1+
import React from "react";
32

4-
interface Props {
5-
field: ReportField;
6-
}
7-
function DetailsPanel({ field }: Props) {
8-
if (field.occurrences.length === 0) return null;
3+
import Delimiter from "./Delimiter";
4+
import FieldName from "./FieldName";
5+
import FieldType from "./FieldType";
6+
import OccurrencesList from "./OccurrencesList";
7+
import { ReportField } from "./reportTypes";
8+
import TypeName from "./TypeName";
99

10+
const Panel: React.FC = ({ children }) => {
1011
return (
1112
<div
1213
style={{
1314
flex: 1,
14-
borderColor: 'rgba(0,0,0,.1)',
15-
borderLeftStyle: 'solid',
16-
borderLeftWidth: '1px',
17-
position: 'fixed',
15+
borderColor: "rgba(0,0,0,.1)",
16+
borderLeftStyle: "solid",
17+
borderLeftWidth: "1px",
18+
position: "fixed",
19+
top: 0,
1820
right: 0,
19-
left: '60%',
20-
height: '100%',
21-
padding: '24px',
22-
}}>
23-
<h2
24-
style={{
25-
color: 'rgba(0,0,0,.3)',
26-
fontSize: '14px',
27-
textTransform: 'uppercase',
28-
letterSpacing: '1px',
29-
}}>
30-
Occurrences
31-
</h2>
32-
<ul>
33-
{field.occurrences.map(({ filename, rootNodeName }) => {
34-
return (
35-
<li
36-
style={{
37-
paddingBottom: '10px',
38-
}}>
39-
<code>
40-
<a href={filename} target="blank">
41-
{rootNodeName}
42-
</a>
43-
</code>
44-
</li>
45-
);
46-
})}
47-
</ul>
21+
left: "50%",
22+
height: "100%",
23+
marginBottom: "24px",
24+
backgroundColor: "#fff",
25+
boxShadow: "0 0 8px rgba(0, 0, 0, 0.15)"
26+
}}
27+
>
28+
{children}
29+
</div>
30+
);
31+
};
32+
33+
const DetailsPanelHeader: React.FC = ({ children }) => {
34+
return (
35+
<div
36+
style={{
37+
height: "72px",
38+
borderBottomStyle: "solid",
39+
borderBottomWidth: "1px",
40+
borderBottomColor: "rgba(0, 0, 0, 0.1)",
41+
display: "flex",
42+
alignItems: "center",
43+
justifyContent: "space-between",
44+
padding: "0 24px"
45+
}}
46+
>
47+
{children}
4848
</div>
4949
);
50+
};
51+
52+
interface DetailsPanelTitleProps {
53+
field: ReportField;
5054
}
5155

56+
const DetailsPanelTitle: React.FC<DetailsPanelTitleProps> = ({ field }) => {
57+
return (
58+
<div>
59+
<TypeName>{field.parentType}</TypeName>
60+
<Delimiter token="." />
61+
<FieldName>{field.name}</FieldName>
62+
</div>
63+
);
64+
};
65+
66+
const DetailsPanelBody: React.FC = ({ children }) => {
67+
return (
68+
<div
69+
style={{
70+
padding: "0 24px"
71+
}}
72+
>
73+
{children}
74+
</div>
75+
);
76+
};
77+
78+
const DetailsPanelHeading: React.FC = ({ children }) => {
79+
return (
80+
<h2
81+
style={{
82+
color: "rgba(0,0,0,.3)",
83+
fontSize: "14px",
84+
textTransform: "uppercase",
85+
letterSpacing: "1px",
86+
borderBottom: "1px solid #e0e0e0",
87+
padding: "16px 0px 8px 0px"
88+
}}
89+
>
90+
{children}
91+
</h2>
92+
);
93+
};
94+
95+
interface Props {
96+
field: ReportField;
97+
}
98+
99+
const DetailsPanel: React.FC<Props> = ({ field }) => {
100+
if (field.occurrences.length === 0) return null;
101+
102+
return (
103+
<Panel>
104+
<DetailsPanelHeader>
105+
<DetailsPanelTitle field={field} />
106+
</DetailsPanelHeader>
107+
<DetailsPanelBody>
108+
<DetailsPanelHeading>Type</DetailsPanelHeading>
109+
<FieldType>{field.type}</FieldType>
110+
<DetailsPanelHeading>Occurrences</DetailsPanelHeading>
111+
<OccurrencesList field={field} />
112+
</DetailsPanelBody>
113+
</Panel>
114+
);
115+
};
116+
52117
export default DetailsPanel;

graphql-usage-ui/src/FieldName.tsx

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

33
interface Props {
4-
highlight: boolean;
4+
highlight?: boolean;
55
}
66

7-
const FieldName: React.FC<Props> = ({ children, highlight }) => {
7+
const FieldName: React.FC<Props> = ({ children, highlight = false }) => {
88
const highlightStyles = highlight ? { backgroundColor: "#ffffe0" } : {};
99
return (
1010
<span style={{ color: "#1f61a0", padding: "10px 0px", ...highlightStyles }}>

graphql-usage-ui/src/FieldType.tsx

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

33
interface Props {
4-
highlight: boolean;
4+
highlight?: boolean;
55
}
66

7-
const FieldType: React.FC<Props> = ({ children, highlight }) => {
7+
const FieldType: React.FC<Props> = ({ children, highlight = false }) => {
88
const highlightStyles = highlight ? { backgroundColor: "#ffffe0" } : {};
99
return (
1010
<span style={{ color: "#f5a000", padding: "10px 0px", ...highlightStyles }}>

graphql-usage-ui/src/Header.tsx

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,46 @@
1-
import React from 'react';
1+
import React from "react";
22

33
interface SearchBoxProps {
4-
onChange: (searchText: string) => void;
54
searchText: string;
5+
onChange(searchText: string): void;
66
}
7-
function SearchBox({ onChange, searchText }: SearchBoxProps) {
7+
8+
const SearchBox: React.FC<SearchBoxProps> = ({ onChange, searchText }) => {
89
const handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
910
onChange(event.target.value);
1011
};
1112

1213
return (
1314
<label
1415
style={{
15-
backgroundColor: '#fff',
16-
display: 'inline-flex',
17-
alignItems: 'center',
18-
padding: '12px 14px 13px 15px',
19-
boxShadow: '0 1px 3px rgba(0, 0, 0, .1)',
20-
}}>
21-
<i style={{ transform: 'rotate(0deg)', display: 'flex' }}>
16+
backgroundColor: "#fff",
17+
display: "inline-flex",
18+
alignItems: "center",
19+
padding: "0px 14px",
20+
boxShadow: "0 1px 3px rgba(0, 0, 0, .1)",
21+
height: "45px"
22+
}}
23+
>
24+
<i style={{ transform: "rotate(0deg)", display: "flex" }}>
2225
<svg
2326
stroke="rgba(0, 0, 0, 0.3)"
2427
strokeWidth="3px"
2528
fill="none"
26-
style={{ width: '16px', height: '16px' }}
27-
viewBox="0 0 50 50">
29+
style={{ width: "16px", height: "16px" }}
30+
viewBox="0 0 50 50"
31+
>
2832
<circle cx="17.82" cy="18.11" r="16.21" />
2933
<line x1="29.28" y1="29.57" x2="48.21" y2="48.5" />
3034
</svg>
3135
</i>
3236
<input
3337
style={{
34-
marginLeft: '10px',
35-
fontSize: '16px',
36-
border: 'none',
37-
letterSpacing: '0.3px',
38-
color: 'gba(0,0,0,0.8)',
39-
outlineWidth: '0',
38+
marginLeft: "10px",
39+
fontSize: "16px",
40+
border: "none",
41+
letterSpacing: "0.3px",
42+
color: "gba(0,0,0,0.8)",
43+
outlineWidth: "0"
4044
}}
4145
type="text"
4246
placeholder="Search..."
@@ -46,29 +50,34 @@ function SearchBox({ onChange, searchText }: SearchBoxProps) {
4650
/>
4751
</label>
4852
);
49-
}
53+
};
5054

5155
interface HeaderProps {
52-
onSearchChange: (searchText: string) => void;
5356
searchText: string;
57+
onSearchChange(searchText: string): void;
5458
}
55-
function Header({ onSearchChange, searchText }: HeaderProps) {
59+
60+
const Header: React.FC<HeaderProps> = ({ searchText, onSearchChange }) => {
5661
return (
5762
<header
5863
style={{
59-
padding: '24px',
60-
backgroundColor: '#fafafa',
61-
borderColor: 'rgba(0,0,0,.1)',
62-
borderBottomWidth: '1px',
63-
borderBottomStyle: 'solid',
64-
position: 'fixed',
64+
paddingLeft: "24px",
65+
height: "72px",
66+
display: "flex",
67+
alignItems: "center",
68+
backgroundColor: "#fafafa",
69+
borderColor: "rgba(0,0,0,.1)",
70+
borderBottomWidth: "1px",
71+
borderBottomStyle: "solid",
72+
position: "fixed",
6573
top: 0,
6674
left: 0,
67-
right: 0,
68-
}}>
75+
right: 0
76+
}}
77+
>
6978
<SearchBox onChange={onSearchChange} searchText={searchText} />
7079
</header>
7180
);
72-
}
81+
};
7382

7483
export default Header;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from "react";
2+
3+
import { ReportField } from "./reportTypes";
4+
5+
interface Props {
6+
field: ReportField;
7+
}
8+
9+
const OccurrencesList: React.FC<Props> = ({ field }) => {
10+
return (
11+
<ul
12+
style={{
13+
listStyle: "none",
14+
padding: 0
15+
}}
16+
>
17+
{field.occurrences.map(({ filename, rootNodeName }, index) => {
18+
return (
19+
<li
20+
key={index}
21+
style={{
22+
paddingBottom: "10px"
23+
}}
24+
>
25+
<code>
26+
<a href={filename} rel="noopener noreferrer" target="_blank">
27+
{rootNodeName}
28+
</a>
29+
</code>
30+
</li>
31+
);
32+
})}
33+
</ul>
34+
);
35+
};
36+
37+
export default OccurrencesList;

graphql-usage-ui/src/TypeName.tsx

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

33
interface Props {
4-
highlight: boolean;
4+
highlight?: boolean;
55
}
66

7-
const TypeName: React.FC<Props> = ({ children, highlight }) => {
7+
const TypeName: React.FC<Props> = ({ children, highlight = false }) => {
88
const highlightStyles = highlight ? { backgroundColor: "#ffffe0" } : {};
99

1010
return (

0 commit comments

Comments
 (0)