aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrederick Muriuki Muriithi2023-04-04 15:55:49 +0300
committerFrederick Muriuki Muriithi2023-04-04 15:56:28 +0300
commita2c4047b8ff395d1cef852b8e51fa9bba9be8bd0 (patch)
tree49e5d3857eb9f51bb6029b66ae7c5af080f3acc7
parentfa92004a8bcd0c4a514f75986f8101c9384c6acc (diff)
downloadgenenetwork2-a2c4047b8ff395d1cef852b8e51fa9bba9be8bd0.tar.gz
oauth2: Provide UI for linking genotype datasets.
-rw-r--r--wqflask/wqflask/oauth2/client.py5
-rw-r--r--wqflask/wqflask/oauth2/data.py68
-rw-r--r--wqflask/wqflask/templates/oauth2/data-list-genotype.html167
-rw-r--r--wqflask/wqflask/templates/oauth2/data-list-phenotype.html2
-rw-r--r--wqflask/wqflask/templates/oauth2/data-list.html2
5 files changed, 221 insertions, 23 deletions
diff --git a/wqflask/wqflask/oauth2/client.py b/wqflask/wqflask/oauth2/client.py
index 70cdfbe2..999bbfc8 100644
--- a/wqflask/wqflask/oauth2/client.py
+++ b/wqflask/wqflask/oauth2/client.py
@@ -15,14 +15,15 @@ def oauth2_client():
scope=SCOPE, token_endpoint_auth_method="client_secret_post",
token=session.get("oauth2_token"))
-def oauth2_get(uri_path: str) -> Either:
+def oauth2_get(uri_path: str, data: dict = {}) -> Either:
token = session.get("oauth2_token")
config = app.config
client = OAuth2Session(
config["OAUTH2_CLIENT_ID"], config["OAUTH2_CLIENT_SECRET"],
token=token, scope=SCOPE)
resp = client.get(
- urljoin(config["GN_SERVER_URL"], uri_path))
+ urljoin(config["GN_SERVER_URL"], uri_path),
+ data=data)
if resp.status_code == 200:
return Right(resp.json())
diff --git a/wqflask/wqflask/oauth2/data.py b/wqflask/wqflask/oauth2/data.py
index 963ab547..96acb2c2 100644
--- a/wqflask/wqflask/oauth2/data.py
+++ b/wqflask/wqflask/oauth2/data.py
@@ -18,6 +18,44 @@ def __render_template__(templatepath, **kwargs):
return render_template(
templatepath, **kwargs, user_privileges=user_privileges)
+def __search_mrna__(query, template, **kwargs):
+ return __render_template__(template, **kwargs)
+
+def __search_genotypes__(query, template, **kwargs):
+ species_name = kwargs["species_name"]
+ datasets = oauth2_get(
+ "oauth2/data/search",
+ data = {
+ "query": query,
+ "dataset_type": "genotype",
+ "species_name": species_name
+ }).either(
+ lambda err: {"datasets_error": process_error(err)},
+ lambda datasets: {"datasets": tuple({
+ "index": idx, **dataset
+ } for idx,dataset in enumerate(datasets, start=1))})
+ return __render_template__(template, **datasets, **kwargs)
+
+def __search_phenotypes__(query, template, **kwargs):
+ per_page = int(request.args.get("per_page", 500))
+ species_name = kwargs["species_name"]
+ search_uri = (f"search/?type=phenotype&per_page={per_page}&query="
+ f"species:{species_name}") + (
+ f" AND ({query})" if bool(query) else "")
+ traits = oauth2_get(search_uri).either(
+ lambda err: {"traits_error": process_error(err)},
+ lambda trts: {"traits": tuple({
+ "index": idx, **trait
+ } for idx, trait in enumerate(trts, start=1))})
+
+ selected_traits = request.form.getlist("selected_traits")
+
+ return __render_template__(
+ template, **traits, per_page=per_page, query=query,
+ selected_traits=selected_traits,
+ search_endpoint=urljoin(app.config["GN_SERVER_URL"], "search/"),
+ **kwargs)
+
@data.route("/<string:species_name>/<string:dataset_type>/list",
methods=["GET", "POST"])
def list_data_by_species_and_dataset(
@@ -25,31 +63,23 @@ def list_data_by_species_and_dataset(
templates = {
"mrna": "oauth2/data-list-mrna.html",
"genotype": "oauth2/data-list-genotype.html",
- "phenotype": "oauth2/data-list-phenotype.html"}
+ "phenotype": "oauth2/data-list-phenotype.html"
+ }
+ search_fns = {
+ "mrna": __search_mrna__,
+ "genotype": __search_genotypes__,
+ "phenotype": __search_phenotypes__
+ }
roles = oauth2_get("oauth2/user/roles").either(
lambda err: {"roles_error": process_error(err)},
lambda roles: {"roles": roles})
- query = request.args.get("query", "")
- per_page = int(request.args.get("per_page", 500))
- search_uri = (f"search/?type={dataset_type}&per_page={per_page}&query="
- f"species:{species_name}") + (
- f" AND ({query})" if bool(query) else "")
- traits = oauth2_get(search_uri).either(
- lambda err: {"traits_error": process_error(err)},
- lambda trts: {"traits": tuple({
- "index": idx, **trait
- } for idx, trait in enumerate(trts, start=1))})
groups = oauth2_get("oauth2/group/list").either(
lambda err: {"groups_error": process_error(err)},
lambda grps: {"groups": grps})
-
- selected_traits = request.form.getlist("selected_traits")
-
- return __render_template__(
- templates[dataset_type], **roles, **traits, **groups,
- species_name=species_name, dataset_type=dataset_type, per_page=per_page,
- query=query, selected_traits=selected_traits,
- search_endpoint=urljoin(app.config["GN_SERVER_URL"], "search/"))
+ query = request.args.get("query", "")
+ return search_fns[dataset_type](
+ query, templates[dataset_type], **roles, **groups,
+ species_name=species_name, dataset_type=dataset_type)
@data.route("/list", methods=["GET", "POST"])
def list_data():
diff --git a/wqflask/wqflask/templates/oauth2/data-list-genotype.html b/wqflask/wqflask/templates/oauth2/data-list-genotype.html
new file mode 100644
index 00000000..6dbcbd38
--- /dev/null
+++ b/wqflask/wqflask/templates/oauth2/data-list-genotype.html
@@ -0,0 +1,167 @@
+{%extends "base.html"%}
+{%from "oauth2/profile_nav.html" import profile_nav%}
+{%from "oauth2/display_error.html" import display_error%}
+
+{%block title%}Link Data: Genotype{%endblock%}
+
+{%block css%}
+<link rel="stylesheet" type="text/css"
+ href="/css/DataTables/css/jquery.dataTables.css" />
+<link rel="stylesheet" type="text/css"
+ href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" />
+<link rel="stylesheet" type="text/css" href="/static/new/css/show_trait.css" />
+{%endblock%}
+
+{%block content%}
+<div class="container" style="min-width: 1250px;">
+ {{profile_nav("data", user_privileges)}}
+
+ {{flash_me()}}
+
+ <div class="row">
+ <noscript>This page needs javascript to work correctly</noscript>
+ </div>
+
+ <div class="row">
+ <form id="frm-link-genotypes">
+ <legend>Link Genotype Traits to Group</legend>
+
+ <div class="form-group">
+ <label for="select-group">Group</label>
+ <select id="select-group" name="group_id" required="required"
+ class="form-control">
+ <option value="">Select group</option>
+ {%for group in groups%}
+ <option value="{{group.group_id}}">{{group.group_name}}</option>
+ {%endfor%}
+ </select>
+ </div>
+
+ <table id="tbl-link-genotypes" class="table-hover table-striped cell-border">
+ <tbody>
+ <tr>
+ <td colspan="100%" align="center" style="text-align: center;">
+ <br/><b><font size="4">
+ <span class="glyphicon glyphicon-info-sign text-info"></span>
+ &nbsp;
+ There are no selected genotype datasets to link to the group.
+ </font></b><br />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ {%if groups | length > 0%}
+ <input type="submit" value="Link Selected" class="btn btn-primary" />
+ {%else%}
+ <input type="submit" value="No group to link to" class="btn btn-warning"
+ disabled="disabled" />
+ {%endif%}
+ </form>
+ </div>
+
+ <div class="row">
+ <span id="search-messages" class="alert-danger" style="display:none"></span>
+ <form id="frm-search-traits"
+ action="#"
+ method="POST">
+ <legend>Search: Genotype</legend>
+ <input type="hidden" value="{{species_name}}" name="species"
+ id="txt-species" />
+ <input type="hidden" value="{{dataset_type}}" name="dataset_type"
+ id="txt-dataset-type" />
+ <input type="hidden" value="{{per_page}}" name="per_page"
+ id="txt-per-page" />
+
+ <div class="form-group">
+ <label for="txt-query">Dataset Search String</label>
+ <input type="text" id="txt-query" name="query" class="form-control"
+ value="{{query}}"/>
+ </div>
+ </form>
+ </div>
+
+ <div class="row">
+ <table id="tbl-genotypes" class="table-hover table-striped cell-border">
+ <tbody>
+ <tr>
+ <td colspan="100%" align="center">
+ <br><b><font size="15">Loading...</font></b><br>
+ </td>
+ </tr>
+ </table>
+ </div>
+
+
+</div>
+{%endblock%}
+
+{%block js%}
+<script language="javascript" type="text/javascript"
+ src="/js/DataTables/js/jquery.dataTables.min.js"></script>
+
+<script language="javascript" type="text/javascript"
+ src="/js/DataTablesExtensions/plugins/sorting/natural.js"></script>
+
+<script language="javascript" type="text/javascript"
+ src="/js/DataTablesExtensions/colReorder/js/dataTables.colReorder.js">
+</script>
+
+<script language="javascript" type="text/javascript"
+ src="/js/DataTablesExtensions/colResize/dataTables.colResize.js">
+</script>
+
+<script language="javascript" type="text/javascript"
+ src="/static/new/javascript/create_datatable.js"></script>
+
+<script language="javascript" type="text/javascript">
+ var common_column_definitions = [
+ {"title": "Index", "data": "index"},
+ {"title": "Group", "data": "InbredSetName"},
+ {"title": "Dataset", "data": "dataset_name"},
+ {"title": "Dataset FullName", "data": "dataset_fullname"},
+ {"title": "Dataset ShortName", "data": "dataset_shortname"}
+ ];
+
+ var search_column_definitions = [{"data": null, "render": function(data) {
+ return (
+ '<input type="checkbox" name="geno_datasets" ' +
+ 'class="checkbox" value="' +
+ JSON.stringify(data) + '" />');
+ }},].concat(common_column_definitions);
+
+ var selected_column_definitions = [{"data": null, "render": function(data) {
+ return (
+ '<input type="checkbox" name="selected_datasets" ' +
+ 'class="checkbox" value="' +
+ data.name + ':' + data.dataset +
+ '" />');
+ }},].concat(common_column_definitions);
+
+ var table_settings = {
+ "scrollY": "40vh",
+ "language": {
+ "emptyTable": "No datasets to display!",
+ "info": "Showing _START_ to _END_ of _TOTAL_ entries",
+ "infoEmpty": "No entries to show",
+ "loadingRecords": "Loading entries ..."
+ }
+ }
+
+ $(document).ready(function() {
+ $("#frm-search-traits").submit(function(event) {
+ event.preventDefault();
+ return false;
+ });
+ /* $("#txt-query").keyup(debounced_search()); */
+ create_table(tableId="tbl-genotypes",
+ tableData={{datasets | list | tojson}},
+ columnDefs=search_column_definitions,
+ customSettings=table_settings);
+ create_table(tableId="tbl-link-genotypes",
+ tableData={{selected_datasets | list | tojson}},
+ columnDefs=selected_column_definitions,
+ customSettings=table_settings);
+ });
+</script>
+{%endblock%}
diff --git a/wqflask/wqflask/templates/oauth2/data-list-phenotype.html b/wqflask/wqflask/templates/oauth2/data-list-phenotype.html
index 0e94bcfa..53c6ce8c 100644
--- a/wqflask/wqflask/templates/oauth2/data-list-phenotype.html
+++ b/wqflask/wqflask/templates/oauth2/data-list-phenotype.html
@@ -2,7 +2,7 @@
{%from "oauth2/profile_nav.html" import profile_nav%}
{%from "oauth2/display_error.html" import display_error%}
-{%block title%}View User{%endblock%}
+{%block title%}Link Data: Phenotype{%endblock%}
{%block css%}
<link rel="stylesheet" type="text/css"
diff --git a/wqflask/wqflask/templates/oauth2/data-list.html b/wqflask/wqflask/templates/oauth2/data-list.html
index b7c526c6..8a8f6694 100644
--- a/wqflask/wqflask/templates/oauth2/data-list.html
+++ b/wqflask/wqflask/templates/oauth2/data-list.html
@@ -1,7 +1,7 @@
{%extends "base.html"%}
{%from "oauth2/profile_nav.html" import profile_nav%}
{%from "oauth2/display_error.html" import display_error%}
-{%block title%}View User{%endblock%}
+{%block title%}Link Data{%endblock%}
{%block content%}
<div class="container" style="min-width: 1250px;">
{{profile_nav("data", user_privileges)}}