Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

all #3

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions app/api/auth/[...nextauth]/options.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { RedisClientType, createClient } from "falkordb";
import CredentialsProvider from "next-auth/providers/credentials"
import { AuthOptions } from "next-auth"


export const connections = new Map<number, RedisClientType>();
let userId = 1;

const authOptions : AuthOptions = {
providers: [
CredentialsProvider({
name: 'Credentials',
credentials: {
host: { label: "Host", type: "text", placeholder: "localhost" },
port: { label: "Port", type: "number", placeholder: "6379" },
username: { label: "Username", type: "text" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {

if (!credentials) {
return null
}

try {
let client = await createClient({
socket: {
host: credentials.host ?? "localhost",
port: credentials.port ? parseInt(credentials.port) : 6379,
reconnectStrategy: false
},
password: credentials.password ?? undefined,
username: credentials.username ?? undefined
})
.on('error', err => console.log('FalkorDB Client Error', err))
.connect();

const id = userId++;
connections.set(id, client as RedisClientType)

let res : any = {
id: id,
host: credentials.host,
port: credentials.port,
password: credentials.password,
username: credentials.username,
}
return res
} catch (err) {
console.log(err)
return null;
}
}

})
],
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id;
token.host = user.host;
token.port = user.port;
token.username = user.username;
token.password = user.password;
}

return token;
},
async session({ session, token, user }) {
if (session.user) {
session.user.id = token.id as number;
session.user.host = token.host as string;
session.user.port = parseInt(token.port as string);
session.user.username = token.username as string;
session.user.password = token.password as string;

}
return session;
}
}
}



export default authOptions
7 changes: 7 additions & 0 deletions app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import NextAuth from "next-auth"
import authOptions from "./options";


const handler = NextAuth(authOptions)

export { handler as GET, handler as POST }
35 changes: 35 additions & 0 deletions app/api/graph/[graph]/[node]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { NextRequest, NextResponse } from "next/server";
import { Graph } from 'falkordb';
import { getServerSession } from "next-auth/next";
import authOptions, { connections } from "../../../auth/[...nextauth]/options";

export async function GET(request: NextRequest, { params }: { params: { graph: string, node: string } }) {

const session = await getServerSession(authOptions)
const id = session?.user?.id
if (!id) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 })
}

let client = connections.get(id)
if (!client) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 })
}

const nodeId = parseInt(params.node);
const graphId = params.graph;

const graph = new Graph(client, graphId);

// Get node's neighbors
const query = `MATCH (src)-[e]-(n)
WHERE ID(src) = $nodeId
RETURN e, n`;

try {
let result: any = await graph.query(query, { params: { nodeId: nodeId } });
return NextResponse.json({ result: result }, { status: 200 })
} catch (err: any) {
return NextResponse.json({ message: err.message }, { status: 400 })
}
}
37 changes: 37 additions & 0 deletions app/api/graph/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { NextRequest, NextResponse } from "next/server";
import { Graph } from 'falkordb';
import { getServerSession } from "next-auth/next";
import authOptions, { connections } from "../auth/[...nextauth]/options";

export async function GET(request: NextRequest) {

const session = await getServerSession(authOptions)
const id = session?.user?.id
if(!id) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 })
}

let client = connections.get(id)
if(!client) {
return NextResponse.json({ message: "Not authenticated" }, { status: 401 })
}

const graphID = request.nextUrl.searchParams.get("graph");
try {
if (graphID) {
const query = request.nextUrl.searchParams.get("query");
if (!query) {
return NextResponse.json({ message: "Missing query parameter 'q'" }, { status: 400 })
}
const graph = new Graph(client, graphID);
let result = await graph.query(query)
return NextResponse.json({ result: result }, { status: 200 })
} else {

let result = await client.graph.list()
return NextResponse.json({ result: { graphs: result } }, { status: 200 })
}
} catch (err: any) {
return NextResponse.json({ message: err.message }, { status: 400 })
}
}
Binary file added app/favicon.ico
Binary file not shown.
76 changes: 76 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
33 changes: 33 additions & 0 deletions app/graph/labels.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { Category, getCategoryColorName } from "./model";
import { cn } from "@/lib/utils";
import { MinusCircle, Palette, PlusCircle } from "lucide-react";
import { useState } from "react";
import { Button } from "@/components/ui/button";

export function Labels(params: { categories: Category[], className?: string, onClick: (category: Category) => void }) {

// fake stae to force reload
const [reload, setReload] = useState(false)

return (
<div className={cn("flex flex-row gap-x-2", params.className)} >
{params.categories.map((category) => {
return (
<div className="flex flex-row gap-x-2 items-center" key={category.index}>
<Button
className={cn(`bg-${getCategoryColorName(category.index)}-500 ${category.show ? "" : "opacity-50"}`, "rounded-lg border border-gray-300 p-2 opac")}
onClick={() => {
params.onClick(category)
setReload(!reload)
}}
>
{category.show ? <MinusCircle /> : <PlusCircle />}
</Button>
<p>{category.name}</p>
</div>
)
})}
</div>
)
}
Loading
Loading