diff --git a/app/api/graph/model.ts b/app/api/graph/model.ts index 6895150..3c47f41 100644 --- a/app/api/graph/model.ts +++ b/app/api/graph/model.ts @@ -313,17 +313,17 @@ export class Graph { return newElements } - public updateCategories(category: string, type: string) { - if (type === "node" && !this.elements.find(e => e.data.category === category)) { + public updateCategories(category: string, type: boolean) { + if (type && !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)) { + if (!type && !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) - } + } } } \ No newline at end of file diff --git a/app/graph/GraphView.tsx b/app/graph/GraphView.tsx index 026ee07..cf77555 100644 --- a/app/graph/GraphView.tsx +++ b/app/graph/GraphView.tsx @@ -424,18 +424,18 @@ const GraphView = forwardRef(({ graph, runQuery, historyQuery, setNodesCount, se if (!result.ok) return selectedElements.forEach((element) => { - const type = element.source ? "edge" : "node" + const type = !element.source const { id } = getElementId(element) graph.Elements.splice(graph.Elements.findIndex(e => e.data.id === id), 1) chartRef.current?.remove(`#${id} `) - if (type === "node") { + if (type) { setNodesCount(prev => prev - 1) } else { setEdgesCount(prev => prev - 1) } - graph.updateCategories(type === "node" ? element.category : element.label, type) + graph.updateCategories(type ? element.category : element.label, type) }) setSelectedElements([]) diff --git a/app/schema/SchemaCreateElement.tsx b/app/schema/SchemaCreateElement.tsx index fe6bdcb..91f7027 100644 --- a/app/schema/SchemaCreateElement.tsx +++ b/app/schema/SchemaCreateElement.tsx @@ -17,7 +17,7 @@ interface Props { onExpand: () => void selectedNodes: NodeDataDefinition[] setSelectedNodes: Dispatch> - type: "node" | "edge" + type: boolean } const emptyAttribute = (): Attribute => [undefined, "", false, false] @@ -26,10 +26,10 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, const [attributes, setAttributes] = useState<[string, Attribute][]>([]) const [attribute, setAttribute] = useState(emptyAttribute()) - const [newKey, setNewKey] = useState() - const [newValue, setNewValue] = useState() - const [label, setLabel] = useState() - const [newLabel, setNewLabel] = useState() + const [newKey, setNewKey] = useState("") + const [newValue, setNewValue] = useState("") + const [label, setLabel] = useState("") + const [newLabel, setNewLabel] = useState("") const [labelEditable, setLabelEditable] = useState(false) const [editable, setEditable] = useState("") const [hover, setHover] = useState("") @@ -57,7 +57,7 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, const handelSetAttribute = (e: React.KeyboardEvent) => { if (e.code === "Escape") { e.preventDefault() - setNewValue(undefined) + setNewValue("") setEditable("") return } @@ -77,19 +77,16 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, p[index][i] = newValue return p }) - setNewValue(undefined) + setNewValue("") } const handelOnCreate = async () => { - if (!label && type === "edge") { + if (!label && !type) { Toast("Please fill the label") return } const ok = await onCreate(attributes, label) - if (!ok) { - Toast("") - return - } + if (!ok) return setAttributes([]) setAttribute(emptyAttribute()) setLabel("") @@ -182,7 +179,7 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, ref={ref => ref?.focus()} className="w-28" variant="Small" - value={newKey === undefined ? key : newKey} + value={newKey === "" ? key : newKey} onChange={(e) => setNewKey(e.target.value)} onKeyDown={handelSetAttribute} onBlur={() => handelCancel()} @@ -226,7 +223,7 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, ref={ref => ref?.focus()} className="w-28" variant="Small" - value={newValue === undefined ? val[1] : newValue} + value={newValue === "" ? val[1] : newValue} onChange={(e) => setNewValue(e.target.value)} onKeyDown={handelSetAttribute} onBlur={() => setEditable("")} @@ -342,7 +339,7 @@ export default function SchemaCreateElement({ onCreate, onExpand, selectedNodes, { - type === "edge" && + !type &&
diff --git a/app/schema/SchemaDataPanel.tsx b/app/schema/SchemaDataPanel.tsx index a986511..a0723e7 100644 --- a/app/schema/SchemaDataPanel.tsx +++ b/app/schema/SchemaDataPanel.tsx @@ -1,7 +1,7 @@ 'use client' import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { cn, ElementDataDefinition, Toast } from "@/lib/utils"; import { ChevronRight, Trash2 } from "lucide-react"; import { Checkbox } from "@/components/ui/checkbox"; @@ -48,6 +48,11 @@ export default function SchemaCreateElement({ obj, onExpand, onDelete, onSetAttr const [label, setLabel] = useState(obj.source ? obj.label : obj.category) const [newLabel, setNewLabel] = useState() + useEffect(() => { + setAttributes(Object.entries(obj).filter(([k, v]) => !excludedProperties.has(k) && !(k === "name" && v === obj.id)).map(([k, v]) => [k, Array.isArray(v) ? v : v.split(",")] as [string, Attribute])) + setLabel(obj.source ? obj.label : obj.category) + }, [obj]) + const handelAddAttribute = async (e: React.KeyboardEvent) => { if (e.code === "Escape") { e.preventDefault() @@ -80,7 +85,7 @@ export default function SchemaCreateElement({ obj, onExpand, onDelete, onSetAttr setEditable("") return } - + if (e.key !== 'Enter') return e.preventDefault() @@ -92,16 +97,16 @@ export default function SchemaCreateElement({ obj, onExpand, onDelete, onSetAttr Toast("Please fill the field") return } - + const attr = attributes[Number(index)][1] - - const success = await onSetAttribute(isKey ? newKey as string : attributes[Number(index)][0] , [attr[0], isKey ? attr[1] : newVal as string, attr[2], attr[3]]) + + const success = await onSetAttribute(isKey ? newKey as string : attributes[Number(index)][0], [attr[0], isKey ? attr[1] : newVal as string, attr[2], attr[3]]) if (!success) return - + setAttributes(prev => { const p = [...prev] - + if (i === "key") { p[Number(index)][0] = newKey as string } @@ -114,7 +119,7 @@ export default function SchemaCreateElement({ obj, onExpand, onDelete, onSetAttr setNewKey("") setEditable("") } - + const handelLabelCancel = () => { setNewLabel(undefined) setLabelEditable(false) @@ -199,142 +204,142 @@ export default function SchemaCreateElement({ obj, onExpand, onDelete, onSetAttr { attributes.map(([key, val], index) => ( - setHover(`${index}`)} - onMouseLeave={() => setHover("")} - > - - { - hover === `${index}` && -
@@ -544,7 +544,7 @@ export default function SchemaView({ schema, setNodesCount, setEdgesCount }: Pro onExpand={onExpand} selectedNodes={selectedNodes} setSelectedNodes={setSelectedNodes} - type={isAddEntity ? "node" : "edge"} + type={isAddEntity} /> } diff --git a/e2e/LoginTest.spec.ts b/e2e/LoginTest.spec.ts new file mode 100644 index 0000000..6c05512 --- /dev/null +++ b/e2e/LoginTest.spec.ts @@ -0,0 +1,9 @@ +import { expect, test } from "@playwright/test"; + +test("Login Test", async ({ page }) => { + await page.goto("http://localhost:3000"); + await page.waitForURL("http://localhost:3000/login"); + await page.getByRole("button", { name: "Connect" }).click(); + await page.waitForURL("http://localhost:3000/graph"); + expect(page.url()).toBe("http://localhost:3000/graph"); +}) \ No newline at end of file diff --git a/e2e/createGraph.spec.ts b/e2e/createGraph.spec.ts deleted file mode 100644 index ae1ae86..0000000 --- a/e2e/createGraph.spec.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { test } from '@playwright/test'; - -test('create graph', async ({ page }) => { - await page.goto('http://localhost:3000/login'); - await page.getByRole('button', { name: 'Connect' }).click(); - await page.getByText('Select Graph...').click(); - await page.getByRole('button', { name: 'Create new Graph...' }).click(); - await page.getByPlaceholder('Graph name').fill('falkorDB'); - await page.getByRole('button', { name: 'Create' }).click(); - await page.getByPlaceholder('MATCH (n) OPTIONAL MATCH (n').fill('CREATE (:Rider {name:\'Valentino Rossi\'})-[:rides]->(:Team {name:\'Yamaha\'}), (:Rider {name:\'Dani Pedrosa\'})-[:rides]->(:Team {name:\'Honda\'}), (:Rider {name:\'Andrea Dovizioso\'})-[:rides]->(:Team {name:\'Ducati\'})'); - await page.getByRole('button').first().click(); - await page.getByText('falkorDB').first().click() -}) \ No newline at end of file diff --git a/e2e/graph.spec.ts b/e2e/graph.spec.ts deleted file mode 100644 index 1327633..0000000 --- a/e2e/graph.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { test } from '@playwright/test'; - -test.beforeEach(async ({ page }) => { - await page.goto('http://localhost:3000/login'); - await page.getByRole('button', { name: 'Connect' }).click(); - await page.getByText('Select Graph...').click(); - await page.getByRole('button', { name: 'Create new Graph...' }).click(); - await page.getByPlaceholder('Graph name').fill('falkorDB'); - await page.getByRole('button', { name: 'Create' }).click(); - await page.waitForTimeout(2000) - await page.getByPlaceholder('MATCH (n) OPTIONAL MATCH (n)').fill('CREATE (:Rider {name:\'Valentino Rossi\'})-[:rides]->(:Team {name:\'Yamaha\'}), (:Rider {name:\'Dani Pedrosa\'})-[:rides]->(:Team {name:\'Honda\'}), (:Rider {name:\'Andrea Dovizioso\'})-[:rides]->(:Team {name:\'Ducati\'})'); - await page.getByRole('button').first().click(); - await page.getByPlaceholder('MATCH (n) OPTIONAL MATCH (n)').click({ clickCount: 3 }); - await page.getByPlaceholder('MATCH (n) OPTIONAL MATCH (n)').fill(''); -}); - -test('delete graph', async ({ page }) => { - await page.getByRole('button').nth(1).click(); - await page.getByRole('button', { name: 'Delete graph' }).click(); - await page.getByRole('button', { name: 'Delete' }).click(); - await page.getByText('Select Graph...').click() -}); - -test('tabs navigation', async ({ page }) => { - await page.getByRole('button').first().click(); - await page.getByRole('tab', {name: 'Graph'}).click(); - await page.getByRole('tab', {name: 'Data'}).first().click(); - await page.getByRole('tab', {name: 'Metadata'}).click(); -}); \ No newline at end of file diff --git a/e2e/homePage.spec.ts b/e2e/homePage.spec.ts deleted file mode 100644 index 005ea48..0000000 --- a/e2e/homePage.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { expect, test } from '@playwright/test'; - -test.beforeEach(async ({ page }) => { - await page.goto('http://localhost:3000/'); -}); - -test('connect', async ({ page }) => { - await page.getByRole('button').click(); - await page.waitForURL('http://localhost:3000/login'); - expect(page.url()).toBe('http://localhost:3000/login'); -}); - -test('themes', async ({ page }) => { - await page.getByLabel('system mode').click(); - await page.getByLabel('dark mode').click(); - await page.getByLabel('light mode').click(); -}); \ No newline at end of file diff --git a/e2e/login.spec.ts b/e2e/login.spec.ts deleted file mode 100644 index 271f233..0000000 --- a/e2e/login.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { expect, test } from '@playwright/test'; - -test.beforeEach(async ({ page }) => { - await page.goto('http://localhost:3000/login'); -}); - -test('login', async ({ page }) => { - await page.getByRole('button', { name: 'Connect' }).click(); - await page.waitForURL("http://localhost:3000/graph"); - expect(page.url()).toBe("http://localhost:3000/graph"); -}); \ No newline at end of file