-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathAPITreeView.tsx
101 lines (90 loc) · 2.65 KB
/
APITreeView.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import { type FC, useMemo } from 'react'
import type { Endpoint, Method } from '../../types'
import { APIMethodBadge } from './APIMethodBadge'
import TreeView, { type TreeItemType } from '../shared/TreeView'
import type { TreeItem, TreeItemIndex } from 'react-complex-tree'
export interface APITreeItemType extends TreeItemType<Endpoint> {
method?: Method
}
interface Props {
endpoints: Endpoint[]
onSelect: (endpoint: Endpoint) => void
defaultTreeIndex: TreeItemIndex
}
const APITreeView: FC<Props> = ({ endpoints, onSelect, defaultTreeIndex }) => {
const treeItems: Record<
TreeItemIndex,
TreeItem<APITreeItemType>
> = useMemo(() => {
const rootItem: TreeItem = {
index: 'root',
isFolder: true,
children: [],
data: null,
}
const rootItems: Record<TreeItemIndex, TreeItem<APITreeItemType>> = {
root: rootItem,
}
for (const endpoint of endpoints) {
// add api if not added already
if (!rootItems[endpoint.api]) {
rootItems[endpoint.api] = {
index: endpoint.api,
isFolder: true,
children: [],
data: {
label: endpoint.api,
},
}
rootItem.children!.push(endpoint.api)
}
// add each method of each path
const id = endpoint.id
rootItems[id] = {
index: id,
data: {
label: `${endpoint.method} - ${endpoint.path}`,
method: endpoint.method,
data: endpoint,
parent: rootItems[endpoint.api],
},
}
rootItems[endpoint.api].children?.push(id)
}
return rootItems
}, [endpoints])
return (
<TreeView<APITreeItemType>
label="API Explorer"
initialItem={defaultTreeIndex}
items={treeItems}
getItemTitle={(item) => item.data.label}
onPrimaryAction={(items) => {
if (items.data.data) {
onSelect(items.data.data)
}
}}
renderItemTitle={({ title, item }) => (
<>
{!item.isFolder && item.data.method ? (
<div className="grid w-full grid-cols-12 gap-4">
<div className="col-span-5 flex">
<APIMethodBadge method={item.data.method} />
</div>
<div className="col-span-7 flex justify-start">
<span className="truncate text-foreground">{item.data.data?.path}</span>
</div>
</div>
) : (
<span className="text-foreground">
{item.children?.length
? `${title} (${item.children.length})`
: title}
</span>
)}
</>
)}
/>
)
}
export default APITreeView