Skip to content

Commit 3c223ec

Browse files
authored
Merge pull request #145 from nanoapi-io/chore/make-dependency-vislualizer-take-manifest-as-props
chore/make dependency vislualizer take manifest as props
2 parents c34de3d + e0fde93 commit 3c223ec

File tree

7 files changed

+163
-154
lines changed

7 files changed

+163
-154
lines changed

packages/app/src/components/DependencyVisualizer/DependencyVisualizer.tsx

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
1-
import { useEffect, useState } from "react";
1+
import { useState } from "react";
22
import { useSearchParams } from "react-router";
3-
import {
4-
getAuditManifest,
5-
getDependencyManifest,
6-
} from "../../service/api/index.ts";
73
import type { AuditManifest, DependencyManifest } from "@napi/shared";
84
import { SidebarProvider, SidebarTrigger } from "../shadcn/Sidebar.tsx";
95
import { Button } from "../shadcn/Button.tsx";
106
import { Moon, Sun } from "lucide-react";
11-
import { toast } from "sonner";
127
import { useTheme } from "../../contexts/ThemeProvider.tsx";
138
import { FileExplorerSidebar } from "./components/FileExplorerSidebar.tsx";
149
import BreadcrumbNav from "./components/BreadcrumNav.tsx";
@@ -17,7 +12,6 @@ import FileVisualizer from "./visualizers/FileVisualizer.tsx";
1712
import SymbolVisualizer from "./visualizers/SymbolVisualizer.tsx";
1813

