Skip to content

Commit

Permalink
new design
Browse files Browse the repository at this point in the history
  • Loading branch information
florianbgt committed Oct 24, 2024
1 parent 3a6655b commit a0bd943
Show file tree
Hide file tree
Showing 13 changed files with 386 additions and 167 deletions.
224 changes: 189 additions & 35 deletions packages/app/src/components/ApiTree/ApiTree.tsx

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions packages/app/src/components/ApiTree/Edge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BaseEdge, getSmoothStepPath, type EdgeProps } from "@xyflow/react";

export default function CustomEdge(props: EdgeProps) {
const [edgePath] = getSmoothStepPath({ ...props, borderRadius: 100 });

return (
<>
<BaseEdge path={edgePath} />
</>
);
}
65 changes: 65 additions & 0 deletions packages/app/src/components/ApiTree/EndpointNode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { Handle, Node, NodeProps, Position } from "@xyflow/react";
import { Endpoint } from "../../service/api/types";
import { DataList } from "@radix-ui/themes";
import EndpointNodeContentDialog from "./EndpointNodeContentDialog";
import MethodBadge from "../MethodBadge";
import GroupBadge from "../GroupBadge";

export default function EndpointNode(
props: NodeProps<
Node<{
busy: boolean;
endpoint: Endpoint;
onChangeGroup: (group: string) => void;
groupColor?: string;
}>
>,
) {
return (
<>
<div className="backdrop-blur-sm bg-[#FFFFFF1A] rounded-xl border border-border-dark overflow-hidden">
<Handle
type="target"
position={Position.Top}
className="border border-gray-dark"
/>
<div
className="h-[5px]"
style={{ backgroundColor: props.data.groupColor }}
/>
<div className="bg-background-dark px-5 py-1 flex justify-between items-center">
<div>Action</div>
<EndpointNodeContentDialog
busy={props.data.busy}
endpoint={props.data.endpoint}
onChangeGroup={props.data.onChangeGroup}
/>
</div>
<div className="px-5 py-3">
<DataList.Root>
<DataList.Item>
<DataList.Label className="text-white">Method</DataList.Label>
<DataList.Value>
<MethodBadge method={props.data.endpoint.method} />
</DataList.Value>
</DataList.Item>
<DataList.Item>
<DataList.Label className="text-white">Path</DataList.Label>
<DataList.Value>
<div className="text-white">{props.data.endpoint.path}</div>
</DataList.Value>
</DataList.Item>
{props.data.endpoint.group && (
<DataList.Item>
<DataList.Label className="text-white">Group</DataList.Label>
<DataList.Value>
<GroupBadge name={props.data.endpoint.group} />
</DataList.Value>
</DataList.Item>
)}
</DataList.Root>
</div>
</div>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FormEvent, useEffect, useState } from "react";
import { Endpoint } from "../../service/api/types";
import MethodBadge from "../MethodBadge";

export default function MethodNodeContentDialog(props: {
export default function EndpointNodeContentDialog(props: {
busy: boolean;
endpoint: Endpoint;
onChangeGroup: (group: string) => void;
Expand All @@ -22,8 +22,20 @@ export default function MethodNodeContentDialog(props: {
return (
<Dialog.Root>
<Dialog.Trigger>
<Button color="purple" size="1" disabled={props.busy}>
Show more
<Button variant="ghost" size="1" highContrast disabled={props.busy}>
<svg
width="15"
height="15"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className="text-text-dark"
>
<path
d="M3.625 7.5C3.625 8.12132 3.12132 8.625 2.5 8.625C1.87868 8.625 1.375 8.12132 1.375 7.5C1.375 6.87868 1.87868 6.375 2.5 6.375C3.12132 6.375 3.625 6.87868 3.625 7.5ZM8.625 7.5C8.625 8.12132 8.12132 8.625 7.5 8.625C6.87868 8.625 6.375 8.12132 6.375 7.5C6.375 6.87868 6.87868 6.375 7.5 6.375C8.12132 6.375 8.625 6.87868 8.625 7.5ZM12.5 8.625C13.1213 8.625 13.625 8.12132 13.625 7.5C13.625 6.87868 13.1213 6.375 12.5 6.375C11.8787 6.375 11.375 6.87868 11.375 7.5C11.375 8.12132 11.8787 8.625 12.5 8.625Z"
fill="currentColor"
/>
</svg>
</Button>
</Dialog.Trigger>
<Dialog.Content>
Expand Down
21 changes: 21 additions & 0 deletions packages/app/src/components/ApiTree/GroupNode.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Handle, Node, NodeProps, Position } from "@xyflow/react";

export default function GroupNode(props: NodeProps<Node<{ path: string }>>) {
return (
<>
<div className="backdrop-blur-sm bg-[#FFFFFF1A] rounded-xl border border-border-dark">
<Handle
type="target"
position={Position.Top}
className="border border-gray-dark"
/>
<div className="text-center font-bold p-5">/{props.data.path}</div>
<Handle
type="source"
position={Position.Bottom}
className="border border-gray-dark"
/>
</div>
</>
);
}
7 changes: 0 additions & 7 deletions packages/app/src/components/ApiTree/GroupNodeContent.tsx

This file was deleted.

46 changes: 0 additions & 46 deletions packages/app/src/components/ApiTree/MethodNodeContent.tsx

This file was deleted.

6 changes: 2 additions & 4 deletions packages/app/src/components/GroupBadge.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { Badge } from "@radix-ui/themes";

export default function GroupBadge(props: { name: string }) {
return (
<Badge color="gray" variant="solid" radius="none" size="1">
<div className="px-2 py-1 bg-[#FFFFFF1A] rounded-lg text-text-dark border border-primary-dark">
{props.name}
</Badge>
</div>
);
}
1 change: 1 addition & 0 deletions packages/app/src/index.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* DO NOT USE @tai/lwind base */
@tailwind base;
@tailwind components;
@tailwind utilities;
Expand Down
27 changes: 18 additions & 9 deletions packages/app/src/layout/default.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import { Button } from "@radix-ui/themes";

export default function DefaultLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<div className="flex flex-col min-h-screen">
<div className="px-5 bg-[#6C5CE7] flex items-center justify-between drop-shadow-lg">
<div className="flex flex-col min-h-screen bg-background-dark text-text-dark">
<div className="px-5 flex items-center gap-5">
<a
className="flex items-center gap-1"
className="flex items-center gap-1 text-gray-dark no-underline "
href="https://nanoapi.io"
target="_blank"
>
<img src="/logo.png" alt="logo" className="w-20 h-20" />
<span className="text-3xl text-white">NanoAPI</span>
<span className="text-3xl">NanoAPI</span>
</a>
<a href="https://nanoapi.io/docs" target="_blank">
<Button color="plum">Documentation</Button>
<a
href="https://nanoapi.io/docs"
target="_blank"
className="text-gray-dark no-underline hover:underline"
>
Documentation
</a>
<a
href="https://nanoapi.io/docs/faqs"
target="_blank"
className="text-gray-dark no-underline hover:underline"
>
Help
</a>
</div>
<div className="flex-grow bg-[#F5F5F5] px-5 py-3">{children}</div>
<div className="flex-grow px-5">{children}</div>
</div>
);
}
58 changes: 8 additions & 50 deletions packages/app/src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, DataList, Skeleton } from "@radix-ui/themes";
import { Skeleton } from "@radix-ui/themes";
import { useEffect, useRef, useState } from "react";
import { toast } from "react-toastify";
import ApiTree from "../components/ApiTree/ApiTree";
Expand Down Expand Up @@ -116,55 +116,10 @@ export default function App() {

return (
<div className="flex flex-col">
<div className="mb-2 flex justify-between items-center gap-2">
<div className="flex gap-2">
{localEndpoints.length > 0 && (
<>
{isOutOfSynced && (
<Button color="yellow" disabled={busy} onClick={handleSync}>
<svg
width="20"
height="20"
viewBox="0 0 15 15"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M1.90321 7.29677C1.90321 10.341 4.11041 12.4147 6.58893 12.8439C6.87255 12.893 7.06266 13.1627 7.01355 13.4464C6.96444 13.73 6.69471 13.9201 6.41109 13.871C3.49942 13.3668 0.86084 10.9127 0.86084 7.29677C0.860839 5.76009 1.55996 4.55245 2.37639 3.63377C2.96124 2.97568 3.63034 2.44135 4.16846 2.03202L2.53205 2.03202C2.25591 2.03202 2.03205 1.80816 2.03205 1.53202C2.03205 1.25588 2.25591 1.03202 2.53205 1.03202L5.53205 1.03202C5.80819 1.03202 6.03205 1.25588 6.03205 1.53202L6.03205 4.53202C6.03205 4.80816 5.80819 5.03202 5.53205 5.03202C5.25591 5.03202 5.03205 4.80816 5.03205 4.53202L5.03205 2.68645L5.03054 2.68759L5.03045 2.68766L5.03044 2.68767L5.03043 2.68767C4.45896 3.11868 3.76059 3.64538 3.15554 4.3262C2.44102 5.13021 1.90321 6.10154 1.90321 7.29677ZM13.0109 7.70321C13.0109 4.69115 10.8505 2.6296 8.40384 2.17029C8.12093 2.11718 7.93465 1.84479 7.98776 1.56188C8.04087 1.27898 8.31326 1.0927 8.59616 1.14581C11.4704 1.68541 14.0532 4.12605 14.0532 7.70321C14.0532 9.23988 13.3541 10.4475 12.5377 11.3662C11.9528 12.0243 11.2837 12.5586 10.7456 12.968L12.3821 12.968C12.6582 12.968 12.8821 13.1918 12.8821 13.468C12.8821 13.7441 12.6582 13.968 12.3821 13.968L9.38205 13.968C9.10591 13.968 8.88205 13.7441 8.88205 13.468L8.88205 10.468C8.88205 10.1918 9.10591 9.96796 9.38205 9.96796C9.65819 9.96796 9.88205 10.1918 9.88205 10.468L9.88205 12.3135L9.88362 12.3123C10.4551 11.8813 11.1535 11.3546 11.7585 10.6738C12.4731 9.86976 13.0109 8.89844 13.0109 7.70321Z"
fill="currentColor"
fillRule="evenodd"
clipRule="evenodd"
></path>
</svg>
Sync changes
</Button>
)}
{!isOutOfSynced && (
<Button color="plum" disabled={busy} onClick={handleSplit}>
Generate Split
</Button>
)}
</>
)}
</div>
{(entrypoint || outputDir) && (
<DataList.Root>
{entrypoint && (
<DataList.Item>
<DataList.Label>Entrypoint:</DataList.Label>
<DataList.Value>{entrypoint}</DataList.Value>
</DataList.Item>
)}
{outputDir && (
<DataList.Item>
<DataList.Label>Output directory:</DataList.Label>
<DataList.Value>{outputDir}</DataList.Value>
</DataList.Item>
)}
</DataList.Root>
)}
</div>
<div style={{ height: "calc(100vh - 170px)", width: "100hh" }}>
<div
className="bg-secondaryBackground-dark rounded-3xl overflow-hidden"
style={{ height: "calc(100vh - 100px)", width: "100hh" }}
>
{chartLoading ? (
<div className="h-full flex flex-col justify-center items-center gap-5">
<Skeleton width="200px" height="75px" />
Expand All @@ -183,7 +138,10 @@ export default function App() {
<ApiTree
busy={busy}
endpoints={localEndpoints}
isOutOfSynced={isOutOfSynced}
onChangeEndpointGroup={handleChangeEndpointGroup}
onSync={handleSync}
onSplit={handleSplit}
/>
) : (
<div />
Expand Down
31 changes: 18 additions & 13 deletions packages/app/src/service/dagree.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Node, Edge, Position } from "@xyflow/react";
import dagre from "@dagrejs/dagre";

export function layoutNodesAndEdges(
nodes: Node[],
edges: Edge[],
options: {
nodeWidth: number;
nodeHeight: number;
} = { nodeWidth: 300, nodeHeight: 100 },
) {
function getNodeHeight(node: Node) {
if (node.type === "groupNode") {
return 100;
}
if (node.type === "endpointNode") {
return 150;
}
return 100;
}

export function layoutNodesAndEdges(nodes: Node[], edges: Edge[]) {
const nodeWidth = 300;

const direction = "TB";

const dagreGraph = new dagre.graphlib.Graph().setDefaultEdgeLabel(() => ({}));
Expand All @@ -19,8 +24,8 @@ export function layoutNodesAndEdges(

nodes.forEach((node) => {
dagreGraph.setNode(node.id, {
width: options.nodeWidth,
height: options.nodeHeight,
width: nodeWidth,
height: getNodeHeight(node),
});
});

Expand All @@ -40,10 +45,10 @@ export function layoutNodesAndEdges(
: ("bottom" as Position),
// We are shifting the dagre node position (anchor=center center) to the top left
// so it matches the React Flow node anchor point (top left).
width: options.nodeWidth,
width: nodeWidth,
position: {
x: nodeWithPosition.x - options.nodeWidth / 2,
y: nodeWithPosition.y - options.nodeHeight / 2,
x: nodeWithPosition.x - nodeWidth / 2,
y: nodeWithPosition.y - getNodeHeight(node) / 2,
},
};

Expand Down
Loading

0 comments on commit a0bd943

Please sign in to comment.