Skip to content

Commit 0c84e0f

Browse files
committed
Fix sidebar action when extracting, Improve breadcrumbs, and add missing tooltips
1 parent 9cb3321 commit 0c84e0f

File tree

9 files changed

+239
-131
lines changed

9 files changed

+239
-131
lines changed

packages/app/src/components/Cytoscape/ControlExtensions/FiltersExtension.tsx

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useState, useEffect, useRef } from "react";
22
import { useParams } from "react-router";
3-
import { Button, DropdownMenu, Checkbox } from "@radix-ui/themes";
3+
import { Button, DropdownMenu, Checkbox, Tooltip } from "@radix-ui/themes";
44
import { LuChevronUp } from "react-icons/lu";
55
import { Core } from "cytoscape";
66
import { toast } from "react-toastify";
@@ -168,24 +168,26 @@ export default function FiltersExtension(props: {
168168
return (
169169
<DropdownMenu.Root>
170170
<DropdownMenu.Trigger>
171-
<Button
172-
size="1"
173-
variant="ghost"
174-
color="violet"
175-
highContrast
176-
className={`${checkFiltersSet() ? "bg-primary-light/20 dark:bg-primary-dark/20" : ""}`}
177-
disabled={props.busy}
178-
onClick={() => props.onLayout()}
179-
>
180-
<MdFilterAlt
181-
className={`text-xl h-5 w-5 ${
182-
checkFiltersSet()
183-
? "text-primary-light dark:text-primary-dark"
184-
: "text-gray-light dark:text-gray-dark"
185-
}`}
186-
/>
187-
<LuChevronUp />
188-
</Button>
171+
<Tooltip content="Filter visible elements" side="top">
172+
<Button
173+
size="1"
174+
variant="ghost"
175+
color="violet"
176+
highContrast
177+
className={`${checkFiltersSet() ? "bg-primary-light/20 dark:bg-primary-dark/20" : ""}`}
178+
disabled={props.busy}
179+
onClick={() => props.onLayout()}
180+
>
181+
<MdFilterAlt
182+
className={`text-xl h-5 w-5 ${
183+
checkFiltersSet()
184+
? "text-primary-light dark:text-primary-dark"
185+
: "text-gray-light dark:text-gray-dark"
186+
}`}
187+
/>
188+
<LuChevronUp />
189+
</Button>
190+
</Tooltip>
189191
</DropdownMenu.Trigger>
190192
<DropdownMenu.Content color="violet" variant="soft">
191193
{/* Add filter options here */}

packages/app/src/components/Cytoscape/ControlExtensions/GraphDepthExtension.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ export default function GraphDepthExtension(props: {
135135
</div>
136136
<Button
137137
color="violet"
138+
loading={props.busy}
138139
disabled={
139140
tempDependencyDepth === dependencyState.depth &&
140141
tempDependentDepth === dependentState.depth

packages/app/src/components/Cytoscape/ControlExtensions/MetricsExtension.tsx

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button, DropdownMenu } from "@radix-ui/themes";
1+
import { Button, DropdownMenu, Tooltip } from "@radix-ui/themes";
22
import { LuChevronUp } from "react-icons/lu";
33
import {
44
Metric,
@@ -50,17 +50,22 @@ export default function MetricsExtension(props: {
5050
return (
5151
<DropdownMenu.Root>
5252
<DropdownMenu.Trigger>
53-
<Button
54-
size="1"
55-
variant="ghost"
56-
color="violet"
57-
highContrast
58-
disabled={props.busy}
59-
className="py-1.5"
53+
<Tooltip
54+
content="Select metric to highlight failing nodes for that metric"
55+
side="top"
6056
>
61-
{getMetricLabel(metric)}
62-
<LuChevronUp />
63-
</Button>
57+
<Button
58+
size="1"
59+
variant="ghost"
60+
color="violet"
61+
highContrast
62+
disabled={props.busy}
63+
className="py-1.5"
64+
>
65+
{getMetricLabel(metric)}
66+
<LuChevronUp />
67+
</Button>
68+
</Tooltip>
6469
</DropdownMenu.Trigger>
6570
<DropdownMenu.Content color="violet" variant="soft">
6671
<DropdownMenu.Item

packages/app/src/components/Cytoscape/Controls.tsx

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Button } from "@radix-ui/themes";
1+
import { Button, Tooltip } from "@radix-ui/themes";
22
import { Core } from "cytoscape";
33
import {
44
MdFilterCenterFocus,
@@ -36,46 +36,54 @@ export default function Controls(props: {
3636
<div className="absolute bottom-6 inset-x-4 z-10 flex justify-around">
3737
<div className="flex gap-3 items-center">
3838
<div className="bg-background-light dark:bg-background-dark flex gap-4 py-2 px-3 rounded-lg">
39-
<Button
40-
size="1"
41-
variant="ghost"
42-
color="violet"
43-
highContrast
44-
disabled={props.busy}
45-
onClick={handleFit}
46-
>
47-
<MdFilterCenterFocus className="text-2xl h-5 w-5" />
48-
</Button>
49-
<Button
50-
size="1"
51-
variant="ghost"
52-
color="violet"
53-
highContrast
54-
disabled={props.busy}
55-
onClick={() => props.onLayout()}
56-
>
57-
<MdOutlineAccountTree className="text-xl h-5 w-5" />
58-
</Button>
59-
<Button
60-
size="1"
61-
variant="ghost"
62-
color="violet"
63-
highContrast
64-
disabled={props.busy}
65-
onClick={() => handleZoom(0.9)}
66-
>
67-
<MdOutlineZoomOut className="text-2xl h-5 w-5" />
68-
</Button>
69-
<Button
70-
size="1"
71-
variant="ghost"
72-
color="violet"
73-
highContrast
74-
disabled={props.busy}
75-
onClick={() => handleZoom(1.1)}
76-
>
77-
<MdOutlineZoomIn className="text-2xl h-5 w-5" />
78-
</Button>
39+
<Tooltip content="Fit to screen" side="top">
40+
<Button
41+
size="1"
42+
variant="ghost"
43+
color="violet"
44+
highContrast
45+
disabled={props.busy}
46+
onClick={handleFit}
47+
>
48+
<MdFilterCenterFocus className="text-2xl h-5 w-5" />
49+
</Button>
50+
</Tooltip>
51+
<Tooltip content="Reset layout" side="top">
52+
<Button
53+
size="1"
54+
variant="ghost"
55+
color="violet"
56+
highContrast
57+
disabled={props.busy}
58+
onClick={() => props.onLayout()}
59+
>
60+
<MdOutlineAccountTree className="text-xl h-5 w-5" />
61+
</Button>
62+
</Tooltip>
63+
<Tooltip content="Zoom out" side="top">
64+
<Button
65+
size="1"
66+
variant="ghost"
67+
color="violet"
68+
highContrast
69+
disabled={props.busy}
70+
onClick={() => handleZoom(0.9)}
71+
>
72+
<MdOutlineZoomOut className="text-2xl h-5 w-5" />
73+
</Button>
74+
</Tooltip>
75+
<Tooltip content="Zoom in" side="top">
76+
<Button
77+
size="1"
78+
variant="ghost"
79+
color="violet"
80+
highContrast
81+
disabled={props.busy}
82+
onClick={() => handleZoom(1.1)}
83+
>
84+
<MdOutlineZoomIn className="text-2xl h-5 w-5" />
85+
</Button>
86+
</Tooltip>
7987
{/* Used to pass extensions into the controls */}
8088
{props.children}
8189
</div>

packages/app/src/components/Cytoscape/contextMenu/SymbolContextMenu.tsx

Lines changed: 32 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Link } from "react-router";
1+
import { Link, useParams } from "react-router";
22
import { DropdownMenu } from "@radix-ui/themes";
33
import { LuPanelRightOpen, LuSearchCode, LuGitGraph } from "react-icons/lu";
44
import { FileDependencyManifest } from "@nanoapi.io/shared";
@@ -16,6 +16,10 @@ export default function SymbolContextMenu(props: {
1616
action: "add" | "remove",
1717
) => void;
1818
}) {
19+
const { file, instance } = useParams();
20+
21+
const isSymbolLevelView = file && instance;
22+
1923
function handleOnExtract() {
2024
props.setExtractionNodes(
2125
props.fileDependencyManifest.filePath,
@@ -48,27 +52,33 @@ export default function SymbolContextMenu(props: {
4852
{props.fileDependencyManifest.symbols[props.symbolId].id}
4953
</h1>
5054
</DropdownMenu.Label>
51-
<DropdownMenu.Separator />
52-
<DropdownMenu.Item
53-
className="px-2 py-1 hover:bg-primary-light dark:hover:bg-primary-dark"
54-
onSelect={() => props.setDetailsPaneOpen(true)}
55-
>
56-
<div className="w-full flex justify-between space-x-2">
57-
<span>Details</span>
58-
<LuPanelRightOpen className="text-lg my-auto" />
59-
</div>
60-
</DropdownMenu.Item>
61-
<DropdownMenu.Item className="px-2 py-1 hover:bg-primary-light dark:hover:bg-primary-dark">
62-
<Link
63-
to={`/audit/${encodeURIComponent(
64-
props.fileDependencyManifest.filePath,
65-
)}/${encodeURIComponent(props.symbolId)}`}
66-
className="w-full flex justify-between space-x-2"
67-
>
68-
<span>Inspect symbol</span>
69-
<LuSearchCode className="text-lg my-auto" />
70-
</Link>
71-
</DropdownMenu.Item>
55+
{/* TODO: There is something wrong with the details pane on the symbol-level view */}
56+
{/* Fix it, and then remove the following */}
57+
{!isSymbolLevelView && (
58+
<>
59+
<DropdownMenu.Separator />
60+
<DropdownMenu.Item
61+
className="px-2 py-1 hover:bg-primary-light dark:hover:bg-primary-dark"
62+
onSelect={() => props.setDetailsPaneOpen(true)}
63+
>
64+
<div className="w-full flex justify-between space-x-2">
65+
<span>Details</span>
66+
<LuPanelRightOpen className="text-lg my-auto" />
67+
</div>
68+
</DropdownMenu.Item>
69+
<DropdownMenu.Item className="px-2 py-1 hover:bg-primary-light dark:hover:bg-primary-dark">
70+
<Link
71+
to={`/audit/${encodeURIComponent(
72+
props.fileDependencyManifest.filePath,
73+
)}/${encodeURIComponent(props.symbolId)}`}
74+
className="w-full flex justify-between space-x-2"
75+
>
76+
<span>Inspect symbol</span>
77+
<LuSearchCode className="text-lg my-auto" />
78+
</Link>
79+
</DropdownMenu.Item>
80+
</>
81+
)}
7282
<DropdownMenu.Separator />
7383
<DropdownMenu.Item
7484
className="px-2 py-1 hover:bg-primary-light dark:hover:bg-primary-dark"

packages/app/src/components/FileExplorer/FileExplorer.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,9 +218,15 @@ export default function FileExplorer(props: {
218218
}
219219

220220
useEffect(() => {
221-
if (extractionPanelRef.current) {
222-
extractionPanelRef.current.resize(50);
223-
}
221+
// Use setTimeout to ensure the panel is resized after the DOM has updated
222+
// IF WE DON'T DO THIS, the panel will not resize correctly when forcing
223+
// the sidebar to open if it was closed.
224+
// This is a side effect of the way we do the sidebar and state management
225+
setTimeout(() => {
226+
if (extractionPanelRef.current) {
227+
extractionPanelRef.current.resize(50);
228+
}
229+
}, 50);
224230
}, [props.extractionState.extractionNodes]);
225231

226232
useEffect(() => {
@@ -271,7 +277,7 @@ export default function FileExplorer(props: {
271277
placeholder="Search"
272278
value={props.search}
273279
onChange={(e) => props.setIsSearch(e.target.value)}
274-
className={`transition-all duration-300 overflow-hidden ${!props.isOpen && "w-0"}`}
280+
className={`min-h-8 transition-all duration-300 overflow-hidden ${!props.isOpen && "w-0"}`}
275281
>
276282
<TextField.Slot>
277283
<MdSearch className="h-6 w-6 my-auto" />
@@ -539,8 +545,11 @@ function ExtractionPanel(props: {
539545
) => void;
540546
}) {
541547
const [editMode, setEditMode] = useState<EditMode>(EditMode.NONE);
548+
const [extractionLoading, setExtractionLoading] = useState(false);
542549

543550
async function runExtractionViaAPI() {
551+
setExtractionLoading(true);
552+
544553
const extractionNodes = Object.values(props.extractionNodes);
545554
const response = await runExtraction(extractionNodes);
546555

@@ -551,6 +560,8 @@ function ExtractionPanel(props: {
551560
} else {
552561
toast.error("Extraction failed. Please check the logs for more details.");
553562
}
563+
564+
setExtractionLoading(false);
554565
}
555566

556567
return (
@@ -586,6 +597,7 @@ function ExtractionPanel(props: {
586597
<Tooltip content="Extract the above symbols into a separate codebase">
587598
<Button
588599
color="violet"
600+
loading={extractionLoading}
589601
className="w-[48%]"
590602
onClick={runExtractionViaAPI}
591603
>

0 commit comments

Comments
 (0)