From 7d92be811ac7e498d624b2a0f7f829d0956c80a9 Mon Sep 17 00:00:00 2001 From: Desmarchelier Maxime <maxime.desmarchelier@ensiie.fr> Date: Sun, 20 Nov 2022 17:31:08 +0100 Subject: [PATCH] Add link between front-end and API --- sg-backend/db.py | 10 +- sg-frontend/index.html | 2 +- .../src/components/RelationInsert.svelte | 26 +++- .../src/components/SoftwareInsert.svelte | 123 +++++++++++------- 4 files changed, 108 insertions(+), 53 deletions(-) diff --git a/sg-backend/db.py b/sg-backend/db.py index 06dbcd1..911e7dd 100644 --- a/sg-backend/db.py +++ b/sg-backend/db.py @@ -54,12 +54,13 @@ class Neo4j: def get_relations(self): with self.driver.session() as session: - results = session.run("MATCH p = (a)-[r]->(b) RETURN a.name as source,b.name as target, r as relation_type") + results = session.run("MATCH p = (a:Software)-[r]->(b:Software) RETURN a.name as source,b.name as target, " + "r as relation_type") return results.data() def get_nodes(self): with self.driver.session() as session: - results = session.run("MATCH (a) return Id(a) as key, a.name as name") + results = session.run("MATCH (a:Software) return Id(a) as key, a.name as name") return results.data() def insert_software(self, insert_data): @@ -81,6 +82,11 @@ class Neo4j: if len(results.data()) != 2: return {"Error": "%s/%s NOT FOUND" % (insert_data.software1, insert_data.software2)} + results = session.run("match (n where n.name = '%s') match (m where m.name= '%s') return exists( (n)--(m) ) " % + (insert_data.software1, insert_data.software2)) + if results.data()[0]['exists( (n)--(m) )']: + return {"Error": "Relation already exist"} + results = session.run( "MATCH (a:Software), (b:Software) WHERE a.name = '%s' AND b.name = '%s' CREATE (a)-[r:%s]->(b) " "RETURN type(r)" % (insert_data.software1, insert_data.software2, insert_data.relationType)) diff --git a/sg-frontend/index.html b/sg-frontend/index.html index fb6e481..81e4661 100644 --- a/sg-frontend/index.html +++ b/sg-frontend/index.html @@ -12,7 +12,7 @@ <div class="topnav"> <a id="home" class="active" href="/">Home</a> <a id="sigma" href="#/sigma-custom">Software graph</a> - <a id="add" href="#/add-node">Software graph</a> + <a id="add" href="#/add-node">Software insert</a> </div> </div> <script type="module" src="/src/main.ts"></script> diff --git a/sg-frontend/src/components/RelationInsert.svelte b/sg-frontend/src/components/RelationInsert.svelte index 4c6fffc..78e5e6b 100644 --- a/sg-frontend/src/components/RelationInsert.svelte +++ b/sg-frontend/src/components/RelationInsert.svelte @@ -9,6 +9,26 @@ node; const BACKEND_URL = import.meta.env.VITE_BACKEND_URL; onMount(async () => { + + const relationAddButton = document.getElementById("relationAddButton"); + relationAddButton.addEventListener("click", async () => { + const response = await fetch(BACKEND_URL + "/relation-insert", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + software1: software1.label, + software2: software2.label, + relationType: document.querySelector('input[name="relationType"]:checked').value + }), + }); + if (response.ok) { + result = await response.json(); + node = result.node; + } + }); + await fetch(BACKEND_URL + "/software") .then((response) => response.json()) .then((data) => { @@ -33,14 +53,14 @@ <SoftwareSelect items="{softwares}" bind:selectedSoftware="{software1}"/> <div> <label class="radio-inline"> - <input type="radio" id="SIMILAR" name="relationType" checked>SIMILAR + <input type="radio" id="SIMILAR" name="relationType" value="SIMILAR" checked>SIMILAR </label> <label class="radio-inline"> - <input type="radio" id="HAS_SAME_CREATOR" name="relationType">HAS SAME CREATOR + <input type="radio" id="HAS_SAME_CREATOR" name="relationType" value="HAS_SAME_CREATOR">HAS SAME CREATOR </label> </div> <SoftwareSelect items="{softwares}" bind:selectedSoftware="{software2}"/> - <button type="submit">Add</button> + <button id="relationAddButton">Add</button> </form> <style> diff --git a/sg-frontend/src/components/SoftwareInsert.svelte b/sg-frontend/src/components/SoftwareInsert.svelte index 0c66016..429da71 100644 --- a/sg-frontend/src/components/SoftwareInsert.svelte +++ b/sg-frontend/src/components/SoftwareInsert.svelte @@ -1,58 +1,87 @@ <script> - import Select from "svelte-select"; + import {onMount} from "svelte"; + const BACKEND_URL = import.meta.env.VITE_BACKEND_URL; + + + let softwares = [], + result, + node; + + + onMount(async () => { + const softwareName = document.getElementById("softwareName"); + const newNodeButton = document.getElementById("newNodeButton"); + + newNodeButton.addEventListener("click", () => { + postSoftwareInsert(); + }); + + async function postSoftwareInsert() { + const res = await fetch(BACKEND_URL + "/software-insert", { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({"newNodeName": softwareName.value}), + }); + } + + }); </script> + <form class="form-inline"> - <label for="softwareName">Software Name :</label> - <input type="text" id="softwareName" placeholder="" name="softwareName"> - <button type="submit">Submit</button> + <label for="softwareName">Software Name :</label> + <input type="text" id="softwareName" placeholder="" name="softwareName"> + <button id="newNodeButton">Submit</button> </form> <style> /* Style the form - display items horizontally */ -.form-inline { - display: flex; - flex-flow: row wrap; - align-items: center; -} - -/* Add some margins for each label */ -.form-inline label { - margin: 5px 10px 5px 0; -} - -/* Style the input fields */ -.form-inline input { - vertical-align: middle; - margin: 5px 10px 5px 0; - padding: 10px; - background-color: #fff; - border: 1px solid #ddd; -} - -/* Add responsiveness - display the form controls vertically instead of horizontally on screens that are less than 800px wide */ -@media (max-width: 800px) { - .form-inline input { - margin: 10px 0; - } - - .form-inline { - flex-direction: column; - align-items: stretch; - } -} - form { - max-width: 400px; - background: #f4f4f4; - padding: 20px; - border-radius: 4px; - color: black; - margin: auto; - } - - label { - margin: 0 0 10px; - } + .form-inline { + display: flex; + flex-flow: row wrap; + align-items: center; + } + + /* Add some margins for each label */ + .form-inline label { + margin: 5px 10px 5px 0; + } + + /* Style the input fields */ + .form-inline input { + vertical-align: middle; + margin: 5px 10px 5px 0; + padding: 10px; + background-color: #fff; + border: 1px solid #ddd; + } + + /* Add responsiveness - display the form controls vertically instead of horizontally on screens that are less than 800px wide */ + @media (max-width: 800px) { + .form-inline input { + margin: 10px 0; + } + + .form-inline { + flex-direction: column; + align-items: stretch; + } + } + + form { + max-width: 400px; + background: #f4f4f4; + padding: 20px; + border-radius: 4px; + color: black; + margin: auto; + } + + label { + margin: 0 0 10px; + } </style> -- GitLab