From 8fc7fe1034a940c077edd06b5b287177023f6b61 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Wed, 19 Apr 2023 10:39:10 +0300 Subject: oauth2: UI: Enable selecting and deselecting items for linking This commit generalises the code for selecting and deselecting items making it usable even for the phenotype traits. Now we can switch items from the search table to the linking table and vice versa. --- .../wqflask/static/new/javascript/auth/search.js | 39 +++++++------ .../static/new/javascript/auth/search_genotypes.js | 37 ++++++------ .../static/new/javascript/auth/search_mrna.js | 39 ++++++------- .../new/javascript/auth/search_phenotypes.js | 39 ++++++++++--- .../templates/oauth2/data-list-phenotype.html | 66 +++++++++++++++++----- 5 files changed, 145 insertions(+), 75 deletions(-) diff --git a/wqflask/wqflask/static/new/javascript/auth/search.js b/wqflask/wqflask/static/new/javascript/auth/search.js index 4e79bfd4..d094cebf 100644 --- a/wqflask/wqflask/static/new/javascript/auth/search.js +++ b/wqflask/wqflask/static/new/javascript/auth/search.js @@ -63,7 +63,10 @@ function render_table(table_data_source) { table_id = table_data_source.table_id.selector; data_attr_name = table_data_source.data_attribute_name; $(table_id + " tbody tr").remove(); - table_data = JSON.parse($(table_id).attr(data_attr_name)); + table_data = JSON.parse($(table_id).attr(data_attr_name)).sort((d1, d2) => { + return (d1.dataset_name > d2.dataset_name ? 1 : ( + d1.dataset_name < d2.dataset_name ? -1 : 0)) + }); if(table_data.length < 1) { row = $("") cell = $(''); @@ -85,43 +88,43 @@ function render_table(table_data_source) { }); } -function remove_from_table_data(dataset, table_data_source) { +function in_array(items, filter_fn) { + return items.filter(filter_fn).length > 0; +} + +function remove_from_table_data(dataset, table_data_source, filter_fn) { let table_id = table_data_source.table_id.selector; let data_attr_name = table_data_source.data_attribute_name; without_dataset = JSON.parse($(table_id).attr(data_attr_name)).filter( - function(dst) { - return !(dst.SpeciesId == dataset.SpeciesId && - dst.InbredSetId == dataset.InbredSetId && - dst.GenoFreezeId == dataset.GenoFreezeId); - }); + filter_fn); $(table_id).attr(data_attr_name, JSON.stringify(without_dataset)); } -function add_to_table_data(dataset, table_data_source) { +function add_to_table_data(dataset, table_data_source, filter_fn) { let table_id = table_data_source.table_id.selector; let data_attr_name = table_data_source.data_attribute_name; table_data = JSON.parse($(table_id).attr(data_attr_name)); - if(!in_array(dataset, table_data)) { + if(!in_array(table_data, filter_fn)) { table_data.push(dataset); } $(table_id).attr(data_attr_name, JSON.stringify(Array.from(table_data))); } /** - * Switch the dataset from search table to selection table and vice versa - * @param {Object} A genotype dataset - * @param {TableDataSource} The table to switch the dataset from - * @param {TableDataSource} The table to switch the dataset to + * Switch the dataset/trait from search table to selection table and vice versa + * @param {Object} A dataset/trait object + * @param {TableDataSource} The source table for the dataset/trait + * @param {TableDataSource} The destination table for the dataset/trait */ -function select_deselect_dataset(dataset, source, destination) { +function select_deselect(item, source, destination, filter_fn, render_fn=render_table) { dest_selector = destination.table_id.selector dest_data = JSON.parse( $(dest_selector).attr(destination.data_attribute_name)); - add_to_table_data(dataset, destination); // Add to destination table - remove_from_table_data(dataset, source); // Remove from source table + add_to_table_data(item, destination, filter_fn); // Add to destination table + remove_from_table_data(item, source, (arg) => {return !filter_fn(arg)}); // Remove from source table /***** BEGIN: Re-render tables *****/ - render_table(destination); - render_table(source); + render_fn(destination); + render_fn(source); /***** END: Re-render tables *****/ } diff --git a/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js b/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js index 40f88121..8d571c53 100644 --- a/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js +++ b/wqflask/wqflask/static/new/javascript/auth/search_genotypes.js @@ -1,17 +1,3 @@ -/** - * Check whether `dataset` is in array of `datasets`. - * @param {GenotypeDataset} A genotype dataset. - * @param {Array} An array of genotype datasets. - */ -function in_array(dataset, datasets) { - found = datasets.filter(function(dst) { - return (dst.SpeciesId == dataset.SpeciesId && - dst.InbredSetId == dataset.InbredSetId && - dst.GenoFreezeId == dataset.GenoFreezeId); - }); - return found.length > 0; -} - function toggle_link_button() { num_groups = $("#frm-link-genotypes select option").length - 1; num_selected = JSON.parse( @@ -63,6 +49,19 @@ function search_genotypes() { }); } +/** + * Return function to check whether `dataset` is in array of `datasets`. + * @param {GenotypeDataset} A genotype dataset. + * @param {Array} An array of genotype datasets. + */ +function make_filter(trait) { + return (dst) => { + return (dst.SpeciesId == dataset.SpeciesId && + dst.InbredSetId == dataset.InbredSetId && + dst.GenoFreezeId == dataset.GenoFreezeId); + }; +} + $(document).ready(function() { let search_table = new TableDataSource( "#tbl-genotypes", "data-datasets", search_checkbox); @@ -78,16 +77,18 @@ $(document).ready(function() { $("#tbl-genotypes").on("change", ".checkbox-search", function(event) { if(this.checked) { - select_deselect_dataset( - JSON.parse(this.value), search_table, link_table); + dataset = JSON.parse(this.value); + select_deselect( + dataset, search_table, link_table, make_filter(dataset)); toggle_link_button(); } }); $("#tbl-link-genotypes").on("change", ".checkbox-selected", function(event) { if(!this.checked) { - select_deselect_dataset( - JSON.parse(this.value), link_table, search_table); + dataset = JSON.parse(this.value); + select_deselect( + dataset, link_table, search_table, make_filter(dataset)); toggle_link_button(); } }); diff --git a/wqflask/wqflask/static/new/javascript/auth/search_mrna.js b/wqflask/wqflask/static/new/javascript/auth/search_mrna.js index e754ae76..27e7fc0c 100644 --- a/wqflask/wqflask/static/new/javascript/auth/search_mrna.js +++ b/wqflask/wqflask/static/new/javascript/auth/search_mrna.js @@ -1,18 +1,3 @@ -/** - * Check whether `dataset` is in array of `datasets`. - * @param {mRNADataset} A mrna dataset. - * @param {Array} An array of mrna datasets. - */ -function in_array(dataset, datasets) { - found = datasets.filter(function(dst) { - return (dst.SpeciesId == dataset.SpeciesId && - dst.InbredSetId == dataset.InbredSetId && - dst.ProbeFreezeId == dataset.ProbeFreezeId && - dst.ProbeSetFreezeId == dataset.ProbeSetFreezeId); - }); - return found.length > 0; -} - function toggle_link_button() { num_groups = $("#frm-link select option").length - 1; num_selected = JSON.parse( @@ -65,6 +50,20 @@ function search_mrna() { }); } +/** + * Make function to check whether `dataset` is in array of `datasets`. + * @param {mRNADataset} A mrna dataset. + * @param {Array} An array of mrna datasets. + */ +function make_filter(dataset) { + return (dst) => { + return (dst.SpeciesId == dataset.SpeciesId && + dst.InbredSetId == dataset.InbredSetId && + dst.ProbeFreezeId == dataset.ProbeFreezeId && + dst.ProbeSetFreezeId == dataset.ProbeSetFreezeId); + }; +} + $(document).ready(function() { let search_table = new TableDataSource( "#tbl-search", "data-datasets", search_checkbox); @@ -80,16 +79,18 @@ $(document).ready(function() { $("#tbl-search").on("change", ".checkbox-search", function(event) { if(this.checked) { - select_deselect_dataset( - JSON.parse(this.value), search_table, link_table); + dataset = JSON.parse(this.value); + select_deselect( + dataset, search_table, link_table, make_filter(dataset)); toggle_link_button(); } }); $("#tbl-link").on("change", ".checkbox-selected", function(event) { if(!this.checked) { - select_deselect_dataset( - JSON.parse(this.value), link_table, search_table); + dataset = JSON.parse(this.value); + select_deselect( + dataset, link_table, search_table, make_filter(dataset)); toggle_link_button(); } }); diff --git a/wqflask/wqflask/static/new/javascript/auth/search_phenotypes.js b/wqflask/wqflask/static/new/javascript/auth/search_phenotypes.js index 61e71771..7cccbb3a 100644 --- a/wqflask/wqflask/static/new/javascript/auth/search_phenotypes.js +++ b/wqflask/wqflask/static/new/javascript/auth/search_phenotypes.js @@ -34,11 +34,17 @@ function default_error_fn(jqXHR, textStatus, errorThrown) { console.debug("ERROR:", errorThrown); } +/** + * Render the table(s) for the phenotype traits + * @param {TableDataSource} The table to render + */ function render_pheno_table(table_data_source) { table_id = table_data_source.table_id.selector; data_attr_name = table_data_source.data_attribute_name; $(table_id + " tbody tr").remove(); - table_data = JSON.parse($(table_id).attr(data_attr_name)); + table_data = JSON.parse($(table_id).attr(data_attr_name)).sort((t1, t2) => { + return (t1.name > t2.name ? 1 : (t1.name < t2.name ? -1 : 0)) + }); if(table_data.length < 1) { row = $("") cell = $(''); @@ -79,6 +85,7 @@ function display_search_results(data, textStatus, jqXHR) { if(data.status == "completed") { $("#tbl-phenotypes").attr( "data-traits", JSON.stringify(data.search_results)); + // Remove this reference to global variable render_pheno_table(search_table); } $("#txt-search").prop("disabled", false); @@ -130,6 +137,20 @@ function search_phenotypes() { }); } +/** + * Return a function to check whether `trait` is in array of `traits`. + * @param {PhenotypeTrait} A phenotype trait. + * @param {Array} An array of phenotype traits. + */ +function make_filter(trait) { + return (trt) => { + return (trt.species == trait.species && + trt.group == trait.group && + trt.dataset == trait.dataset && + trt.name == trait.name); + }; +} + $(document).ready(function() { $("#frm-search-traits").submit(event => { event.preventDefault(); @@ -138,16 +159,20 @@ $(document).ready(function() { $("#txt-query").keyup(debounce(search_phenotypes)); - $("#tbl-phenotypes").on("change", ".checkbox-selected", function(event) { - if(this.checked) { - select_deselect(JSON.parse(this.value), search_table, link_table); + $("#tbl-link-phenotypes").on("change", ".checkbox-selected", function(event) { + if(!this.checked) { + trait = JSON.parse(this.value); + select_deselect(trait, link_table, search_table, + make_filter(trait), render_pheno_table); toggle_link_button(); } }); - $("#tbl-link-phenotypes").on("change", ".checkbox-search", function(event) { - if(!this.checked) { - select_deselect(JSON.parse(this.value), search_table, link_table); + $("#tbl-phenotypes").on("change", ".checkbox-search", function(event) { + if(this.checked) { + trait = JSON.parse(this.value) + select_deselect(trait, search_table, link_table, + make_filter(trait), render_pheno_table); toggle_link_button(); } }); diff --git a/wqflask/wqflask/templates/oauth2/data-list-phenotype.html b/wqflask/wqflask/templates/oauth2/data-list-phenotype.html index 6afabdf8..9838a38d 100644 --- a/wqflask/wqflask/templates/oauth2/data-list-phenotype.html +++ b/wqflask/wqflask/templates/oauth2/data-list-phenotype.html @@ -24,7 +24,7 @@
-