--- a +++ b/qiita_pet/templates/analysis_selected.html @@ -0,0 +1,286 @@ +{% extends sitebase.html %} +{% block head %} +{% from itertools import chain %} +<script type="text/javascript"> + +function error(evt) { $('#ws-error').html("<b>Server communication error. Sample removal will not be recorded. Please try again later.</b>"); }; +function check_empty() { + if($('.row').length <= 1) { + $('#dflt-sel-info').removeAttr('style'); + $('.topfloat').hide(); + $('#no-selected').show(); + } +} + +function clear() { + if(confirm('Are you sure you want to remove all samples?')) { + qiita_websocket.send('clear', {'pids': {% raw [int(p) for p in chain.from_iterable(pid.keys() for sid, pid in sel_data.items())] %} }); + } +} + +function clear_from_html(data) { + $.each($('.row'), function(index, value) { value.remove(); }); + check_empty(); +} + +function remove_proc_data(pid, sid) { + if(confirm('Are you sure you want to remove all samples for this processed data?')) { + qiita_websocket.send('remove_pd', {'proc_data': pid, 'samples': [], 'sid': sid}); + } +} + +function remove_pd_from_html(data) { + pid = data.proc_data; + sid = data.sid; + $('#proc' + pid).remove(); + $('#proc' + pid + '-samples').remove(); + // remove study if all proc data removed + if($('#study'+ sid + '-table tbody').children().length === 1) { $('#study'+sid).remove(); } + check_empty(); +} + +function remove_sample(sid, pid, sample) { qiita_websocket.send('remove_sample', {'proc_data': pid, 'samples': [sample], 'sid': sid}); } + +function remove_sample_from_html(data) { + pid = data.proc_data; + sample = data.samples[0]; + sid = data.sid; + document.getElementById(pid + '@' + sample).remove(); + //decriment sample count for pid + var count = $('#proc' + pid + '-sample-count'); + count.text(parseInt(count.text(), 10) - 1); + // remove proc data if all samples removed + if($('#proc' + pid + '-samples-table tbody').children().length === 0) { $('#proc'+pid).remove(); $('#proc' + pid + '-samples').remove(); } + // remove study if all proc data removed + if($('#study'+ sid + '-table tbody').children().length === 1) { $('#study'+sid).remove(); } + check_empty(); +} +$(document).ready(function() { + qiita_websocket.init(window.location.host + '{% raw qiita_config.portal_dir %}/analysis/selected/socket/', error, error); + qiita_websocket.add_callback('remove_pd', remove_pd_from_html); + qiita_websocket.add_callback('remove_sample', remove_sample_from_html); + qiita_websocket.add_callback('clear', clear_from_html); + $('#clear-button').on('click', clear); + {% if sel_data %}$('#no-selected').hide(){% end %} + + var common_sample_fields = {% raw list(common['sample']) %}; + var common_prep_fields = {% raw list(common['prep']) %}; + + $.each($(".chosen-select"), function (_, element){ + var is_sample = element.id.startsWith('sample-metadata'); + $.each(element.options, function (_, option){ + if (is_sample) { + if (jQuery.inArray(option.text, common_sample_fields) >= 0) { + option.selected=true; + if (!$('#analysis-metadata').val().includes(option.text)) { + $('#analysis-metadata').append( + $('<option>', { value: option.value, text: option.text, + selected: true})); + } + } + } else { + if (jQuery.inArray(option.text, common_prep_fields) >= 0) { + option.selected=true; + if (!$('#analysis-metadata').val().includes(option.text)) { + $('#analysis-metadata').append( + $('<option>', { value: option.value, text: option.text, + selected: true})); + } + } + } + }); + }); + + $('#analysis-metadata').chosen({ + width: "95%" + }); + + $(".chosen-select").chosen({ + width: "95%", + no_results_text: "Oops, nothing found!", + display_disabled_options: false, + display_selected_options: false, + }).change(function(event, object) { + var item = $(this).attr('id'); + var key = Object.keys(object)[0]; + var toggle = key == 'selected'; + var selection = object[key]; + + if (toggle && !$('#analysis-metadata').val().includes(selection)) { + $('#analysis-metadata').append( + $('<option>', { value: selection, text: selection, + selected: true})); + } else { + $(".analysis-metadata option[value='" + selection + "']").remove(); + } + // we need to update the chosen element AKA this line is needed for + // things to work fine + $("#analysis-metadata").trigger("chosen:updated"); + + if (jQuery.inArray(object[key], common_sample_fields) >= 0) { + $.each($(".chosen-select"), function (_, element){ + if (item != element.id) { + $.each(element.options, function (_, option){ + if (option.text == selection) { + option.selected=toggle; + } + }); + } + }); + } else if (jQuery.inArray(object[key], common_sample_fields) >= 0) { + $.each($(".chosen-select"), function (_, element){ + if (item != element.id) { + $.each(element.options, function (_, option){ + if (option.text == selection) { + option.selected=toggle; + } + }); + } + }); + } + }); + }); +</script> +{% end %} + + +{% block content %} +<h1>Selected Samples</h1> +<span id="ws-error" style="color:red"></span> +<div id="no-selected" class="jumbotron"> + <h1>No samples selected</h1> + <h3><a href="{% raw qiita_config.portal_dir %}/study/list/">Please select at least one sample to continue</a><h3> +</div> +{% if sel_data %} +<div class="row"> + <div class="col-lg-12"> + <button type="button" class="btn btn-success btn-sm" id="create-button" name="create-button" data-toggle="modal" data-target="#create-analysis-modal-view"> + Create Analysis + </button> + <button type="button" class="btn btn-danger btn-sm" id="clear-button" name="clear-button"> + Clear Selected + </button> + </div> +</div> +<br/> +{% end %} + +{% for study, proc_datas in sel_data.items() %} +<div class="row" id="study{{study.id}}"> + <div class="col-md-12" style="border:2px solid #a1a1a1; border-radius: 15px;"> + <h2><a href="{% raw qiita_config.portal_dir %}/study/description/{{study.id}}">{{study.title}}</a></h2> + <h4>Processed Data</h4> + <table class='table table-striped' id='study{{study.id}}-table'> + <tr> + <th class="col-sm-1">id</th><th class="col-sm-1">Datatype</th><th class="col-sm-2">Processed Date</th><th class="col-sm-2">Parent processing</th><th class="col-sm-2">Merging Scheme</th><th class="col-sm-1">Samples selected from Prep Info</th><th></th><th></th> + </tr> + {% for pid, samples in proc_datas.items() %} + <tr id="proc{{pid}}"> + <td>{{pid}} <a href="#" data-toggle="modal" data-target="#proc{{pid}}-settings-modal" onclick="return false;"><span class="glyphicon glyphicon-info-sign"></span></a></td> + <td>{{proc_info[pid]["data_type"]}}</td> + <td>{{proc_info[pid]["processed_date"]}}</td> + <td>{{proc_info[pid]["merging_scheme"][1]}}</td> + <td>{{proc_info[pid]["merging_scheme"][0]}}</td> + <td><span id="proc{{pid}}-sample-count">{% raw len(samples) %}</span></td> + <td><a href="#" onclick="$('#proc{{pid}}-samples').toggle(); return false;">Show/Hide samples</a></td> + <td><a href="#" onclick = 'remove_proc_data({{pid}}, {{study.id}})'>Remove</a></td> + </tr> + <tr id="proc{{pid}}-samples" hidden><td colspan=7> + <table class="table table-striped sample-table" id="proc{{pid}}-samples-table" style="width:50%"> + {% for samp in samples %} + <tr id="{{pid}}@{{samp}}"><td>{{samp}}</td><td><a href="#" onclick="remove_sample('{{study.id}}', '{{pid}}', '{{samp}}')">Remove</a></td></tr> + {% end %} + </table> + </td></tr> + {% for pid in proc_datas %} +<!-- modal view to enter analysis information --> + <div class="modal fade" id="proc{{pid}}-settings-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title" id="myModalLabel">Processed Data {{pid}}</h4> + </div> + <form role="form" action="{% raw qiita_config.portal_dir %}/analysis/create/" method="post"> + <input type="hidden" name="action" value="create"> + <div class="modal-body"> + <b>Datatype</b>: {{proc_info[pid]["data_type"]}} <br/> + <b>Processed Date</b>: {{proc_info[pid]["processed_date"]}} <br/> + <b>Parent processing</b>: {{proc_info[pid]["merging_scheme"][1]}} <br/> + <b>Merging Scheme</b>: {{proc_info[pid]["merging_scheme"][0]}} + </div> + <div class="modal-footer"> + </div> + </div> + </div> + </div> + {% end %} + {% end %} + </table> + <hr> + <h4>Metadata Selection <small>Common fields for all studies are preselected. Click to view/add unique fields from each dataset.</small></h4> + <table border="0" style="width: 100%;"> + <tr> + <td style="width: 50%;"> + Sample Information + <select data-placeholder="Choose Sample Metadata..." multiple class="chosen-select" id="sample-metadata-{{study.id}}"> + {% for field in sorted(metadata[study.id]['sample']) %} + <option value="{{field}}">{{field}}</option> + {% end %} + </select> + </td> + <td style="width: 50%;"> + Preparation Information + <select data-placeholder="Choose Preparation Metadata..." multiple class="chosen-select" id="prep-metadata-{{study.id}}"> + {% for field in sorted(metadata[study.id]['prep']) %} + <option value="{{field}}">{{field}}</option> + {% end %} + </td> + </tr> + </table> + </div> +</div> +{% end %} + +<!-- modal view to enter analysis information --> + <div class="modal fade" id="create-analysis-modal-view" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> + <h4 class="modal-title" id="myModalLabel">Create new analysis</h4> + </div> + <form role="form" action="{% raw qiita_config.portal_dir %}/analysis/create/" method="post"> + <input type="hidden" name="action" value="create"> + <div class="modal-body"> + <div> + <div class="form-group"> + <label for="name">Analysis name</label> + <input type="text" class="form-control" id="name" name="name" placeholder="Analysis name"> + </div> + <div class="form-group"> + <label for="description">Description</label> + <input type="text" class="form-control" id="description" name="description" placeholder="Short description"> + </div> + <div class="form-group"> + <label for="description">Merge samples with the same name <br/><small>useful when merging multiple preparation artifacts</small></label> + <input type="checkbox" class="form-control" id="merge_duplicated_sample_ids" name="merge_duplicated_sample_ids"> + </div> + <div class="form-group"> + <label for="description">Metadata selected <small>(to update use the main page)</small></label> + <select name="analysis-metadata" id="analysis-metadata" class="analysis-metadata" multiple disabled></select> + </div> + <div class="form-group"> + <label for="description">Reservation (optional)</label> + <input type="text" class="form-control" id="reservation" name="reservation" placeholder="Reservation (optional)"> + </div> + </div> + </div> + <div class="modal-footer"> + <button type="submit" onclick="$('#analysis-metadata').removeAttr('disabled');" "class="btn btn-primary">Create analysis</button> + </div> + </form> + </div> + </div> + </div> +{% end %}