From 81cab5468f777dbb4ff6f90b4018e6ee0cd4a01f Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Mon, 10 Apr 2023 10:35:19 +0300 Subject: Do search. Filter out selected datasets. Enable search when user types in search box. Filter out any selected datasets. --- wqflask/wqflask/oauth2/client.py | 5 ++- wqflask/wqflask/oauth2/data.py | 47 +++++++++++++++++--- wqflask/wqflask/oauth2/request_utils.py | 5 ++- .../static/new/javascript/auth/search_genotypes.js | 50 +++++++++++++++++++++- .../templates/oauth2/data-list-genotype.html | 13 ++++-- 5 files changed, 103 insertions(+), 17 deletions(-) diff --git a/wqflask/wqflask/oauth2/client.py b/wqflask/wqflask/oauth2/client.py index 0cecd965..1d3e07ae 100644 --- a/wqflask/wqflask/oauth2/client.py +++ b/wqflask/wqflask/oauth2/client.py @@ -16,7 +16,7 @@ def oauth2_client(): scope=SCOPE, token_endpoint_auth_method="client_secret_post", token=session.get("oauth2_token")) -def oauth2_get(uri_path: str, data: dict = {}) -> Either: +def oauth2_get(uri_path: str, data: dict = {}, **kwargs) -> Either: token = session.get("oauth2_token") config = app.config client = OAuth2Session( @@ -24,7 +24,8 @@ def oauth2_get(uri_path: str, data: dict = {}) -> Either: token=token, scope=SCOPE) resp = client.get( urljoin(config["GN_SERVER_URL"], uri_path), - data=data) + data=data, + **kwargs) if resp.status_code == 200: return Right(resp.json()) diff --git a/wqflask/wqflask/oauth2/data.py b/wqflask/wqflask/oauth2/data.py index e1b33b56..03fde15f 100644 --- a/wqflask/wqflask/oauth2/data.py +++ b/wqflask/wqflask/oauth2/data.py @@ -3,8 +3,8 @@ import json from urllib.parse import urljoin from flask import ( - flash, request, url_for, redirect, Response, Blueprint, render_template, - current_app as app) + flash, request, jsonify, url_for, redirect, Response, Blueprint, + render_template, current_app as app) from .request_utils import process_error from .client import oauth2_get, oauth2_post @@ -22,18 +22,29 @@ def __render_template__(templatepath, **kwargs): def __search_mrna__(query, template, **kwargs): return __render_template__(template, **kwargs) +def __selected_datasets__(): + if bool(request.json): + return request.json.get( + "selected", + request.args.get("selected", + request.form.get("selected", []))) + return request.args.get("selected", + request.form.get("selected", [])) + def __search_genotypes__(query, template, **kwargs): species_name = kwargs["species_name"] + search_uri = urljoin(app.config["GN_SERVER_URL"], "oauth2/data/search") datasets = oauth2_get( "oauth2/data/search", - data = { + json = { "query": query, "dataset_type": "genotype", - "species_name": species_name + "species_name": species_name, + "selected": __selected_datasets__() }).either( lambda err: {"datasets_error": process_error(err)}, lambda datasets: {"datasets": datasets}) - return __render_template__(template, **datasets, **kwargs) + return __render_template__(template, search_uri=search_uri, **datasets, **kwargs) def __search_phenotypes__(query, template, **kwargs): per_page = int(request.args.get("per_page", 500)) @@ -55,6 +66,28 @@ def __search_phenotypes__(query, template, **kwargs): search_endpoint=urljoin(app.config["GN_SERVER_URL"], "search/"), **kwargs) +@data.route("/genotype/search", methods=["POST"]) +def json_search_genotypes() -> Response: + def __handle_error__(err): + error = process_error(err) + print(f"THE ERROR: {error}") + return jsonify(error), error["status_code"] + + print(f"===============================================") + print(request.json) + print(f"===============================================") + + return oauth2_get( + "oauth2/data/search", + json = { + "query": request.json["query"], + "dataset_type": "genotype", + "species_name": request.json["species_name"], + "selected": __selected_datasets__() + }).either( + __handle_error__, + lambda datasets: jsonify(datasets)) + @data.route("///list", methods=["GET", "POST"]) def list_data_by_species_and_dataset( @@ -177,6 +210,6 @@ def link_genotype_data(): return oauth2_post("oauth2/data/link/genotype", json={ "species_name": form.get("species_name"), "group_id": form.get("group_id"), - "selected_datasets": tuple(json.loads(dataset) for dataset - in form.getlist("selected_datasets")) + "selected": tuple(json.loads(dataset) for dataset + in form.getlist("selected")) }).either(lambda err: __link_error__(process_error(err)), __link_success__) diff --git a/wqflask/wqflask/oauth2/request_utils.py b/wqflask/wqflask/oauth2/request_utils.py index ed523614..eefae900 100644 --- a/wqflask/wqflask/oauth2/request_utils.py +++ b/wqflask/wqflask/oauth2/request_utils.py @@ -23,9 +23,10 @@ def process_error(error: Response, return { "error": "NotFoundError", "error_message": message, - "error_description": message + "error_description": message, + "status_code": error.status_code } - return error.json() + return {**error.json(), "status_code": error.status_code} def request_error(response): app.logger.error(f"{response}: {response.url} [{response.status_code}]") diff --git a/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js b/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js index 39999e76..8d821f44 100644 --- a/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js +++ b/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js @@ -15,7 +15,7 @@ function link_checkbox(dataset) { return __build_checkbox__( dataset, ''); + 'name="selected" checked="checked">'); } function search_checkbox(dataset) { @@ -179,6 +179,52 @@ function select_deselect_dataset(dataset, source, destination) { /***** END: Re-render tables *****/ } +function debounce(func, delay=500) { + var timeout; + return function search(event) { + clearTimeout(timeout); + timeout = setTimeout(func, delay); + }; +} + +function search_genotypes() { + query = document.getElementById("txt-query").value; + selected = JSON.parse(document.getElementById( + "tbl-link-genotypes").getAttribute("data-selected-datasets")); + species_name = document.getElementById("txt-species-name").value + search_endpoint = "/oauth2/data/genotype/search" + $.ajax( + search_endpoint, + { + "method": "POST", + "contentType": "application/json; charset=utf-8", + "dataType": "json", + "data": JSON.stringify({ + "query": query, + "selected": selected, + "dataset_type": "genotype", + "species_name": species_name}), + "error": function(jqXHR, textStatus, errorThrown) { + data = jqXHR.responseJSON + elt = document.getElementById("search-error").setAttribute( + "style", "display: block;"); + document.getElementById("search-error-text").innerHTML = ( + data.error + " (" + data.status_code + "): " + + data.error_description); + document.getElementById("tbl-genotypes").setAttribute( + "data-datasets", JSON.stringify([])); + render_table("#tbl-genotypes", "data-datasets", search_checkbox); + }, + "success": function(data, textStatus, jqXHR) { + document.getElementById("search-error").setAttribute( + "style", "display: none;"); + document.getElementById("tbl-genotypes").setAttribute( + "data-datasets", JSON.stringify(data)); + render_table("#tbl-genotypes", "data-datasets", search_checkbox); + } + }); +} + $(document).ready(function() { let search_table = new TableDataSource("#tbl-genotypes", "data-datasets"); let link_table = new TableDataSource( @@ -189,7 +235,7 @@ $(document).ready(function() { return false; }); - /* $("#txt-query").keyup(debounced_search()); */ + $("#txt-query").keyup(debounce(search_genotypes)); $("#tbl-genotypes").on("change", ".checkbox-search", function(event) { if(this.checked) { diff --git a/wqflask/wqflask/templates/oauth2/data-list-genotype.html b/wqflask/wqflask/templates/oauth2/data-list-genotype.html index 54479251..47c21079 100644 --- a/wqflask/wqflask/templates/oauth2/data-list-genotype.html +++ b/wqflask/wqflask/templates/oauth2/data-list-genotype.html @@ -58,7 +58,7 @@ {{dataset.dataset_name}} @@ -91,12 +91,12 @@
-
Search: Genotype + id="txt-species-name" />
+ -- cgit v1.2.3