about summary refs log tree commit diff
path: root/uploader
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2024-09-05 12:31:48 -0500
committerFrederick Muriuki Muriithi2024-09-05 14:19:55 -0500
commite13a694540ee65f401652d9ebdb5f845c15fb97e (patch)
tree93c74cfe70d082b37867ae60c79e9e4fdffa33c8 /uploader
parentb6a38df0eaedb9ac4bb4b602643ca1e97f889b49 (diff)
downloadgn-uploader-e13a694540ee65f401652d9ebdb5f845c15fb97e.tar.gz
Provide basic UI for editing the Species details.
Diffstat (limited to 'uploader')
-rw-r--r--uploader/species/models.py8
-rw-r--r--uploader/species/views.py69
-rw-r--r--uploader/templates/species/edit-species.html127
-rw-r--r--uploader/templates/species/list-species.html1
-rw-r--r--uploader/templates/species/view-species.html4
5 files changed, 199 insertions, 10 deletions
diff --git a/uploader/species/models.py b/uploader/species/models.py
index 53e7de0..cea3549 100644
--- a/uploader/species/models.py
+++ b/uploader/species/models.py
@@ -81,3 +81,11 @@ def save_species(conn: mdb.Connection,
             **species,
             "species_id": species_id
         }
+
+
+def species_families(conn: mdb.Connection) -> tuple:
+    """Retrieve the families under which species are grouped."""
+    with conn.cursor(cursorclass=DictCursor) as cursor:
+        cursor.execute(
+            "SELECT DISTINCT(Family) FROM Species WHERE Family IS NOT NULL")
+        return tuple(fam["Family"] for fam in cursor.fetchall())
diff --git a/uploader/species/views.py b/uploader/species/views.py
index 5de5277..d994e41 100644
--- a/uploader/species/views.py
+++ b/uploader/species/views.py
@@ -1,4 +1,5 @@
 """Endpoints handling species."""
