diff --git a/sg-backend/db.py b/sg-backend/db.py index 1e5f3a04335faf0a3fd14dc06d94ac7fe92cc89e..06dbcd13c3ebcfa5fba7acb3c6533a020b3beee7 100644 --- a/sg-backend/db.py +++ b/sg-backend/db.py @@ -64,20 +64,24 @@ class Neo4j: def insert_software(self, insert_data): with self.driver.session() as session: - # On check si la node avec laquelle on se relie existe - results = session.run("match (a:Software) where ID(a) = %d return a" % int(insert_data.nodeId)) - if not results.data(): - return {"Error": "%d ID not found" % int(insert_data.nodeId)} - # On check si le logiciel n'existe pas déjà results = session.run("match (a:Software) where a.name = '%s' return a" % insert_data.newNodeName) if results.data(): return {"Error": "%s already exist" % insert_data.newNodeName} session.run("CREATE (n:Software {name: '%s'})" % insert_data.newNodeName) + return results.data() - results = session.run( - "MATCH (a:Software), (b:Software) WHERE a.name = '%s' AND ID(b) = %d CREATE (a)-[r:%s]->(b) " - "RETURN type(r)" % (insert_data.newNodeName, int(insert_data.nodeId), insert_data.relationType)) + def relation_insert(self, insert_data): + with self.driver.session() as session: + # On check si la node avec laquelle on se relie existe + results = session.run("match (a:Software) where (a.name = '%s' OR a.name = '%s') return a" + % (insert_data.software1, insert_data.software2)) + if len(results.data()) != 2: + return {"Error": "%s/%s NOT FOUND" % (insert_data.software1, insert_data.software2)} + + 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)) return results.data() diff --git a/sg-backend/main.py b/sg-backend/main.py index 54561d521db37dc07a43062e8dfe2aac9188cd34..8b40e1920f2e7e92dd4228f55bc2b579c4b8e10d 100644 --- a/sg-backend/main.py +++ b/sg-backend/main.py @@ -16,8 +16,12 @@ class SoftwareSearch(BaseModel): class SoftwareInsert(BaseModel): newNodeName: str + + +class RelationInsert(BaseModel): + software1: str + software2: str relationType: str - nodeId: str driver = Neo4j(os.environ.get("NEO4J_URI"), os.environ.get("NEO4J_USER"), os.environ.get("NEO4J_PASSWORD")) @@ -103,3 +107,9 @@ async def software_search(search: SoftwareSearch): async def software_insert(insert_data: SoftwareInsert): res = driver.insert_software(insert_data) return res + + +@app.post("/relation-insert") +async def software_insert(insert_data: RelationInsert): + res = driver.relation_insert(insert_data) + return res diff --git a/sg-frontend/src/components/RelationInsert.svelte b/sg-frontend/src/components/RelationInsert.svelte new file mode 100644 index 0000000000000000000000000000000000000000..4c6fffcebfb1afd19ceb512681181ccd3a7149ed --- /dev/null +++ b/sg-frontend/src/components/RelationInsert.svelte @@ -0,0 +1,96 @@ +<script> + import SoftwareSelect from "./SoftwareSelect.svelte"; + import {onMount} from "svelte"; + + let softwares = [], + software1, + software2, + result, + node; + const BACKEND_URL = import.meta.env.VITE_BACKEND_URL; + onMount(async () => { + await fetch(BACKEND_URL + "/software") + .then((response) => response.json()) + .then((data) => { + console.log(data); + let tempSoft = []; + data["softwares"].forEach((element) => { + node = Object.values(Object.values(element))[0]; + delete Object.assign(node, {["label"]: node["name"]})["name"]; + tempSoft.push(node); + }); + softwares = tempSoft; + console.log(softwares); + }) + .catch((error) => { + console.log(error); + return []; + }); + }); +</script> + +<form> + <SoftwareSelect items="{softwares}" bind:selectedSoftware="{software1}"/> + <div> + <label class="radio-inline"> + <input type="radio" id="SIMILAR" name="relationType" checked>SIMILAR + </label> + <label class="radio-inline"> + <input type="radio" id="HAS_SAME_CREATOR" name="relationType">HAS SAME CREATOR + </label> + </div> + <SoftwareSelect items="{softwares}" bind:selectedSoftware="{software2}"/> + <button type="submit">Add</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; + } + + p { + display: none !important; + } + + /* 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> diff --git a/sg-frontend/src/components/SoftwareInsert.svelte b/sg-frontend/src/components/SoftwareInsert.svelte new file mode 100644 index 0000000000000000000000000000000000000000..0c660165dfc8c364782db7c9fe76139125c0710b --- /dev/null +++ b/sg-frontend/src/components/SoftwareInsert.svelte @@ -0,0 +1,58 @@ +<script> + import Select from "svelte-select"; + +</script> + +<form class="form-inline"> + <label for="softwareName">Software Name :</label> + <input type="text" id="softwareName" placeholder="" name="softwareName"> + <button type="submit">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; + } +</style> diff --git a/sg-frontend/src/routes/AddNode.svelte b/sg-frontend/src/routes/AddNode.svelte index 6720a65385cd9c915e9c269604308f10d70ae694..649088b4007cd82495b384997cee1466ba7f2040 100644 --- a/sg-frontend/src/routes/AddNode.svelte +++ b/sg-frontend/src/routes/AddNode.svelte @@ -1,12 +1,14 @@ <script lang="ts"> import {onMount} from 'svelte'; + import SotfwareInsert from "../components/SoftwareInsert.svelte"; + import RelationInsert from "../components/RelationInsert.svelte"; onMount(() => { fetch("http://localhost:8000/add-node") .then(response => response.json()) .then(data => { - // Retrieve some useful DOM elements: + // Retrieve some useful DOM elements: const link = document.getElementById("sigma") as HTMLElement; const home = document.getElementById("home") as HTMLElement; const add = document.getElementById("add") as HTMLElement; @@ -17,5 +19,8 @@ }); </script> <div id="app-base"> -<h1>Add new node</h1> + <h1>Add new node</h1> + <SotfwareInsert></SotfwareInsert> + <h1>Add new relation</h1> + <RelationInsert></RelationInsert> </div> \ No newline at end of file