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

Fix #288 Add schema #289

Merged
merged 7 commits into from
Aug 6, 2024
Merged
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
6 changes: 5 additions & 1 deletion app/api/graph/[graph]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,13 @@ export async function GET(request: NextRequest, { params }: { params: { graph: s
}

const query = request.nextUrl.searchParams.get("query")
const create = request.nextUrl.searchParams.get("create")

if (!query) throw new Error("Missing parameter 'query'")

if (create === "false") {
const type = await client.connection.type(graphId)
if (type === "none") return NextResponse.json({}, { status: 200 })
}
const graph = client.selectGraph(graphId)
const result = await graph.query(query)

Expand Down
92 changes: 66 additions & 26 deletions app/api/graph/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ const COLORS_ORDER_NAME = [
]

const COLORS_ORDER_VALUE = [
"#F2EB47",
"#99E4E5",
"#EF8759",
"#89D86D",
"#7167F6",
"#ED70B1",
"#7167F6"
"#EF8759",
"#99E4E5",
"#F2EB47",
"#89D86D"
]

const NODE_RESERVED_KEYS = ["parent", "id", "position"]
Expand All @@ -53,13 +53,17 @@ function edgeSafeKey(key: string): string {
}

export function getCategoryColorValue(index = 0): string {
const colorIndex = index % COLORS_ORDER_VALUE.length
return COLORS_ORDER_VALUE[colorIndex]
return COLORS_ORDER_VALUE[index % COLORS_ORDER_VALUE.length]
}

export function getCategoryColorName(index = 0): string {
const colorIndex = index % COLORS_ORDER_NAME.length
return COLORS_ORDER_NAME[colorIndex]
return COLORS_ORDER_NAME[index % COLORS_ORDER_NAME.length]
}

export function getCategoryColorNameFromValue(colorValue: string): string {
const colorIndex = COLORS_ORDER_VALUE.findIndex((c) => c === colorValue)

return COLORS_ORDER_NAME[colorIndex % COLORS_ORDER_NAME.length]
}

export interface ExtractedData {
Expand Down Expand Up @@ -116,10 +120,34 @@ export class Graph {
return this.categories;
}

set Categories(categories: Category[]) {
this.categories = categories;
}

get CategoriesMap(): Map<string, Category> {
return this.categoriesMap;
}

get Labels(): Category[] {
return this.labels;
}

set Labels(labels: Category[]) {
this.labels = labels;
}

get LabelsMap(): Map<string, Category> {
return this.labelsMap;
}

get NodesMap(): Map<number, NodeDataDefinition> {
return this.nodesMap;
}

get EdgesMap(): Map<number, EdgeDataDefinition> {
return this.edgesMap;
}

get Elements(): ElementDefinition[] {
return this.elements;
}
Expand Down Expand Up @@ -150,7 +178,7 @@ export class Graph {
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public extendNode(cell: any, newElements: ElementDefinition[]) {
public extendNode(cell: any) {
// check if category already exists in categories
let category = this.categoriesMap.get(cell.labels[0])
if (!category) {
Expand All @@ -174,8 +202,10 @@ export class Graph {
});
this.nodesMap.set(cell.id, node)
this.elements.push({ data: node })
newElements.push({ data: node })
} else if (currentNode.category === "") {
return node
}

if (currentNode.category === "") {
// set values in a fake node
currentNode.id = cell.id.toString();
currentNode.name = cell.id.toString();
Expand All @@ -184,14 +214,13 @@ export class Graph {
Object.entries(cell.properties).forEach(([key, value]) => {
currentNode[nodeSafeKey(key)] = value as string;
});
newElements.push({ data: currentNode })
}

return newElements
return currentNode
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public extendEdge(cell: any, newElements: ElementDefinition[]) {
public extendEdge(cell: any) {

let label = this.labelsMap.get(cell.relationshipType)
if (!label) {
Expand All @@ -205,7 +234,7 @@ export class Graph {
const sourceId = cell.sourceId.toString();
const destinationId = cell.destinationId.toString()
const edge: EdgeDataDefinition = {
_id: cell.id,
id: `_${cell.id}`,
source: sourceId,
target: destinationId,
label: cell.relationshipType,
Expand All @@ -216,8 +245,6 @@ export class Graph {
});
this.edgesMap.set(cell.id, edge)
this.elements.push({ data: edge })
newElements.push({ data: edge })

// creates a fakeS node for the source and target
let source = this.nodesMap.get(cell.sourceId)
if (!source) {
Expand All @@ -229,7 +256,6 @@ export class Graph {
}
this.nodesMap.set(cell.sourceId, source)
this.elements.push({ data: source })
newElements.push({ data: source })
}

let destination = this.nodesMap.get(cell.destinationId)
Expand All @@ -242,16 +268,16 @@ export class Graph {
}
this.nodesMap.set(cell.destinationId, destination)
this.elements.push({ data: destination })
newElements.push({ data: destination })
}
return edge
}
return newElements
return currentEdge
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
public extend(results: any): ElementDefinition[] {

const newElements: ElementDefinition[] = []

if (results?.data?.length) {
if (results.data[0] instanceof Object) {
this.columns = Object.keys(results.data[0])
Expand All @@ -268,21 +294,35 @@ export class Graph {
if (cell.nodes) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cell.nodes.forEach((node: any) => {
this.extendNode(node, newElements)
newElements.push({ data: this.extendNode(node) })
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
cell.edges.forEach((edge: any) => {
this.extendEdge(edge, newElements)
newElements.push({ data: this.extendEdge(edge) })
})
} else if (cell.relationshipType) {
this.extendEdge(cell, newElements)
newElements.push({ data: this.extendEdge(cell) })
} else if (cell.labels) {
this.extendNode(cell, newElements)
newElements.push({ data: this.extendNode(cell) })
}
}
})
})

return newElements
}

public updateCategories(category: string, type: string) {
if (type === "node" && !this.elements.find(e => e.data.category === category)) {
const i = this.categories.findIndex(({ name }) => name === category)
this.categories.splice(i, 1)
this.categoriesMap.delete(category)
}

if (type === "edge" && !this.elements.find(e => e.data.label === category)) {
const i = this.labels.findIndex(({ name }) => name === category)
this.labels.splice(i, 1)
this.labelsMap.delete(category)
}
}
}
26 changes: 0 additions & 26 deletions app/api/schema/[schema]/route.ts

This file was deleted.

26 changes: 12 additions & 14 deletions app/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,27 @@ export default function Header({ inCreate = false, onSetGraphName }: Props) {
const pathname = usePathname()
const [userStatus, setUserStatus] = useState<Role>()
const [graphName, setGraphName] = useState<string>("")

// const createGraph = async () => {
// const result = await securedFetch(`api/graph/${newName}`)
// }
const type = pathname.includes("/schema") ? "Schema" : "Graph"

const handelCreateGraph = async (e: FormEvent) => {


if (!onSetGraphName) return

e.preventDefault()

const name = `${graphName}${type === "Schema" ? "_schema" : ""}`

const q = `RETURN 1`
const result = await securedFetch(`api/graph/${graphName}/?query=${prepareArg(q)}`, {
const result = await securedFetch(`api/graph/${name}/?query=${prepareArg(q)}`, {
method: "GET"
})

if (result.ok) {
Toast(`Graph ${graphName} created successfully!`, "Success")
Toast(`${type} ${graphName} created successfully!`, "Success")
onSetGraphName(graphName)
setCreateOpen(false)
setGraphName("")
}

}

return (
Expand All @@ -68,14 +66,14 @@ export default function Header({ inCreate = false, onSetGraphName }: Props) {
<div className="flex gap-6">
<Button
label="Graphs"
className={cn(pathname.includes("/graph") && "text-[#7167F6]")}
className={cn(type === "Graph" && "text-[#7167F6]")}
onClick={() => router.push("/graph")}
/>
{/* <Button
<Button
label="Schemas"
className={cn(pathname.includes("/schema") && "text-[#7167F6]")}
className={cn(type === "Schema" && "text-[#7167F6]")}
onClick={() => router.push("/schema")}
/> */}
/>
</div>
</div>
<div className="flex items-center gap-12">
Expand All @@ -86,11 +84,11 @@ export default function Header({ inCreate = false, onSetGraphName }: Props) {
<Button
className="text-white"
variant="Primary"
label="New Graph"
label={`New ${type}`}
icon={<PlusCircle />}
/>
</DialogTrigger>
<DialogComponent className="w-[40%]" title="Add Graph" description="Enter new graph name">
<DialogComponent className="w-[40%]" title={`Add ${type}`} description={`Enter new ${type} name`}>
<form className="flex flex-col gap-12" onSubmit={handelCreateGraph}>
<div className="flex flex-col gap-2">
<p>Name:</p>
Expand Down
10 changes: 7 additions & 3 deletions app/components/graph/DeleteGraph.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
import { Toast, securedFetch } from "@/lib/utils";

export default function DeleteGraph({ graphName, isOpen, onOpen, onDeleteGraph }: {
export default function DeleteGraph({ graphName, isOpen, onOpen, onDeleteGraph, isSchema }: {
graphName: string
isOpen: boolean
onOpen: (open: boolean) => void
onDeleteGraph: () => void
isSchema: boolean
}) {

const type = isSchema ? "Schema" : "Graph"

const deleteGraph = async () => {
const result = await securedFetch(`/api/graph/${graphName}`, {
const name = `${graphName}${isSchema ? "_schema" : ""}`
const result = await securedFetch(`/api/graph/${name}`, {
method: "DELETE",
});

if (result.ok) {
Toast(`Graph ${graphName} deleted`, "Success")
Toast(`${type} ${graphName} deleted`, "Success")
onDeleteGraph()
}
}
Expand Down
Loading
Loading