+from pymonad.either import Left, Right, Either
 from flask import (flash,
                    request,
                    url_for,
@@ -9,9 +10,10 @@ from flask import (flash,
 from uploader.population import popbp
 from uploader.ui import make_template_renderer
 from uploader.db_utils import database_connection
+from uploader.oauth2.client import oauth2_get, oauth2_post
 from uploader.authorisation import require_login, require_token
 
-from .models import all_species, save_species, species_by_id
+from .models import all_species, save_species, species_by_id, species_families
 
 
 speciesbp = Blueprint("species", __name__)
@@ -100,11 +102,11 @@ def create_species():
         return redirect(url_for("species.view_species", species_id=species["species_id"]))
 
 
-@speciesbp.route("/<int:species_id>/edit")
+@speciesbp.route("/<int:species_id>/edit-extra", methods=["GET", "POST"])
 @require_login
 @require_token
 #def edit_species(species_id: int):
-def edit_species(token: dict, species_id: int):
+def edit_species_extra(token: dict, species_id: int):# pylint: disable=[unused-argument]
     """Edit a species' details.
 
     Parameters
@@ -112,9 +114,58 @@ def edit_species(token: dict, species_id: int):
     token: A JWT token used for authorisation.
     species_id: An identifier for the species being edited.
     """
-    app.logger.debug("======================\n"
-                     "Token: %s\n"
-                     "SpeciesId: %s\n"
-                     "======================",
-                     token, species_id)
-    return "Would edit the species."
+    def __failure__(res):
+        app.logger.debug(
+            "There was an error in the attempt to edit the species: %s", res)
+        flash(res, "alert-danger")
+        return redirect(url_for("species.view_species", species_id=species_id))
+
+    def __system_resource_uuid__(resources) -> Either:
+        sys_res = [
+            resource for resource in resources
+            if resource["resource_category"]["resource_category_key"] == "system"
+        ]
+        if len(sys_res) != 1:
+            return Left("Could not find/identify a valid system resource.")
+        return Right(sys_res[0]["resource_id"])
+
+    def __check_privileges__(authorisations):
+        if len(authorisations.items()) != 1:
+            return Left("Got authorisations for more than a single resource!")
+
+        auths = tuple(authorisations.items())[0][1]
+        authorised = "system:species:edit-extra-info" in tuple(
+            privilege["privilege_id"]
+            for role in auths["roles"]
+            for privilege in role["privileges"])
+        if authorised:
+            return Right(authorised)
+        return Left("You are not authorised to edit species extra details.")
+
+    with database_connection(app.config["SQL_URI"]) as conn:
+        species = species_by_id(conn, species_id)
+        families = species_families(conn)
+        if bool(species) and request.method == "GET":
+            return oauth2_get("auth/user/resources").then(
+                __system_resource_uuid__
+            ).then(
+                lambda resource_id: oauth2_post(
+                    "auth/resource/authorisation",
+                    json={"resource-ids": [resource_id]})
+            ).then(__check_privileges__).then(
+                lambda authorisations: render_template("species/edit-species.html",
+                                                  species=species,
+                                                  families=families,
+                                                  activelink="edit-species")
+            ).either(__failure__, lambda res: res)
+
+        if bool(species) and request.method == "POST":
+            flash("We would have edited the species, but the feature is not "
+                  "currently implemented …",
+                  "alert-danger")
+            return redirect(url_for("species.edit_species_extra",
+                                    species_id=species_id))
+
+        flash("Species with the given identifier was not found!",
+              "alert-danger")
+        return redirect(url_for("species.list_species"))
diff --git a/uploader/templates/species/edit-species.html b/uploader/templates/species/edit-species.html
new file mode 100644
index 0000000..c7c57fb
--- /dev/null
+++ b/uploader/templates/species/edit-species.html
@@ -0,0 +1,127 @@
+{%extends "species/base.html"%}
+{%from "flash_messages.html" import flash_all_messages%}
+
+{%block title%}Edit Species{%endblock%}
+
+{%block pagetitle%}Edit Species{%endblock%}
+
+{%block css%}
+<style type="text/css">
+  .card {
+      margin-top: 0.3em;
+      border-width: 1px;
+      border-style: solid;
+      border-radius: 0.3em;
+      border-color: #AAAAAA;
+      padding: 0.5em;
+  }
+</style>
+{%endblock%}
+
+{%block lvl2_breadcrumbs%}
+<li {%if activelink=="edit-species"%}
+    class="breadcrumb-item active"
+    {%else%}
+    class="breadcrumb-item"
+    {%endif%}>
+  <a href="{{url_for('species.edit_species_extra',
+           species_id=species.SpeciesId)}}">Edit</a>
+</li>
+{%endblock%}
+
+{%block contents%}
+{{flash_all_messages()}}
+<div class="row">
+  <form id="frm-edit-species"
+        method="POST"
+        action="{{url_for('species.edit_species_extra',
+                species_id=species.SpeciesId)}}">
+
+    <legend>Edit Extra Detail for Species '{{species.FullName}}'</legend>
+
+    <input type="hidden" name="species_id" value="{{species.SpeciesId}}" />
+
+    <div class="form-group">
+      <label for="lbl-species-taxonid" class="form-label">
+        Taxonomy Id
+      </label>
+      <label id="lbl-species-taxonid"
+             disabled="disabled"
+             class="form-control">{{species.TaxonomyId}}</label>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-species-name" class="form-label">
+        Common Name
+      </label>
+      <input type="text"
+             id="txt-species-name"
+             name="species_name"
+             required="required"
+             value="{{species.SpeciesName}}"
+             class="form-control" />
+    </div>
+
+    <div class="form-group">
+      <label for="txt-species-fullname" class="form-label">
+        Scientific Name
+      </label>
+      <input type="text"
+             id="txt-species-fullname"
+             name="species_fullname"
+             required="required"
+             value="{{species.FullName}}"
+             class="form-control" />
+    </div>
+
+    <div class="form-group">
+      <label for="select-species-family" class="form-label">
+        Family
+      </label>
+      <select id="select-species-family"
+              name="species_family"
+              class="form-control">
+        <option value="">Select the family</option>
+        {%for family in families%}
+        <option value="{{family}}"
+                {%if species.Family == family%}
+                selected="selected"
+                {%endif%}>{{family}}</option>
+        {%endfor%}
+      </select>
+    </div>
+
+    <div class="form-group">
+      <label for="txt-species-familyorderid" class="form-label">
+        Family Order Id
+      </label>
+      <input type="number"
+             id="txt-species-familyorderid"
+             name="species_familyorderid"
+             value="{{species.FamilyOrderId}}"
+             class="form-control" />
+    </div>
+
+    <div class="form-group">
+      <label for="txt-species-orderid" class="form-label">
+        Order Id
+      </label>
+      <input type="number"
+             id="txt-species-orderid"
+             name="species_orderid"
+             value="{{species.OrderId}}"
+             class="form-control" />
+    </div>
+
+    <div class="form-group">
+      <input type="submit" value="Submit Changes" class="btn btn-primary" />
+    </div>
+
+  </form>
+</div>
+{%endblock%}
+
+{%block sidebarcontents%}
+<p>&hellip; provide details on FamilyOrderId here &hellip;</p>
+<p>&hellip; provide details on OrderId here &hellip;</p>
+{%endblock%}
diff --git a/uploader/templates/species/list-species.html b/uploader/templates/species/list-species.html
index 42094c1..573bcee 100644
--- a/uploader/templates/species/list-species.html
+++ b/uploader/templates/species/list-species.html
@@ -6,6 +6,7 @@
 {%block pagetitle%}List Species{%endblock%}
 
 {%block contents%}
+{{flash_all_messages()}}
 <div class="row">
   <p>
     All data in GeneNetwork revolves around species. This is the core of the
diff --git a/uploader/templates/species/view-species.html b/uploader/templates/species/view-species.html
index 15b2969..bf5f0c1 100644
--- a/uploader/templates/species/view-species.html
+++ b/uploader/templates/species/view-species.html
@@ -29,6 +29,7 @@
 {%endblock%}
 
 {%block contents%}
+{{flash_all_messages()}}
 <div class="row">
   <h2>Details on species {{species.FullName}}</h2>
 
@@ -92,7 +93,8 @@
         <dd>{{species.OrderId}}</dd>
       </dl>
     </div>
-    <a href="{{url_for('species.edit_species', species_id=species.SpeciesId)}}"
+    <a href="{{url_for('species.edit_species_extra',
+             species_id=species.SpeciesId)}}"
        class="card-link"
        title="Edit the species' internal-use details.">Edit</a>
   </div>