Skip to content

Commit

Permalink
Merge branch 'staging' into fix-collapse
Browse files Browse the repository at this point in the history
  • Loading branch information
Anchel123 authored Feb 6, 2025
2 parents 3281912 + e4f1d2b commit 7b75a2c
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 95 deletions.
47 changes: 41 additions & 6 deletions app/components/code-graph.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Dispatch, RefObject, SetStateAction, useContext, useEffect, useRef, useState } from "react";
import { GraphData, Node } from "./model";
import { GraphData, Link, Node } from "./model";
import { GraphContext } from "./provider";
import { Toolbar } from "./toolbar";
import { Labels } from "./labels";
import { GitFork, Search, X } from "lucide-react";
import { Download, GitFork, Search, X } from "lucide-react";
import ElementMenu from "./elementMenu";
import Combobox from "./combobox";
import { toast } from '@/components/ui/use-toast';
Expand All @@ -21,7 +21,7 @@ const GraphView = dynamic(() => import('./graphView'));
interface Props {
data: GraphData,
setData: Dispatch<SetStateAction<GraphData>>,
onFetchGraph: (graphName: string) => void,
onFetchGraph: (graphName: string) => Promise<void>,
onFetchNode: (nodeIds: number[]) => Promise<GraphData>,
options: string[]
setOptions: Dispatch<SetStateAction<string[]>>
Expand Down Expand Up @@ -55,7 +55,7 @@ export function CodeGraph({
let graph = useContext(GraphContext)

const [url, setURL] = useState("");
const [selectedObj, setSelectedObj] = useState<Node>();
const [selectedObj, setSelectedObj] = useState<Node | Link>();
const [selectedObjects, setSelectedObjects] = useState<Node[]>([]);
const [position, setPosition] = useState<Position>();
const [graphName, setGraphName] = useState<string>("");
Expand Down Expand Up @@ -145,9 +145,10 @@ export function CodeGraph({
}

run()

}, [graphName])

function handleSelectedValue(value: string) {
async function handleSelectedValue(value: string) {
setGraphName(value)
onFetchGraph(value)
}
Expand Down Expand Up @@ -241,7 +242,8 @@ export function CodeGraph({
graph.visibleLinks(true, [chartNode!.id])
setData({ ...graph.Elements })
}


setSearchNode(n)
setTimeout(() => {
chart.zoomToFit(1000, 150, (n: NodeObject<Node>) => n.id === chartNode!.id);
}, 0)
Expand All @@ -259,6 +261,33 @@ export function CodeGraph({
setData({ ...graph.Elements })
}

const handleDownloadImage = async () => {
try {
const canvas = document.querySelector('.force-graph-container canvas') as HTMLCanvasElement;
if (!canvas) {
toast({
title: "Error",
description: "Canvas not found",
variant: "destructive",
});
return;
}

const dataURL = canvas.toDataURL('image/webp');
const link = document.createElement('a');
link.href = dataURL;
link.download = `${graphName}.webp`;
link.click();
} catch (error) {
console.error('Error downloading graph image:', error);
toast({
title: "Error",
description: "Failed to download image. Please try again.",
variant: "destructive",
});
}
};

return (
<div className="h-full w-full flex flex-col gap-4 p-8 bg-gray-100">
<header className="flex flex-col gap-4">
Expand Down Expand Up @@ -351,6 +380,12 @@ export function CodeGraph({
className="pointer-events-auto"
chartRef={chartRef}
/>
<button
className="pointer-events-auto bg-white p-2 rounded-md"
onClick={handleDownloadImage}
>
<Download />
</button>
</div>
</div>
<ElementMenu
Expand Down
127 changes: 87 additions & 40 deletions app/components/dataPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import { Dispatch, SetStateAction, useRef, useEffect, useState } from "react";
import { Node } from "./model";
import { Dispatch, SetStateAction } from "react";
import { JSONTree } from 'react-json-tree';
import { Link, Node } from "./model";
import { Copy, SquareArrowOutUpRight, X } from "lucide-react";
import SyntaxHighlighter from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/hljs';

interface Props {
obj: Node | undefined;
setObj: Dispatch<SetStateAction<Node | undefined>>;
obj: Node | Link | undefined;
setObj: Dispatch<SetStateAction<Node | Link | undefined>>;
url: string;
}

const excludedProperties = [
"category",
"label",
"color",
"expand",
"collapsed",
"isPath",
"isPathStartEnd",
"visible",
"index",
"curve",
"__indexColor",
"isPathSelected",
"__controlPoints",
"x",
"y",
"vx",
Expand All @@ -30,20 +35,16 @@ const excludedProperties = [

export default function DataPanel({ obj, setObj, url }: Props) {

const containerRef = useRef<HTMLDivElement>(null);
const [containerHeight, setContainerHeight] = useState(0);

useEffect(() => {
if (containerRef.current) {
setContainerHeight(containerRef.current.clientHeight);
}
}, [containerRef.current]);
debugger

if (!obj) return null;

const label = `${obj.category}: ${obj.name}`
const type = "category" in obj
const label = type ? `${obj.category}: ${obj.name}` : obj.label
const object = Object.entries(obj).filter(([k]) => !excludedProperties.includes(k))

console.log(obj)

return (
<div data-name="node-details-panel" className="z-20 absolute -top-10 left-20 bg-[#343434] text-white shadow-lg rounded-lg flex flex-col max-h-[88%] max-w-[56%] overflow-hidden" >
<header className="bg-[#191919] flex items-center gap-8 justify-between p-8">
Expand All @@ -52,7 +53,7 @@ export default function DataPanel({ obj, setObj, url }: Props) {
<X color="white" />
</button>
</header>
<main ref={containerRef} className="bg-[#343434] flex flex-col grow overflow-y-auto p-4">
<main className="bg-[#343434] flex flex-col grow overflow-y-auto p-4">
{
object.map(([key, value]) => (
<div key={key} className="flex gap-2">
Expand All @@ -73,40 +74,86 @@ export default function DataPanel({ obj, setObj, url }: Props) {
>
{value}
</SyntaxHighlighter>
: <p className="text-white">{value}</p>
: typeof value === "object" ?
<JSONTree
data={Object.fromEntries(Object.entries(value).filter(([k]) => !excludedProperties.includes(k)))}
theme={{
base00: '#343434', // background
base01: '#000000',
base02: '#CE9178',
base03: '#CE9178', // open values
base04: '#CE9178',
base05: '#CE9178',
base06: '#CE9178',
base07: '#CE9178',
base08: '#CE9178',
base09: '#b5cea8', // numbers
base0A: '#CE9178',
base0B: '#CE9178', // close values
base0C: '#CE9178',
base0D: '#99E4E5', // * keys
base0E: '#ae81ff',
base0F: '#cc6633'
}}
valueRenderer={(valueAsString, value, keyPath) => {
if (keyPath === "src") {
return <SyntaxHighlighter
language="python"
style={{
...dark,
hljs: {
...dark.hljs,
maxHeight: `9rem`,
background: '#343434',
padding: 2,
}
}}
>
{value as string}
</SyntaxHighlighter>
}
return <span className="text-white">{value as string}</span>
}}
/>
: <span className="text-white">{value}</span>
}
</div>
))
}
</main>
<footer className="bg-[#191919] flex items-center justify-between p-4">
<button
className="flex items-center gap-2 p-2"
title="Copy src to clipboard"
onClick={() => navigator.clipboard.writeText(obj.src || "")}
>
<Copy color="white" />
Copy
</button>
<a
className="flex items-center gap-2 p-2"
href={url}
target="_blank"
title="Go to repo"
onClick={() => {
const newTab = window.open(url, '_blank');
{
"category" in obj &&
<>
<button
className="flex items-center gap-2 p-2"
title="Copy src to clipboard"
onClick={() => navigator.clipboard.writeText(obj.src || "")}
>
<Copy color="white" />
Copy
</button>
<a
className="flex items-center gap-2 p-2"
href={url}
target="_blank"
title="Go to repo"
onClick={() => {
const newTab = window.open(url, '_blank');

if (!obj.src_start || !obj.src_end || !newTab) return
if (!obj.src_start || !obj.src_end || !newTab) return

newTab.scroll({
top: obj.src_start,
behavior: 'smooth'
})
}}
>
<SquareArrowOutUpRight color="white" />
Go to repo
</a>
newTab.scroll({
top: obj.src_start,
behavior: 'smooth'
})
}}
>
<SquareArrowOutUpRight color="white" />
Go to repo
</a>
</>
}
</footer>
</div>
)
Expand Down
Loading

0 comments on commit 7b75a2c

Please sign in to comment.