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