1914
export interface VisualizerContext {
20-
busy: boolean;
2115
dependencyManifest: DependencyManifest;
2216
auditManifest: AuditManifest;
2317
highlightedCytoscapeRef: {
@@ -26,65 +20,30 @@ export interface VisualizerContext {
2620
} | undefined;
2721
}
2822

29-
export default function DependencyVisualizer() {
23+
export default function DependencyVisualizer(props: {
24+
dependencyManifest: DependencyManifest;
25+
auditManifest: AuditManifest;
26+
}) {
3027
const [searchParams] = useSearchParams();
3128

3229
const { theme, setTheme } = useTheme();
3330

34-
const [busy, setBusy] = useState<boolean>(true);
35-
36-
const [auditManifest, setAuditManifest] = useState<AuditManifest>({});
37-
const [dependencyManifest, setDependencyManifest] = useState<
38-
DependencyManifest
39-
>({});
40-
4131
const [highlightedCytoscapeRef, setHighlightedCytoscapeRef] = useState<
4232
{
4333
filePath: string;
4434
symbolId: string | undefined;
4535
} | undefined
4636
>(undefined);
4737

48-
useEffect(() => {
49-
async function handleOnLoad() {
50-
setBusy(true);
51-
try {
52-
const dependencyManifestPromise = getDependencyManifest();
53-
const auditManifestPromise = getAuditManifest();
54-
55-
const allPromise = Promise.all([
56-
dependencyManifestPromise,
57-
auditManifestPromise,
58-
]);
59-
60-
toast.promise(allPromise, {
61-
loading: "Loading manifests",
62-
success: "Manifests loaded successfully",
63-
error: "Failed to load manifests",
64-
});
65-
66-
const [dependencyManifest, auditManifest] = await allPromise;
67-
68-
setDependencyManifest(dependencyManifest);
69-
setAuditManifest(auditManifest);
70-
} finally {
71-
setBusy(false);
72-
}
73-
}
74-
75-
handleOnLoad();
76-
}, []);
77-
7838
return (
7939
<SidebarProvider
8040
defaultOpen
8141
className="h-screen w-screen"
8242
style={{ "--sidebar-width": "30rem" } as React.CSSProperties}
8343
>
8444
<FileExplorerSidebar
85-
busy={busy}
86-
dependencyManifest={dependencyManifest}
87-
auditManifest={auditManifest}
45+
dependencyManifest={props.dependencyManifest}
46+
auditManifest={props.auditManifest}
8847
onHighlightInCytoscape={(node) => {
8948
if (!node.fileId) return;
9049
const newRef = {
@@ -160,29 +119,26 @@ export default function DependencyVisualizer() {
160119
{searchParams.get("fileId") && searchParams.get("instanceId")
161120
? (
162121
<SymbolVisualizer
163-
busy={busy}
164122
fileId={searchParams.get("fileId")!}
165123
instanceId={searchParams.get("instanceId")!}
166-
dependencyManifest={dependencyManifest}
167-
auditManifest={auditManifest}
124+
dependencyManifest={props.dependencyManifest}
125+
auditManifest={props.auditManifest}
168126
highlightedCytoscapeRef={highlightedCytoscapeRef}
169127
/>
170128
)
171129
: searchParams.get("fileId")
172130
? (
173131
<FileVisualizer
174-
busy={busy}
175132
fileId={searchParams.get("fileId")!}
176-
dependencyManifest={dependencyManifest}
177-
auditManifest={auditManifest}
133+
dependencyManifest={props.dependencyManifest}
134+
auditManifest={props.auditManifest}
178135
highlightedCytoscapeRef={highlightedCytoscapeRef}
179136
/>
180137
)
181138
: (
182139
<ProjectVisualizer
183-
busy={busy}
184-
dependencyManifest={dependencyManifest}
185-
auditManifest={auditManifest}
140+
dependencyManifest={props.dependencyManifest}
141+
auditManifest={props.auditManifest}
186142
highlightedCytoscapeRef={highlightedCytoscapeRef}
187143
/>
188144
)}

packages/app/src/components/DependencyVisualizer/components/FileExplorerSidebar.tsx

Lines changed: 82 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
SidebarRail,
1010
} from "../../shadcn/Sidebar.tsx";
1111
import { Button } from "../../shadcn/Button.tsx";
12-
import { Skeleton } from "../../shadcn/Skeleton.tsx";
1312
import { Input } from "../../shadcn/Input.tsx";
1413
import {
1514
Tooltip,
@@ -36,7 +35,6 @@ export interface ExplorerNodeData {
3635
}
3736

3837
export function FileExplorerSidebar(props: {
39-
busy: boolean;
4038
dependencyManifest: DependencyManifest;
4139
auditManifest: AuditManifest;
4240
onHighlightInCytoscape: (node: ExplorerNodeData) => void;
@@ -181,56 +179,46 @@ export function FileExplorerSidebar(props: {
181179
</SidebarHeader>
182180

183181
<SidebarContent>
184-
{props.busy
185-
? (
186-
<SidebarGroup className="flex flex-col space-y-5">
187-
{Array.from({ length: 10 }).map((_, index) => (
188-
<Skeleton key={index} className="w-full h-6" />
189-
))}
190-
</SidebarGroup>
191-
)
192-
: (
193-
<SidebarGroup className="flex h-full">
194-
<ScrollArea>
195-
<Tooltip delayDuration={500}>
196-
<TooltipTrigger asChild>
197-
<Input
198-
value={search}
199-
onChange={(e) => setSearch(e.target.value)}
200-
placeholder="Search"
201-
/>
202-
</TooltipTrigger>
203-
<TooltipContent>
204-
<div className="text-sm">
205-
Search for a file or symbol.
206-
<br />
207-
The search will find partial matches in both symbol names
208-
and file paths.
209-
</div>
210-
</TooltipContent>
211-
</Tooltip>
212-
213-
<div className="pt-2">
214-
{!explorerTree
215-
? (
216-
<div className="text-sm font-muted italic">
217-
No Matching files found
218-
</div>
219-
)
220-
: (
221-
<ExplorerNode
222-
node={explorerTree}
223-
level={0}
224-
onHighlightInCytoscape={props
225-
.onHighlightInCytoscape}
226-
toDetails={props.toDetails}
227-
/>
228-
)}
182+
<SidebarGroup className="flex h-full">
183+
<ScrollArea>
184+
<Tooltip delayDuration={500}>
185+
<TooltipTrigger asChild>
186+
<Input
187+
value={search}
188+
onChange={(e) => setSearch(e.target.value)}
189+
placeholder="Search"
190+
/>
191+
</TooltipTrigger>
192+
<TooltipContent>
193+
<div className="text-sm">
194+
Search for a file or symbol.
195+
<br />
196+
The search will find partial matches in both symbol names and
197+
file paths.
229198
</div>
230-
<ScrollBar orientation="vertical" />
231-
</ScrollArea>
232-
</SidebarGroup>
233-
)}
199+
</TooltipContent>
200+
</Tooltip>
201+
202+
<div className="pt-2">
203+
{!explorerTree
204+
? (
205+
<div className="text-sm font-muted italic">
206+
No Matching files found
207+
</div>
208+
)
209+
: (
210+
<ExplorerNode
211+
node={explorerTree}
212+
level={0}
213+
onHighlightInCytoscape={props
214+
.onHighlightInCytoscape}
215+
toDetails={props.toDetails}
216+
/>
217+
)}
218+
</div>
219+
<ScrollBar orientation="vertical" />
220+
</ScrollArea>
221+
</SidebarGroup>
234222
</SidebarContent>
235223
<SidebarRail />
236224
</Sidebar>
@@ -275,45 +263,49 @@ function ExplorerNode(props: {
275263
);
276264
case "file":
277265
return (
278-
<div className="flex items-center space-x-1">
279-
<Button
280-
variant="ghost"
281-
size="sm"
282-
onClick={() => setShowChildren(!showChildren)}
283-
className="w-full justify-start"
284-
>
285-
<File />
286-
<DisplayNameWithTooltip
287-
name={props.node.displayName}
288-
maxChar={Math.max(5, 30 - props.level * 2)}
289-
/>
290-
</Button>
291-
<Tooltip delayDuration={500}>
292-
<TooltipTrigger asChild>
293-
<Button
294-
variant="secondary"
295-
size="sm"
296-
onClick={() => props.onHighlightInCytoscape(props.node)}
297-
>
298-
<ScanEye />
299-
</Button>
300-
</TooltipTrigger>
301-
<TooltipContent className="text-xs">
302-
Highlight in graph
303-
</TooltipContent>
304-
</Tooltip>
305-
<Tooltip delayDuration={500}>
306-
<TooltipTrigger asChild>
307-
<Button asChild variant="secondary" size="sm">
308-
<Link to={props.toDetails(props.node)}>
309-
<SearchCode />
310-
</Link>
311-
</Button>
312-
</TooltipTrigger>
313-
<TooltipContent className="text-xs">
314-
View graph for this file
315-
</TooltipContent>
316-
</Tooltip>
266+
<div className="flex justify-between items-center">
267+
<div className="flex items-center space-x-1">
268+
<Button
269+
variant="ghost"
270+
size="sm"
271+
onClick={() => setShowChildren(!showChildren)}
272+
className="w-full justify-start"
273+
>
274+
<File />
275+
<DisplayNameWithTooltip
276+
name={props.node.displayName}
277+
maxChar={Math.max(5, 30 - props.level * 2)}
278+
/>
279+
</Button>
280+
</div>
281+
<div className="flex items-center space-x-1">
282+
<Tooltip delayDuration={500}>
283+
<TooltipTrigger asChild>
284+
<Button
285+
variant="secondary"
286+
size="sm"
287+
onClick={() => props.onHighlightInCytoscape(props.node)}
288+
>
289+
<ScanEye />
290+
</Button>
291+
</TooltipTrigger>
292+
<TooltipContent className="text-xs">
293+
Highlight in graph
294+
</TooltipContent>
295+
</Tooltip>
296+
<Tooltip delayDuration={500}>
297+
<TooltipTrigger asChild>
298+
<Button asChild variant="secondary" size="sm">
299+
<Link to={props.toDetails(props.node)}>
300+
<SearchCode />
301+
</Link>
302+
</Button>
303+
</TooltipTrigger>
304+
<TooltipContent className="text-xs">
305+
View graph for this file
306+
</TooltipContent>
307+
</Tooltip>
308+
</div>
317309
</div>
318310
);
319311
case "symbol":

packages/app/src/components/DependencyVisualizer/visualizers/FileVisualizer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export default function FileVisualizer(
171171

172172
<div className="absolute bottom-10 left-1/2 transform -translate-x-1/2 z-20">
173173
<Controls
174-
busy={props.busy || busy}
174+
busy={busy}
175175
cy={fileVisualizer?.cy}
176176
onLayout={() => fileVisualizer?.layoutGraph(fileVisualizer.cy)}
177177
>

packages/app/src/components/DependencyVisualizer/visualizers/ProjectVisualizer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,12 @@ export default function ProjectVisualizer(props: VisualizerContext) {
128128

129129
<div className="absolute bottom-10 left-1/2 transform -translate-x-1/2 z-20">
130130
<Controls
131-
busy={props.busy || busy}
131+
busy={busy}
132132
cy={projectVisualizer?.cy}
133133
onLayout={() => projectVisualizer?.layoutGraph(projectVisualizer.cy)}
134134
>
135135
<MetricsExtension
136-
busy={props.busy || busy}
136+
busy={busy}
137137
metricState={{
138138
metric,
139139
setMetric: handleMetricChange,

packages/app/src/components/DependencyVisualizer/visualizers/SymbolVisualizer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,12 @@ export default function SymbolVisualizer(
165165

166166
<div className="absolute bottom-10 left-1/2 transform -translate-x-1/2 z-20">
167167
<Controls
168-
busy={props.busy || busy}
168+
busy={busy}
169169
cy={symbolVisualizer?.cy}
170170
onLayout={() => symbolVisualizer?.layoutGraph(symbolVisualizer.cy)}
171171
>
172172
<GraphDepthExtension
173-
busy={props.busy || busy}
173+
busy={busy}
174174
dependencyState={{
175175
depth: dependencyDepth,
176176
setDepth: handleDependencyDepthChange,

packages/app/src/main.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import ReactDOM from "react-dom/client";
55
import { createBrowserRouter, RouterProvider } from "react-router";
66
import { Toaster } from "./components/shadcn/Sonner.tsx";
77
import { ThemeProvider } from "./contexts/ThemeProvider.tsx";
8-
import DependencyVisualizer from "./components/DependencyVisualizer/DependencyVisualizer.tsx";
8+
import IndexPage from "./pages/index.tsx";
99

1010
const router = createBrowserRouter([
1111
{
1212
path: "/",
13-
element: <DependencyVisualizer />,
13+
element: <IndexPage />,
1414
},
1515
]);
1616

0 commit comments

Comments
 (0)