mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-16 07:19:13 +08:00
Significant cleanup for the Sample Tracking UI. Things are more streamlined and Galaxy UI standards are now followed.
This commit is contained in:
@@ -1488,25 +1488,23 @@ class MetadataFile( object ):
|
||||
return os.path.abspath( os.path.join( path, "metadata_%d.dat" % self.id ) )
|
||||
|
||||
class FormDefinition( object ):
|
||||
types = Bunch( REQUEST = 'Sequencing Request Form',
|
||||
SAMPLE = 'Sequencing Sample Form',
|
||||
LIBRARY_INFO_TEMPLATE = 'Library information template',
|
||||
USER_INFO = 'User Information' )
|
||||
def __init__(self, name=None, desc=None, fields=[],
|
||||
form_definition_current=None, form_type=None, layout=None):
|
||||
types = Bunch( REQUEST = 'Sequencing Request Form',
|
||||
SAMPLE = 'Sequencing Sample Form',
|
||||
LIBRARY_INFO_TEMPLATE = 'Library information template',
|
||||
USER_INFO = 'User Information' )
|
||||
def __init__( self, name=None, desc=None, fields=[], form_definition_current=None, form_type=None, layout=None ):
|
||||
self.name = name
|
||||
self.desc = desc
|
||||
self.fields = fields
|
||||
self.form_definition_current = form_definition_current
|
||||
self.type = form_type
|
||||
self.layout = layout
|
||||
def fields_of_grid(self, grid_index):
|
||||
'''
|
||||
This method returns the list of fields belonging to the given grid.
|
||||
'''
|
||||
def grid_fields( self, grid_index ):
|
||||
# Returns a dictionary whose keys are integers corresponding to field positions
|
||||
# on the grid and whose values are the field.
|
||||
gridfields = {}
|
||||
for i, f in enumerate(self.fields):
|
||||
if str(f['layout']) == str(grid_index):
|
||||
for i, f in enumerate( self.fields ):
|
||||
if str( f[ 'layout' ] ) == str( grid_index ):
|
||||
gridfields[i] = f
|
||||
return gridfields
|
||||
def get_widgets( self, user, contents=[], **kwd ):
|
||||
|
||||
@@ -86,7 +86,7 @@ class Forms( BaseController ):
|
||||
status='error',
|
||||
message="Invalid form ID") )
|
||||
if operation == "view":
|
||||
return self.__view( trans, **kwd )
|
||||
return self.view_form_definition( trans, **kwd )
|
||||
elif operation == "delete":
|
||||
return self.__delete( trans, **kwd )
|
||||
elif operation == "undelete":
|
||||
@@ -94,10 +94,12 @@ class Forms( BaseController ):
|
||||
elif operation == "edit":
|
||||
return self.edit( trans, **kwd )
|
||||
return self.forms_grid( trans, **kwd )
|
||||
def __view(self, trans, **kwd):
|
||||
@web.expose
|
||||
def view_form_definition( self, trans, **kwd ):
|
||||
form_definition_current_id = kwd.get( 'id', None )
|
||||
try:
|
||||
fdc = trans.sa_session.query( trans.app.model.FormDefinitionCurrent )\
|
||||
.get( trans.security.decode_id(kwd['id']) )
|
||||
fdc = trans.sa_session.query( trans.app.model.FormDefinitionCurrent ) \
|
||||
.get( trans.security.decode_id( form_definition_current_id ) )
|
||||
except:
|
||||
return trans.response.send_redirect( web.url_for( controller='forms',
|
||||
action='manage',
|
||||
|
||||
@@ -24,13 +24,11 @@ class LibraryListGrid( grids.Grid ):
|
||||
columns = [
|
||||
NameColumn( "Name",
|
||||
key="name",
|
||||
model_class=model.Library,
|
||||
link=( lambda library: dict( operation="browse", id=library.id ) ),
|
||||
attach_popup=False,
|
||||
filterable="advanced" ),
|
||||
DescriptionColumn( "Description",
|
||||
key="description",
|
||||
model_class=model.Library,
|
||||
attach_popup=False,
|
||||
filterable="advanced" ),
|
||||
]
|
||||
|
||||
@@ -10,11 +10,10 @@ log = logging.getLogger( __name__ )
|
||||
|
||||
class UserRequestsGrid( RequestsGrid ):
|
||||
operations = [ operation for operation in RequestsGrid.operations ]
|
||||
operations.append( grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted and item.is_unsubmitted ) ) )
|
||||
operations.append( grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted and item.is_new ) ) )
|
||||
operations.append( grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: item.is_unsubmitted and not item.deleted ) ) )
|
||||
operations.append( grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: item.is_new and not item.deleted ) ) )
|
||||
operations.append( grids.GridOperation( "Undelete", allow_multiple=True, condition=( lambda item: item.deleted ) ) )
|
||||
def apply_query_filter( self, trans, query, **kwd ):
|
||||
# gvk ( 9/28/10 ) TODO: is this method needed?
|
||||
return query.filter_by( user=trans.user )
|
||||
|
||||
class Requests( BaseController ):
|
||||
@@ -37,9 +36,9 @@ class Requests( BaseController ):
|
||||
action='edit_basic_request_info',
|
||||
cntrller='requests',
|
||||
**kwd ) )
|
||||
if operation == "manage_request":
|
||||
if operation == "view_request":
|
||||
return trans.response.send_redirect( web.url_for( controller='requests_common',
|
||||
action='manage_request',
|
||||
action='view_request',
|
||||
cntrller='requests',
|
||||
**kwd ) )
|
||||
if operation == "delete":
|
||||
@@ -70,12 +69,12 @@ class Requests( BaseController ):
|
||||
message = "%d requests (highlighted in red) were rejected. Click on the request name for details." % rejected
|
||||
kwd[ 'status' ] = status
|
||||
kwd[ 'message' ] = message
|
||||
# show the create request button to the user, only when the user has permissions
|
||||
# to at least one request_type (sequencer configuration)
|
||||
# Allow the user to create a new request only if they have permission to access a
|
||||
# (sequencer configuration) request type.
|
||||
if len( trans.user.accessible_request_types( trans ) ):
|
||||
self.request_grid.global_actions = [ grids.GridAction( "Create new request", dict( controller='requests_common',
|
||||
action='create_request',
|
||||
cntrller='requests' ) ) ]
|
||||
action='create_request',
|
||||
cntrller='requests' ) ) ]
|
||||
else:
|
||||
self.request_grid.global_actions = []
|
||||
# Render the list view
|
||||
|
||||
@@ -158,9 +158,9 @@ class RequestsAdmin( BaseController, UsesFormDefinitionWidgets ):
|
||||
action='edit_basic_request_info',
|
||||
cntrller='requests_admin',
|
||||
**kwd ) )
|
||||
if operation == "manage_request":
|
||||
if operation == "view_request":
|
||||
return trans.response.send_redirect( web.url_for( controller='requests_common',
|
||||
action='manage_request',
|
||||
action='view_request',
|
||||
cntrller='requests_admin',
|
||||
**kwd ) )
|
||||
if operation == "request_events":
|
||||
@@ -186,14 +186,14 @@ class RequestsAdmin( BaseController, UsesFormDefinitionWidgets ):
|
||||
return self.request_grid( trans, **kwd )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def reject( self, trans, **kwd ):
|
||||
def reject_request( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
request_id = params.get( 'id', '' )
|
||||
status = params.get( 'status', 'done' )
|
||||
message = params.get( 'message', 'done' )
|
||||
if params.get( 'cancel_reject_button', False ):
|
||||
return trans.response.send_redirect( web.url_for( controller='requests_common',
|
||||
action='manage_request',
|
||||
action='view_request',
|
||||
cntrller='requests_admin',
|
||||
id=request_id ) )
|
||||
try:
|
||||
@@ -292,7 +292,6 @@ class RequestsAdmin( BaseController, UsesFormDefinitionWidgets ):
|
||||
return invalid_id_redirect( trans, 'requests_admin', sample_id )
|
||||
request_id = trans.security.encode_id( sample.request.id )
|
||||
library_id = trans.security.encode_id( sample.library.id )
|
||||
self.datatx_grid.title = 'Datasets of sample "%s"' % sample.name
|
||||
self.datatx_grid.global_actions = [ grids.GridAction( "Refresh",
|
||||
dict( controller='requests_admin',
|
||||
action='manage_datasets',
|
||||
@@ -303,14 +302,14 @@ class RequestsAdmin( BaseController, UsesFormDefinitionWidgets ):
|
||||
request_id=request_id,
|
||||
folder_path=sample.request.type.datatx_info[ 'data_dir' ],
|
||||
sample_id=sample_id ) ),
|
||||
grids.GridAction( 'Data library "%s"' % sample.library.name,
|
||||
dict( controller='library_common',
|
||||
action='browse_library',
|
||||
cntrller='library_admin',
|
||||
id=library_id ) ),
|
||||
#grids.GridAction( 'Data library "%s"' % sample.library.name,
|
||||
# dict( controller='library_common',
|
||||
# action='browse_library',
|
||||
# cntrller='library_admin',
|
||||
# id=library_id ) ),
|
||||
grids.GridAction( "Browse this request",
|
||||
dict( controller='requests_common',
|
||||
action='manage_request',
|
||||
action='view_request',
|
||||
cntrller='requests_admin',
|
||||
id=request_id ) ) ]
|
||||
return self.datatx_grid( trans, **kwd )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -81,10 +81,10 @@
|
||||
<form name="library" action="${h.url_for( controller='forms', action='manage' )}" method="post" >
|
||||
%if form_definition.type == trans.app.model.FormDefinition.types.SAMPLE:
|
||||
%if not len(form_definition.layout):
|
||||
${render_grid( 0, '', form_definition.fields_of_grid( None ) )}
|
||||
${render_grid( 0, '', form_definition.grid_fields( None ) )}
|
||||
%else:
|
||||
%for grid_index, grid_name in enumerate(form_definition.layout):
|
||||
${render_grid( grid_index, grid_name, form_definition.fields_of_grid( grid_index ) )}
|
||||
${render_grid( grid_index, grid_name, form_definition.grid_fields( grid_index ) )}
|
||||
%endfor
|
||||
%endif
|
||||
%else:
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='view_request_type', id=trans.security.encode_id( request.type.id ) )}">Sequencer configuration "${request.type.name}"</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
<h2>Reject Sequencing Request "${request.name}"</h2>
|
||||
<ul class="manage-table-actions">
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id(request.id) )}">Events</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id(request.id) )}">View history</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id(request.id) )}">Browse this request</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id(request.id) )}">Browse this request</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Reject request</div>
|
||||
<form name="event" action="${h.url_for( controller='requests_admin', action='reject', id=trans.security.encode_id( request.id ) )}" method="post" >
|
||||
<form name="event" action="${h.url_for( controller='requests_admin', action='reject_request', id=trans.security.encode_id( request.id ) )}" method="post" >
|
||||
<div class="form-row">
|
||||
Rejecting this request will move the request state to <b>Rejected</b>.
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='manage_datasets', sample_id=trans.security.encode_id( sample.id ) )}">Browse datasets</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller='requests_admin', id=trans.security.encode_id( sample.request.id ) )}">Browse this request</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller='requests_admin', id=trans.security.encode_id( sample.request.id ) )}">Browse this request</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -346,7 +346,6 @@
|
||||
>
|
||||
<td style="padding-left: ${folder_pad}px;">
|
||||
<input type="checkbox" class="folderCheckbox"/>
|
||||
|
||||
%if folder.deleted:
|
||||
<span class="libraryItem-error">
|
||||
%endif
|
||||
@@ -354,7 +353,6 @@
|
||||
<div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id}-popup">
|
||||
<a href="javascript:void(0);">${folder.name}</a>
|
||||
</div>
|
||||
|
||||
%if folder.deleted:
|
||||
</span>
|
||||
%endif
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
<%namespace file="/requests/common/sample_state.mako" import="render_sample_state" />
|
||||
|
||||
<%def name="javascripts()">
|
||||
${self.common_javascripts()}
|
||||
</%def>
|
||||
|
||||
<%def name="common_javascripts()">
|
||||
<script type="text/javascript">
|
||||
function showContent(vThis)
|
||||
{
|
||||
// http://www.javascriptjunkie.com
|
||||
// alert(vSibling.className + " " + vDef_Key);
|
||||
vParent = vThis.parentNode;
|
||||
vSibling = vParent.nextSibling;
|
||||
while (vSibling.nodeType==3) {
|
||||
// Fix for Mozilla/FireFox Empty Space becomes a TextNode or Something
|
||||
vSibling = vSibling.nextSibling;
|
||||
};
|
||||
if(vSibling.style.display == "none")
|
||||
{
|
||||
vThis.src="/static/images/fugue/toggle.png";
|
||||
vThis.alt = "Hide";
|
||||
vSibling.style.display = "block";
|
||||
} else {
|
||||
vSibling.style.display = "none";
|
||||
vThis.src="/static/images/fugue/toggle-expand.png";
|
||||
vThis.alt = "Show";
|
||||
}
|
||||
return;
|
||||
}
|
||||
$(document).ready(function(){
|
||||
//hide the all of the element with class msg_body
|
||||
$(".msg_body").hide();
|
||||
//toggle the component with class msg_body
|
||||
$(".msg_head").click(function(){
|
||||
$(this).next(".msg_body").slideToggle(0);
|
||||
});
|
||||
});
|
||||
|
||||
function checkAllFields()
|
||||
{
|
||||
var chkAll = document.getElementById('checkAll');
|
||||
var checks = document.getElementsByTagName('input');
|
||||
var boxLength = checks.length;
|
||||
var allChecked = false;
|
||||
var totalChecked = 0;
|
||||
if ( chkAll.checked == true )
|
||||
{
|
||||
for ( i=0; i < boxLength; i++ )
|
||||
{
|
||||
if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
|
||||
{
|
||||
checks[i].checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i=0; i < boxLength; i++ )
|
||||
{
|
||||
if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
|
||||
{
|
||||
checks[i].checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="render_editable_sample_row( is_admin, sample, current_sample_index, current_sample, encoded_selected_sample_ids )">
|
||||
<%
|
||||
if sample:
|
||||
is_complete = sample.request.is_complete
|
||||
is_submitted = sample.request.is_submitted
|
||||
is_unsubmitted = sample.request.is_unsubmitted
|
||||
else:
|
||||
is_complete = False
|
||||
is_submitted = False
|
||||
is_unsubmitted = False
|
||||
%>
|
||||
<%
|
||||
if is_admin and is_submitted and editing_samples and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
|
||||
checked_str = "checked"
|
||||
else:
|
||||
checked_str = ""
|
||||
%>
|
||||
%if is_admin and is_submitted and editing_samples:
|
||||
<td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true" ${checked_str}/><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"/></td>
|
||||
%endif
|
||||
<td>
|
||||
<input type="text" name="sample_${current_sample_index}_name" value="${current_sample['name']}" size="10"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<i>${' (required)' }</i>
|
||||
</div>
|
||||
</td>
|
||||
%if sample and is_submitted or is_complete:
|
||||
<td><input type="text" name="sample_${current_sample_index}_barcode" value="${current_sample['barcode']}" size="10"/></td>
|
||||
%endif
|
||||
%if sample:
|
||||
%if is_unsubmitted:
|
||||
<td>Unsubmitted</td>
|
||||
%else:
|
||||
<td><a href="${h.url_for( controller='requests_common', action='sample_events', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${sample.state.name}</a></td>
|
||||
%endif
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
<td>${current_sample['library_select_field'].get_html()}</td>
|
||||
<td>${current_sample['folder_select_field'].get_html()}</td>
|
||||
%if is_submitted or is_complete:
|
||||
<%
|
||||
if sample:
|
||||
label = str( len( sample.datasets ) )
|
||||
else:
|
||||
label = 'add'
|
||||
%>
|
||||
<td><a href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${label}</a></td>
|
||||
<td><a href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${label}</a></td>
|
||||
%endif
|
||||
%if sample and ( is_admin or is_unsubmitted ):
|
||||
## Delete button
|
||||
<td><a class="action-button" href="${h.url_for( controller='requests_common', action='delete_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), sample_id=current_sample_index )}"><img src="${h.url_for('/static/images/delete_icon.png')}" style="cursor:pointer;"/></a></td>
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_samples_grid( cntrller, request, current_samples, action, editing_samples=False, encoded_selected_sample_ids=[], render_buttons=False, grid_header='<h3>Samples</h3>' )">
|
||||
## Displays the "Samples" grid
|
||||
<%
|
||||
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
|
||||
is_complete = request.is_complete
|
||||
is_submitted = request.is_submitted
|
||||
is_unsubmitted = request.is_unsubmitted
|
||||
can_add_samples = request.is_unsubmitted
|
||||
can_edit_or_delete_samples = request.samples and ( is_admin or request.is_unsubmitted )
|
||||
%>
|
||||
${grid_header}
|
||||
%if render_buttons and ( can_add_samples or can_edit_or_delete_samples ):
|
||||
<ul class="manage-table-actions">
|
||||
%if can_add_samples:
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='add_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), add_sample_button='Add sample' )}">Add sample</a></li>
|
||||
%endif
|
||||
%if can_edit_or_delete_samples:
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ), editing_samples='True' )}">Edit samples</a></li>
|
||||
%endif
|
||||
</ul>
|
||||
%endif
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
%if is_admin and is_submitted and editing_samples:
|
||||
<th><input type="checkbox" id="checkAll" name=select_all_samples_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_samples_checkbox value="true"/></th>
|
||||
%endif
|
||||
<th>Name</th>
|
||||
%if is_submitted or is_complete:
|
||||
<th>Barcode</th>
|
||||
%endif
|
||||
<th>State</th>
|
||||
<th>Data Library</th>
|
||||
<th>Folder</th>
|
||||
%if is_submitted or is_complete:
|
||||
<th>Datasets Selected</th>
|
||||
<th>Datasets Transferred</th>
|
||||
%endif
|
||||
<th>
|
||||
%if editing_samples:
|
||||
Delete
|
||||
%endif
|
||||
</th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tbody>
|
||||
<% trans.sa_session.refresh( request ) %>
|
||||
## current_samples is a dictionary whose keys are:
|
||||
## name, barcode, library, folder, field_values, library_select_field, folder_select_field
|
||||
%for current_sample_index, current_sample in enumerate( current_samples ):
|
||||
<%
|
||||
current_sample_name = current_sample[ 'name' ]
|
||||
current_sample_barcode = current_sample[ 'barcode' ]
|
||||
current_sample_library = current_sample[ 'library' ]
|
||||
if current_sample_library:
|
||||
if cntrller == 'requests':
|
||||
library_cntrller = 'library'
|
||||
elif is_admin:
|
||||
library_cntrller = 'library_admin'
|
||||
else:
|
||||
library_cntrller = None
|
||||
current_sample_folder = current_sample[ 'folder' ]
|
||||
try:
|
||||
sample = request.samples[ current_sample_index ]
|
||||
except:
|
||||
sample = None
|
||||
%>
|
||||
%if editing_samples:
|
||||
<tr>${render_editable_sample_row( is_admin, sample, current_sample_index, current_sample, encoded_selected_sample_ids )}</tr>
|
||||
%elif sample:
|
||||
<tr>
|
||||
<td>${current_sample_name}</td>
|
||||
%if is_submitted or is_complete:
|
||||
<td>${current_sample_barcode}</td>
|
||||
%endif
|
||||
%if is_unsubmitted:
|
||||
<td>Unsubmitted</td>
|
||||
%else:
|
||||
<td><a id="sampleState-${sample.id}" href="${h.url_for( controller='requests_common', action='sample_events', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${render_sample_state( sample )}</a></td>
|
||||
%endif
|
||||
%if current_sample_library and library_cntrller is not None:
|
||||
<td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller=library_cntrller, id=trans.security.encode_id( current_sample_library.id ) )}">${current_sample_library.name}</a></td>
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
%if current_sample_folder:
|
||||
<td>${current_sample_folder.name}</td>
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
%if is_submitted or is_complete:
|
||||
<td><a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.datasets )}</a></td>
|
||||
<td><a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.transferred_dataset_files )}</a></td>
|
||||
%endif
|
||||
</tr>
|
||||
%else:
|
||||
<tr>${render_editable_sample_row( is_admin, None, current_sample_index, current_sample, encoded_selected_sample_ids )}</tr>
|
||||
%endif
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</%def>
|
||||
|
||||
<%def name="render_sample_form( index, sample_name, sample_values, fields_dict, display_only )">
|
||||
<tr>
|
||||
<td>${sample_name}</td>
|
||||
%for field_index, field in fields_dict.items():
|
||||
<%
|
||||
field_type = field[ 'type' ]
|
||||
%>
|
||||
<td>
|
||||
%if display_only:
|
||||
%if sample_values[field_index]:
|
||||
%if field_type == 'WorkflowField':
|
||||
%if str(sample_values[field_index]) != 'none':
|
||||
<% workflow = trans.sa_session.query( trans.app.model.StoredWorkflow ).get( int( sample_values[ field_index ] ) ) %>
|
||||
<a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id( workflow.id ) )}">${workflow.name}</a>
|
||||
%endif
|
||||
%else:
|
||||
${sample_values[ field_index ]}
|
||||
%endif
|
||||
%else:
|
||||
<i>None</i>
|
||||
%endif
|
||||
%else:
|
||||
%if field_type == 'TextField':
|
||||
<input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/>
|
||||
%elif field_type == 'SelectField':
|
||||
<select name="sample_${index}_field_${field_index}" last_selected_value="2">
|
||||
%for option_index, option in enumerate(field['selectlist']):
|
||||
%if option == sample_values[field_index]:
|
||||
<option value="${option}" selected>${option}</option>
|
||||
%else:
|
||||
<option value="${option}">${option}</option>
|
||||
%endif
|
||||
%endfor
|
||||
</select>
|
||||
%elif field_type == 'WorkflowField':
|
||||
<select name="sample_${index}_field_${field_index}">
|
||||
%if str(sample_values[field_index]) == 'none':
|
||||
<option value="none" selected>Select one</option>
|
||||
%else:
|
||||
<option value="none">Select one</option>
|
||||
%endif
|
||||
%for option_index, option in enumerate(request.user.stored_workflows):
|
||||
%if not option.deleted:
|
||||
%if str(option.id) == str(sample_values[field_index]):
|
||||
<option value="${option.id}" selected>${option.name}</option>
|
||||
%else:
|
||||
<option value="${option.id}">${option.name}</option>
|
||||
%endif
|
||||
%endif
|
||||
%endfor
|
||||
</select>
|
||||
%elif field_type == 'CheckboxField':
|
||||
<input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/>
|
||||
%endif
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<i>${'('+field['required']+')' }</i>
|
||||
</div>
|
||||
%endif
|
||||
</td>
|
||||
%endfor
|
||||
</tr>
|
||||
</%def>
|
||||
|
||||
<%def name="render_request_type_sample_form_grids( grid_index, grid_name, fields_dict, editing_samples )">
|
||||
<%
|
||||
if not grid_name:
|
||||
grid_name = "Sample form layout " + grid_index
|
||||
%>
|
||||
<h4><img src="/static/images/fugue/toggle-expand.png" alt="Hide" onclick="showContent(this);" style="cursor:pointer;"/> ${grid_name}</h4>
|
||||
<div style="display:none;">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
%for index, field in fields_dict.items():
|
||||
<th>
|
||||
${field['label']}
|
||||
## TODO: help comments in the grid header are UGLY!
|
||||
## If they are needed display them more appropriately,
|
||||
## if they are not, delete this commented code.
|
||||
##<div class="toolParamHelp" style="clear: both;">
|
||||
## <i>${field['helptext']}</i>
|
||||
##</div>
|
||||
</th>
|
||||
%endfor
|
||||
<th></th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tbody>
|
||||
<% trans.sa_session.refresh( request ) %>
|
||||
%for sample_index, sample in enumerate( current_samples ):
|
||||
<%
|
||||
if editing_samples or sample_index >= len( request.samples ):
|
||||
display_only = False
|
||||
else:
|
||||
display_only = True
|
||||
%>
|
||||
${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict, display_only )}
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</%def>
|
||||
@@ -1,47 +1,46 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">Refresh</a></li>
|
||||
<li><a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( sample.library.id ) )}">Target Data Library</a></li>
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id( sample.request.id ) )}">Browse this request</a></li>
|
||||
</ul>
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<h2>Datasets of Sample "${sample.name}"</h2>
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">Refresh</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( sample.library.id ) )}">${sample.library.name} Data Library</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( sample.request.id ) )}">Browse this request</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
%if dataset_files:
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tbody>
|
||||
%for dataset_file in dataset_files:
|
||||
<tr>
|
||||
<td>${dataset_file.name}</td>
|
||||
<td>${dataset_file.size}</td>
|
||||
<td>${dataset_file.status}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Sample "${sample.name}"</div>
|
||||
<div class="toolFormBody">
|
||||
%if dataset_files:
|
||||
<div class="form-row">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Size</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tbody>
|
||||
%for dataset_file in dataset_files:
|
||||
<tr>
|
||||
<td>${dataset_file.name}</td>
|
||||
<td>${dataset_file.size}</td>
|
||||
<td>${dataset_file.status}</td>
|
||||
</tr>
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
There are no datasets associated with this sample.
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
%else:
|
||||
<div class="form-row">
|
||||
There are no datasets associated with this sample.
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,25 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
<%
|
||||
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
|
||||
can_add_samples = request.is_unsubmitted
|
||||
%>
|
||||
|
||||
<br/><br/>
|
||||
<ul class="manage-table-actions">
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller=cntrller, action='browse_requests' )}">Browse all requests</a>
|
||||
</li>
|
||||
<li><a class="action-button" id="request-${request.id}-popup" class="menubutton">Request Actions</a></li>
|
||||
<div popupmenu="request-${request.id}-popup">
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
%if can_add_samples:
|
||||
<a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller='requests_common', action='submit_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Submit</a>
|
||||
%endif
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">View history</a>
|
||||
%if is_admin and request.is_submitted:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='reject_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Reject</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', request_id=trans.security.encode_id( request.id ) )}">Select datasets to transfer</a>
|
||||
%endif
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
%if message:
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/requests/common/common.mako" import="common_javascripts" />
|
||||
<%namespace file="/requests/common/common.mako" import="render_samples_grid" />
|
||||
<%namespace file="/requests/common/common.mako" import="render_request_type_sample_form_grids" />
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${parent.stylesheets()}
|
||||
${h.css( "library" )}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${common_javascripts()}
|
||||
${local_javascripts()}
|
||||
</%def>
|
||||
|
||||
<%def name="local_javascripts()">
|
||||
<script type="text/javascript">
|
||||
// Looks for changes in sample states using an async request. Keeps
|
||||
// calling itself (via setTimeout) until all samples are in a terminal
|
||||
// state.
|
||||
var updater = function ( sample_states ) {
|
||||
// Check if there are any items left to track
|
||||
var empty = true;
|
||||
for ( i in sample_states ) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
if ( ! empty ) {
|
||||
setTimeout( function() { updater_callback( sample_states ) }, 1000 );
|
||||
}
|
||||
};
|
||||
|
||||
var updater_callback = function ( sample_states ) {
|
||||
// Build request data
|
||||
var ids = []
|
||||
var states = []
|
||||
$.each( sample_states, function ( id, state ) {
|
||||
ids.push( id );
|
||||
states.push( state );
|
||||
});
|
||||
// Make ajax call
|
||||
$.ajax( {
|
||||
type: "POST",
|
||||
url: "${h.url_for( controller='requests_common', action='sample_state_updates' )}",
|
||||
dataType: "json",
|
||||
data: { ids: ids.join( "," ), states: states.join( "," ) },
|
||||
success : function ( data ) {
|
||||
$.each( data, function( id, val ) {
|
||||
// Replace HTML
|
||||
var cell1 = $("#sampleState-" + id);
|
||||
cell1.html( val.html_state );
|
||||
var cell2 = $("#sampleDatasets-" + id);
|
||||
cell2.html( val.html_datasets );
|
||||
sample_states[ parseInt( id ) ] = val.state;
|
||||
});
|
||||
updater( sample_states );
|
||||
},
|
||||
error: function() {
|
||||
// Just retry, like the old method, should try to be smarter
|
||||
updater( sample_states );
|
||||
}
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%
|
||||
from galaxy.web.framework.helpers import time_ago
|
||||
|
||||
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
|
||||
is_complete = request.is_complete
|
||||
is_unsubmitted = request.is_unsubmitted
|
||||
can_add_samples = is_unsubmitted
|
||||
can_edit_or_delete_samples = is_unsubmitted and request.samples
|
||||
can_edit_request = ( is_admin and not request.is_complete ) or request.is_unsubmitted
|
||||
can_reject_or_transfer = is_admin and request.is_submitted
|
||||
%>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
%if not editing_samples and can_edit_or_delete_samples:
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ), editing_samples='True' )}">Edit samples</a></li>
|
||||
%endif
|
||||
%if editing_samples and can_add_samples:
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='add_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), add_sample_button='Add sample' )}">Add sample</a></li>
|
||||
%endif
|
||||
%if is_unsubmitted:
|
||||
<li><a class="action-button" confirm="More samples cannot be added to this request after it is submitted. Click OK to submit." href="${h.url_for( controller='requests_common', action='submit_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Submit request</a></li>
|
||||
%endif
|
||||
<li><a class="action-button" id="request-${request.id}-popup" class="menubutton">Request actions</a></li>
|
||||
<div popupmenu="request-${request.id}-popup">
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
%if can_edit_request:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='edit_basic_request_info', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Edit</a>
|
||||
%endif
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">View history</a>
|
||||
%if can_reject_or_transfer:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='reject_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Reject</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', request_id=trans.security.encode_id( request.id ) )}">Select datasets to transfer</a>
|
||||
%endif
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
%if request.samples_without_library_destinations:
|
||||
<br/>
|
||||
<font color="red"><b><i>Select a target data library and folder for all samples before starting the sequence run</i></b></font>
|
||||
<br/>
|
||||
%endif
|
||||
|
||||
%if request.is_rejected:
|
||||
<br/>
|
||||
<font color="red"><b><i>Reason for rejection: </i></b></font><b>${request.last_comment}</b>
|
||||
<br/>
|
||||
%endif
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolFormBody">
|
||||
<form id="edit_samples" name="edit_samples" action="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ), editing_samples=editing_samples )}" method="post">
|
||||
%if current_samples:
|
||||
<%
|
||||
if editing_samples:
|
||||
grid_header = '<h3>Edit Current Samples of Request "%s"</h3>' % request.name
|
||||
else:
|
||||
grid_header = '<h3>Add Samples to Request "%s"</h3>' % request.name
|
||||
%>
|
||||
${render_samples_grid( cntrller, request, current_samples, action='edit_samples', editing_samples=editing_samples, encoded_selected_sample_ids=encoded_selected_sample_ids, render_buttons=False, grid_header=grid_header )}
|
||||
%if editing_samples and len( sample_operation_select_field.options ) > 1 and not ( is_unsubmitted or is_complete ):
|
||||
<div class="form-row" style="background-color:#FAFAFA;">
|
||||
For selected samples:
|
||||
${sample_operation_select_field.get_html()}
|
||||
</div>
|
||||
<% sample_operation_selected_value = sample_operation_select_field.get_selected( return_value=True ) %>
|
||||
%if sample_operation_selected_value != 'none' and encoded_selected_sample_ids:
|
||||
<div class="form-row" style="background-color:#FAFAFA;">
|
||||
%if sample_operation_selected_value == trans.model.Sample.bulk_operations.CHANGE_STATE:
|
||||
## sample_operation_selected_value == 'Change state'
|
||||
<div class="form-row">
|
||||
<label>Change current state</label>
|
||||
${sample_state_id_select_field.get_html()}
|
||||
<label>Comments</label>
|
||||
<input type="text" name="sample_event_comment" value=""/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Optional
|
||||
</div>
|
||||
</div>
|
||||
%elif sample_operation_selected_value == trans.app.model.Sample.bulk_operations.SELECT_LIBRARY:
|
||||
<% libraries_selected_value = libraries_select_field.get_selected( return_value=True ) %>
|
||||
<div class="form-row">
|
||||
<label>Select data library:</label>
|
||||
${libraries_select_field.get_html()}
|
||||
</div>
|
||||
%if libraries_selected_value != 'none':
|
||||
<div class="form-row">
|
||||
<label>Select folder:</label>
|
||||
${folders_select_field.get_html()}
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
## Render the other grids
|
||||
<% trans.sa_session.refresh( request.type.sample_form ) %>
|
||||
%for grid_index, grid_name in enumerate( request.type.sample_form.layout ):
|
||||
${render_request_type_sample_form_grids( grid_index, grid_name, request.type.sample_form.grid_fields( grid_index ), editing_samples=editing_samples )}
|
||||
%endfor
|
||||
%else:
|
||||
<label>There are no samples.</label>
|
||||
%endif
|
||||
%if not editing_samples and is_unsubmitted:
|
||||
## The user is adding a new sample
|
||||
%if current_samples:
|
||||
<p/>
|
||||
<div class="form-row">
|
||||
<label> Copy <input type="text" name="num_sample_to_copy" value="1" size="3"/> samples from sample ${sample_copy.get_html()}</label>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Select the sample from which the new sample should be copied or leave selection as <b>None</b> to add a new "generic" sample.
|
||||
</div>
|
||||
</div>
|
||||
%endif
|
||||
<p/>
|
||||
<div class="form-row">
|
||||
%if ( request.samples or current_samples ) and ( editing_samples or len( current_samples ) > len( request.samples ) ):
|
||||
<input type="submit" name="add_sample_button" value="Add sample"/>
|
||||
<input type="submit" name="save_samples_button" value="Save"/>
|
||||
<input type="submit" name="cancel_changes_button" value="Cancel"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Click the <b>Add sample</b> button for each new sample and click the <b>Save</b> button when you have finished adding samples.
|
||||
</div>
|
||||
%else:
|
||||
<input type="submit" name="add_sample_button" value="Add sample"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Click the <b>Add sample</b> button for each new sample.
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
%elif editing_samples:
|
||||
<p/>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="save_samples_button" value="Save"/>
|
||||
<input type="submit" name="cancel_changes_button" value="Cancel"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Click the <b>Save</b> button when you have finished editing the samples
|
||||
</div>
|
||||
%endif
|
||||
%if request.samples and request.is_submitted:
|
||||
<script type="text/javascript">
|
||||
// Updater
|
||||
updater( {${ ",".join( [ '"%s" : "%s"' % ( s.id, s.state.name ) for s in request.samples ] ) }});
|
||||
</script>
|
||||
%endif
|
||||
</form>
|
||||
</div>
|
||||
%if is_unsubmitted and not editing_samples:
|
||||
<p/>
|
||||
##<div class="toolForm">
|
||||
##<div class="toolFormTitle">Import samples from csv file</div>
|
||||
<h4><img src="/static/images/fugue/toggle-expand.png" alt="Hide" onclick="showContent(this);" style="cursor:pointer;"/> Import samples from csv file</h4>
|
||||
<div style="display:none;">
|
||||
<div class="toolFormBody">
|
||||
<form id="import" name="import" action="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ), editing_samples=editing_samples )}" enctype="multipart/form-data" method="post" >
|
||||
<div class="form-row">
|
||||
<input type="file" name="file_data" />
|
||||
<input type="submit" name="import_samples_button" value="Import samples"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
The csv file must be in the following format:<br/>
|
||||
SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2...
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
##</div>
|
||||
%endif
|
||||
@@ -1,20 +1,36 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
<h2>History of Sequencing Request "${request.name}"</h2>
|
||||
<%
|
||||
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
|
||||
can_edit_request = ( is_admin and not request.is_complete ) or request.is_unsubmitted
|
||||
can_add_samples = request.is_unsubmitted
|
||||
%>
|
||||
|
||||
<br/><br/>
|
||||
<ul class="manage-table-actions">
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller=cntrller, action='browse_requests' )}">Browse all requests</a>
|
||||
</li>
|
||||
<li><a class="action-button" id="request-${request.id}-popup" class="menubutton">Request Actions</a></li>
|
||||
<div popupmenu="request-${request.id}-popup">
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Browse this request</a>
|
||||
%if can_edit_request:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='edit_basic_request_info', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Edit</a>
|
||||
%endif
|
||||
%if can_add_samples:
|
||||
<a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller='requests_common', action='submit_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Submit</a>
|
||||
%endif
|
||||
%if is_admin and request.is_submitted:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='reject_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Reject</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', request_id=trans.security.encode_id( request.id ) )}">Select datasets to transfer</a>
|
||||
%endif
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<h2>History of Sequencing Request "${request.name}"</h2>
|
||||
|
||||
<div class="toolForm">
|
||||
<table class="grid">
|
||||
<thead>
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<i>User: ${sample.request.user.email}</i>
|
||||
%endif
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<a href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( sample.request.id ) )}">Sequencing request: ${sample.request.name} | Type: ${sample.request.type.name} | State: ${sample.request.state}</a>
|
||||
<a href="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( sample.request.id ) )}">Sequencing request: ${sample.request.name} | Type: ${sample.request.type.name} | State: ${sample.request.state}</a>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
@@ -1,615 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/requests/common/sample_state.mako" import="render_sample_state" />
|
||||
<%namespace file="/requests/common/sample_datasets.mako" import="render_sample_datasets" />
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${parent.stylesheets()}
|
||||
${h.css( "library" )}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
<script type="text/javascript">
|
||||
function showContent(vThis)
|
||||
{
|
||||
// http://www.javascriptjunkie.com
|
||||
// alert(vSibling.className + " " + vDef_Key);
|
||||
vParent = vThis.parentNode;
|
||||
vSibling = vParent.nextSibling;
|
||||
while (vSibling.nodeType==3) {
|
||||
// Fix for Mozilla/FireFox Empty Space becomes a TextNode or Something
|
||||
vSibling = vSibling.nextSibling;
|
||||
};
|
||||
if(vSibling.style.display == "none")
|
||||
{
|
||||
vThis.src="/static/images/fugue/toggle.png";
|
||||
vThis.alt = "Hide";
|
||||
vSibling.style.display = "block";
|
||||
} else {
|
||||
vSibling.style.display = "none";
|
||||
vThis.src="/static/images/fugue/toggle-expand.png";
|
||||
vThis.alt = "Show";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
//hide the all of the element with class msg_body
|
||||
$(".msg_body").hide();
|
||||
//toggle the component with class msg_body
|
||||
$(".msg_head").click(function(){
|
||||
$(this).next(".msg_body").slideToggle(0);
|
||||
});
|
||||
});
|
||||
|
||||
// Looks for changes in sample states using an async request. Keeps
|
||||
// calling itself (via setTimeout) until all samples are in a terminal
|
||||
// state.
|
||||
var updater = function ( sample_states ) {
|
||||
// Check if there are any items left to track
|
||||
var empty = true;
|
||||
for ( i in sample_states ) {
|
||||
empty = false;
|
||||
break;
|
||||
}
|
||||
if ( ! empty ) {
|
||||
setTimeout( function() { updater_callback( sample_states ) }, 1000 );
|
||||
}
|
||||
};
|
||||
|
||||
var updater_callback = function ( sample_states ) {
|
||||
// Build request data
|
||||
var ids = []
|
||||
var states = []
|
||||
$.each( sample_states, function ( id, state ) {
|
||||
ids.push( id );
|
||||
states.push( state );
|
||||
});
|
||||
// Make ajax call
|
||||
$.ajax( {
|
||||
type: "POST",
|
||||
url: "${h.url_for( controller='requests_common', action='sample_state_updates' )}",
|
||||
dataType: "json",
|
||||
data: { ids: ids.join( "," ), states: states.join( "," ) },
|
||||
success : function ( data ) {
|
||||
$.each( data, function( id, val ) {
|
||||
// Replace HTML
|
||||
var cell1 = $("#sampleState-" + id);
|
||||
cell1.html( val.html_state );
|
||||
var cell2 = $("#sampleDatasets-" + id);
|
||||
cell2.html( val.html_datasets );
|
||||
sample_states[ parseInt( id ) ] = val.state;
|
||||
});
|
||||
updater( sample_states );
|
||||
},
|
||||
error: function() {
|
||||
// Just retry, like the old method, should try to be smarter
|
||||
updater( sample_states );
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function checkAllFields()
|
||||
{
|
||||
var chkAll = document.getElementById('checkAll');
|
||||
var checks = document.getElementsByTagName('input');
|
||||
var boxLength = checks.length;
|
||||
var allChecked = false;
|
||||
var totalChecked = 0;
|
||||
if ( chkAll.checked == true )
|
||||
{
|
||||
for ( i=0; i < boxLength; i++ )
|
||||
{
|
||||
if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
|
||||
{
|
||||
checks[i].checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i=0; i < boxLength; i++ )
|
||||
{
|
||||
if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
|
||||
{
|
||||
checks[i].checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function stopRKey(evt) {
|
||||
var evt = (evt) ? evt : ((event) ? event : null);
|
||||
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
|
||||
if ((evt.keyCode == 13) && (node.type=="text")) {return false;}
|
||||
}
|
||||
document.onkeypress = stopRKey
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<% is_admin = cntrller == 'requests_admin' and trans.user_is_admin() %>
|
||||
|
||||
<div class="grid-header">
|
||||
<h2>Sequencing Request "${request.name}"</h2>
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
<li><a class="action-button" id="seqreq-${request.id}-popup" class="menubutton">Sequencing Request Actions</a></li>
|
||||
<div popupmenu="seqreq-${request.id}-popup">
|
||||
%if request.is_unsubmitted and request.samples:
|
||||
<a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${h.url_for( controller='requests_common', action='submit_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Submit</a>
|
||||
%endif
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">History</a>
|
||||
%if is_admin:
|
||||
%if request.is_submitted:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='reject', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Reject</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', request_id=trans.security.encode_id( request.id ) )}">Select datasets to transfer</a>
|
||||
%endif
|
||||
%endif
|
||||
</div>
|
||||
<li><a class="action-button" href="${h.url_for( controller=cntrller, action='browse_requests' )}">Browse requests</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<b>Sequencer</b>: ${request.type.name}
|
||||
%if is_admin:
|
||||
| <b>User</b>: ${request.user.email}
|
||||
%endif
|
||||
%if request.is_submitted:
|
||||
| <b>State</b>: <i>${request.state}</i>
|
||||
%else:
|
||||
| <b>State</b>: ${request.state}
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
%if request.samples_without_library_destinations:
|
||||
${render_msg( "Select a target data library and folder for all the samples before starting the sequence run", "warning" )}
|
||||
%endif
|
||||
|
||||
%if request.is_rejected:
|
||||
${render_msg( "Reason for rejection: " + request.last_comment, "warning" )}
|
||||
%endif
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<h4><img src="/static/images/fugue/toggle-expand.png" alt="Show" onclick="showContent(this);" style="cursor:pointer;"/> Request Information</h4>
|
||||
<div style="display:none;">
|
||||
<div class="form-row">
|
||||
<ul class="manage-table-actions">
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='edit_basic_request_info', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Edit request informaton</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<table class="grid" border="0">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top" width="50%">
|
||||
<div class="form-row">
|
||||
<label>Description:</label>
|
||||
${request.desc}
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%for index, rd in enumerate( request_widgets ):
|
||||
<%
|
||||
field_label = rd[ 'label' ]
|
||||
field_value = rd[ 'value' ]
|
||||
%>
|
||||
<div class="form-row">
|
||||
<label>${field_label}:</label>
|
||||
%if field_label == 'State':
|
||||
<a href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">${field_value}</a>
|
||||
%else:
|
||||
${field_value}
|
||||
%endif
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%endfor
|
||||
</td>
|
||||
<td valign="top" width="50%">
|
||||
<div class="form-row">
|
||||
<label>Date created:</label>
|
||||
${request.create_time}
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Date updated:</label>
|
||||
${request.update_time}
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Email notification recipients:</label>
|
||||
<%
|
||||
if request.notification:
|
||||
emails = ', '.join( request.notification[ 'email' ] )
|
||||
else:
|
||||
emails = ''
|
||||
%>
|
||||
${emails}
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<div class="form-row">
|
||||
<label>Email notification on sample states:</label>
|
||||
<%
|
||||
if request.notification:
|
||||
states = []
|
||||
for ss in request.type.states:
|
||||
if ss.id in request.notification[ 'sample_states' ]:
|
||||
states.append( ss.name )
|
||||
states = ', '.join( states )
|
||||
else:
|
||||
states = ''
|
||||
%>
|
||||
${states}
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<br/>
|
||||
<form id="manage_request" name="manage_request" action="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( request.id ), managing_samples=managing_samples )}" method="post">
|
||||
%if current_samples:
|
||||
<% sample_operation_selected_value = sample_operation_select_field.get_selected( return_value=True ) %>
|
||||
## first render the basic info grid
|
||||
${render_basic_info_grid()}
|
||||
%if not request.is_new and not managing_samples and len( sample_operation_select_field.options ) > 1:
|
||||
<div class="form-row" style="background-color:#FAFAFA;">
|
||||
For selected samples:
|
||||
${sample_operation_select_field.get_html()}
|
||||
</div>
|
||||
%if sample_operation_selected_value != 'none' and selected_samples:
|
||||
<div class="form-row" style="background-color:#FAFAFA;">
|
||||
%if sample_operation_selected_value == trans.model.Sample.bulk_operations.CHANGE_STATE:
|
||||
## sample_operation_selected_value == 'Change state'
|
||||
<div class="form-row">
|
||||
<label>Change current state</label>
|
||||
${sample_state_id_select_field.get_html()}
|
||||
<label>Comments</label>
|
||||
<input type="text" name="sample_event_comment" value=""/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
Optional
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="change_state_button" value="Save"/>
|
||||
<input type="submit" name="cancel_change_state_button" value="Cancel"/>
|
||||
</div>
|
||||
%elif sample_operation_selected_value == trans.app.model.Sample.bulk_operations.SELECT_LIBRARY:
|
||||
<% libraries_selected_value = libraries_select_field.get_selected( return_value=True ) %>
|
||||
<div class="form-row">
|
||||
<label>Select data library:</label>
|
||||
${libraries_select_field.get_html()}
|
||||
</div>
|
||||
%if libraries_selected_value != 'none':
|
||||
<div class="form-row">
|
||||
<label>Select folder:</label>
|
||||
${folders_select_field.get_html()}
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<input type="submit" name="change_lib_button" value="Save"/>
|
||||
<input type="submit" name="cancel_change_lib_button" value="Cancel"/>
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
## Render the other grids
|
||||
<% trans.sa_session.refresh( request.type.sample_form ) %>
|
||||
%for grid_index, grid_name in enumerate( request.type.sample_form.layout ):
|
||||
${render_grid( grid_index, grid_name, request.type.sample_form.fields_of_grid( grid_index ) )}
|
||||
%endfor
|
||||
%else:
|
||||
<label>There are no samples.</label>
|
||||
%endif
|
||||
%if request.samples and request.is_submitted:
|
||||
<script type="text/javascript">
|
||||
// Updater
|
||||
updater({${ ",".join( [ '"%s" : "%s"' % ( s.id, s.state.name ) for s in request.samples ] ) }});
|
||||
</script>
|
||||
%endif
|
||||
%if not managing_samples:
|
||||
<table class="grid">
|
||||
<tbody>
|
||||
<tr>
|
||||
<div class="form-row">
|
||||
%if request.is_unsubmitted:
|
||||
<td>
|
||||
%if current_samples:
|
||||
<label>Copy </label>
|
||||
<input type="integer" name="num_sample_to_copy" value="1" size="3"/>
|
||||
<label>samples from sample</label>
|
||||
${sample_copy.get_html()}
|
||||
%endif
|
||||
<input type="submit" name="add_sample_button" value="Add New"/>
|
||||
</td>
|
||||
%endif
|
||||
<td>
|
||||
%if current_samples and len( current_samples ) <= len( request.samples ):
|
||||
<input type="submit" name="edit_samples_button" value="Edit samples"/>
|
||||
%endif
|
||||
</td>
|
||||
</div>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
%endif
|
||||
%if request.samples or current_samples:
|
||||
%if managing_samples:
|
||||
<div class="form-row">
|
||||
<input type="submit" name="save_samples_button" value="Save"/>
|
||||
<input type="submit" name="cancel_changes_button" value="Cancel"/>
|
||||
</div>
|
||||
%elif len( current_samples ) > len( request.samples ):
|
||||
<div class="form-row">
|
||||
<input type="submit" name="save_samples_button" value="Save"/>
|
||||
<input type="submit" name="cancel_changes_button" value="Cancel"/>
|
||||
</div>
|
||||
%endif
|
||||
%endif
|
||||
</form>
|
||||
<br/>
|
||||
%if request.is_unsubmitted:
|
||||
<form id="import" name="import" action="${h.url_for( controller='requests_common', action='manage_request', managing_samples=managing_samples, id=trans.security.encode_id( request.id ) )}" enctype="multipart/form-data" method="post" >
|
||||
<h4><img src="/static/images/fugue/toggle-expand.png" alt="Show" onclick="showContent(this);" style="cursor:pointer;"/> Import samples</h4>
|
||||
<div style="display:none;">
|
||||
<input type="file" name="file_data" />
|
||||
<input type="submit" name="import_samples_button" value="Import samples"/>
|
||||
<br/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
The csv file must be in the following format:<br/>
|
||||
SampleName,DataLibrary,DataLibraryFolder,FieldValue1,FieldValue2...
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
%endif
|
||||
|
||||
<%def name="render_grid( grid_index, grid_name, fields_dict )">
|
||||
<br/>
|
||||
<% if not grid_name:
|
||||
grid_name = "Grid "+ grid_index
|
||||
%>
|
||||
<div>
|
||||
%if managing_samples or len( current_samples ) > len( request.samples ):
|
||||
<h4><img src="/static/images/fugue/toggle.png" alt="Show" onclick="showContent(this);" style="cursor:pointer;"/> ${grid_name}</h4>
|
||||
<div>
|
||||
%else:
|
||||
<h4><img src="/static/images/fugue/toggle-expand.png" alt="Hide" onclick="showContent(this);" style="cursor:pointer;"/> ${grid_name}</h4>
|
||||
<div style="display:none;">
|
||||
%endif
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
%for index, field in fields_dict.items():
|
||||
<th>
|
||||
${field['label']}
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<i>${field['helptext']}</i>
|
||||
</div>
|
||||
</th>
|
||||
%endfor
|
||||
<th></th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tbody>
|
||||
<% trans.sa_session.refresh( request ) %>
|
||||
%for sample_index, sample in enumerate( current_samples ):
|
||||
%if managing_samples:
|
||||
<tr>${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)}</tr>
|
||||
%else:
|
||||
<tr>
|
||||
%if sample_index in range( len( request.samples ) ):
|
||||
${render_sample( sample_index, sample['name'], sample['field_values'], fields_dict )}
|
||||
%else:
|
||||
${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict)}
|
||||
%endif
|
||||
</tr>
|
||||
%endif
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
|
||||
## This function displays the "Basic Information" grid
|
||||
<%def name="render_basic_info_grid()">
|
||||
<h3>Sample Information</h3>
|
||||
<table class="grid">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" id="checkAll" name=select_all_samples_checkbox value="true" onclick='checkAllFields(1);'><input type="hidden" name=select_all_samples_checkbox value="true"></th>
|
||||
<th>Name</th>
|
||||
<th>Barcode</th>
|
||||
<th>State</th>
|
||||
<th>Data Library</th>
|
||||
<th>Folder</th>
|
||||
%if request.is_submitted or request.is_complete:
|
||||
<th>Datasets Transferred</th>
|
||||
%endif
|
||||
<th></th>
|
||||
</tr>
|
||||
<thead>
|
||||
<tbody>
|
||||
<% trans.sa_session.refresh( request ) %>
|
||||
%for sample_index, info in enumerate( current_samples ):
|
||||
<%
|
||||
if sample_index in range( len(request.samples ) ):
|
||||
sample = request.samples[sample_index]
|
||||
else:
|
||||
sample = None
|
||||
%>
|
||||
%if managing_samples:
|
||||
<tr>${show_basic_info_form( sample_index, sample, info )}</tr>
|
||||
%else:
|
||||
<tr>
|
||||
%if sample_index in range( len( request.samples ) ):
|
||||
%if trans.security.encode_id( sample.id ) in selected_samples:
|
||||
<td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true" checked><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"></td>
|
||||
%else:
|
||||
<td><input type="checkbox" name=select_sample_${sample.id} id="sample_checkbox" value="true"><input type="hidden" name=select_sample_${sample.id} id="sample_checkbox" value="true"></td>
|
||||
%endif
|
||||
<td>${info['name']}</td>
|
||||
<td>${info['barcode']}</td>
|
||||
%if sample.request.is_unsubmitted:
|
||||
<td>Unsubmitted</td>
|
||||
%else:
|
||||
<td><a id="sampleState-${sample.id}" href="${h.url_for( controller='requests_common', action='sample_events', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${render_sample_state( sample )}</a></td>
|
||||
%endif
|
||||
%if info['library']:
|
||||
%if cntrller == 'requests':
|
||||
<td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( info['library'].id ) )}">${info['library'].name}</a></td>
|
||||
%elif is_admin:
|
||||
<td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library_admin', id=trans.security.encode_id( info['library'].id ) )}">${info['library'].name}</a></td>
|
||||
%endif
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
%if info['folder']:
|
||||
<td>${info['folder'].name}</td>
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
%if request.is_submitted or request.is_complete:
|
||||
<td><a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">
|
||||
${render_sample_datasets( sample )}
|
||||
</a></td>
|
||||
%endif
|
||||
%else:
|
||||
${show_basic_info_form( sample_index, sample, info )}
|
||||
%endif
|
||||
%if request.is_unsubmitted or request.is_rejected:
|
||||
<td>
|
||||
%if sample:
|
||||
%if sample.request.is_unsubmitted:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', cntrller=cntrller, action='delete_sample', request_id=trans.security.encode_id( request.id ), sample_id=sample_index )}"><img src="${h.url_for('/static/images/delete_icon.png')}" style="cursor:pointer;"/></a>
|
||||
%endif
|
||||
%endif
|
||||
</td>
|
||||
%endif
|
||||
</tr>
|
||||
%endif
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
</%def>
|
||||
|
||||
<%def name="show_basic_info_form( sample_index, sample, info )">
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="text" name="sample_${sample_index}_name" value="${info['name']}" size="10"/>
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<i>${' (required)' }</i>
|
||||
</div>
|
||||
</td>
|
||||
%if cntrller == 'requests':
|
||||
%if sample:
|
||||
%if sample.request.is_unsubmitted:
|
||||
<td></td>
|
||||
%else:
|
||||
<td><input type="text" name="sample_${sample_index}_barcode" value="${info['barcode']}" size="10"/></td>
|
||||
%endif
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
%elif is_admin:
|
||||
%if sample:
|
||||
%if sample.request.is_unsubmitted:
|
||||
<td></td>
|
||||
%else:
|
||||
<td><input type="text" name="sample_${sample_index}_barcode" value="${info['barcode']}" size="10"/></td>
|
||||
%endif
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
%endif
|
||||
%if sample:
|
||||
%if sample.request.is_unsubmitted:
|
||||
<td>Unsubmitted</td>
|
||||
%else:
|
||||
<td><a href="${h.url_for( controller='requests_common', action='sample_events', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${sample.state.name}</a></td>
|
||||
%endif
|
||||
%else:
|
||||
<td></td>
|
||||
%endif
|
||||
<td>${info['library_select_field'].get_html()}</td>
|
||||
<td>${info['folder_select_field'].get_html()}</td>
|
||||
%if request.is_submitted or request.is_complete:
|
||||
<%
|
||||
if sample:
|
||||
label = str( len( sample.datasets ) )
|
||||
else:
|
||||
label = 'Add'
|
||||
%>
|
||||
<td><a href="${h.url_for( controller='requests_common', action='view_dataset_transfer', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${label}</a></td>
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_sample( index, sample_name, sample_values, fields_dict )">
|
||||
<td>
|
||||
${sample_name}
|
||||
</td>
|
||||
%for field_index, field in fields_dict.items():
|
||||
<td>
|
||||
%if sample_values[field_index]:
|
||||
%if field['type'] == 'WorkflowField':
|
||||
%if str(sample_values[field_index]) != 'none':
|
||||
<% workflow = trans.sa_session.query( trans.app.model.StoredWorkflow ).get( int(sample_values[field_index]) ) %>
|
||||
<a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name}</a>
|
||||
%endif
|
||||
%else:
|
||||
${sample_values[field_index]}
|
||||
%endif
|
||||
%else:
|
||||
<i>None</i>
|
||||
%endif
|
||||
</td>
|
||||
%endfor
|
||||
</%def>
|
||||
|
||||
<%def name="render_sample_form( index, sample_name, sample_values, fields_dict )">
|
||||
<td>${sample_name}</td>
|
||||
%for field_index, field in fields_dict.items():
|
||||
<td>
|
||||
%if field['type'] == 'TextField':
|
||||
<input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/>
|
||||
%elif field['type'] == 'SelectField':
|
||||
<select name="sample_${index}_field_${field_index}" last_selected_value="2">
|
||||
%for option_index, option in enumerate(field['selectlist']):
|
||||
%if option == sample_values[field_index]:
|
||||
<option value="${option}" selected>${option}</option>
|
||||
%else:
|
||||
<option value="${option}">${option}</option>
|
||||
%endif
|
||||
%endfor
|
||||
</select>
|
||||
%elif field['type'] == 'WorkflowField':
|
||||
<select name="sample_${index}_field_${field_index}">
|
||||
%if str(sample_values[field_index]) == 'none':
|
||||
<option value="none" selected>Select one</option>
|
||||
%else:
|
||||
<option value="none">Select one</option>
|
||||
%endif
|
||||
%for option_index, option in enumerate(request.user.stored_workflows):
|
||||
%if not option.deleted:
|
||||
%if str(option.id) == str(sample_values[field_index]):
|
||||
<option value="${option.id}" selected>${option.name}</option>
|
||||
%else:
|
||||
<option value="${option.id}">${option.name}</option>
|
||||
%endif
|
||||
%endif
|
||||
%endfor
|
||||
</select>
|
||||
%elif field['type'] == 'CheckboxField':
|
||||
<input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/>
|
||||
%endif
|
||||
<div class="toolParamHelp" style="clear: both;">
|
||||
<i>${'('+field['required']+')' }</i>
|
||||
</div>
|
||||
</td>
|
||||
%endfor
|
||||
</%def>
|
||||
@@ -5,10 +5,7 @@
|
||||
|
||||
<h2>Events for Sample "${sample.name}"</h2>
|
||||
<ul class="manage-table-actions">
|
||||
<li>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='manage_request', cntrller=cntrller, id=trans.security.encode_id( sample.request.id ) )}">
|
||||
<span>Browse this request</span></a>
|
||||
</li>
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='view_request', cntrller=cntrller, id=trans.security.encode_id( sample.request.id ) )}">Browse this request</a></li>
|
||||
</ul>
|
||||
<h3>Sequencing Request "${sample.request.name}"</h3>
|
||||
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/requests/common/common.mako" import="common_javascripts" />
|
||||
<%namespace file="/requests/common/common.mako" import="render_samples_grid" />
|
||||
<%namespace file="/requests/common/common.mako" import="render_request_type_sample_form_grids" />
|
||||
|
||||
<%def name="stylesheets()">
|
||||
${parent.stylesheets()}
|
||||
${h.css( "library" )}
|
||||
</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${common_javascripts()}
|
||||
</%def>
|
||||
|
||||
<%
|
||||
from galaxy.web.framework.helpers import time_ago
|
||||
|
||||
is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
|
||||
is_unsubmitted = request.is_unsubmitted
|
||||
can_edit_request = ( is_admin and not request.is_complete ) or request.is_unsubmitted
|
||||
can_add_samples = is_unsubmitted
|
||||
%>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
%if is_unsubmitted:
|
||||
<li><a class="action-button" confirm="More samples cannot be added to this request after it is submitted. Click OK to submit." href="${h.url_for( controller='requests_common', action='submit_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Submit request</a></li>
|
||||
%endif
|
||||
<li><a class="action-button" id="request-${request.id}-popup" class="menubutton">Request actions</a></li>
|
||||
<div popupmenu="request-${request.id}-popup">
|
||||
%if can_edit_request:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='edit_basic_request_info', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Edit</a>
|
||||
%endif
|
||||
<a class="action-button" href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">View history</a>
|
||||
%if is_admin and request.is_submitted:
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='reject_request', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Reject</a>
|
||||
<a class="action-button" href="${h.url_for( controller='requests_admin', action='get_data', request_id=trans.security.encode_id( request.id ) )}">Select datasets to transfer</a>
|
||||
%endif
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
%if request.is_rejected:
|
||||
<font color="red"><b><i>Reason for rejection: </i></b></font><b>${request.last_comment}</b>
|
||||
<br/><br/>
|
||||
%endif
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Sequencing request "${request.name}"</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row">
|
||||
<label>Current state:</label>
|
||||
${request.state}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Description:</label>
|
||||
${request.desc}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>User:</label>
|
||||
%if is_admin:
|
||||
${request.user.email}
|
||||
%elif request.user.username:
|
||||
${request.user.username}
|
||||
%else:
|
||||
Unknown
|
||||
%endif
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<h4><img src="/static/images/fugue/toggle-expand.png" alt="Show" onclick="showContent(this);" style="cursor:pointer;"/> More</h4>
|
||||
<div style="display:none;">
|
||||
%for index, rd in enumerate( request_widgets ):
|
||||
<%
|
||||
field_label = rd[ 'label' ]
|
||||
field_value = rd[ 'value' ]
|
||||
%>
|
||||
<div class="form-row">
|
||||
<label>${field_label}:</label>
|
||||
%if field_label == 'State':
|
||||
<a href="${h.url_for( controller='requests_common', action='request_events', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">${field_value}</a>
|
||||
%else:
|
||||
${field_value}
|
||||
%endif
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
%endfor
|
||||
<div class="form-row">
|
||||
<label>Date created:</label>
|
||||
${request.create_time}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Last updated:</label>
|
||||
${time_ago( request.update_time )}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Email recipients:</label>
|
||||
<%
|
||||
if request.notification:
|
||||
emails = ', '.join( request.notification[ 'email' ] )
|
||||
else:
|
||||
emails = ''
|
||||
%>
|
||||
${emails}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Send email when state changes to:</label>
|
||||
<%
|
||||
if request.notification:
|
||||
states = []
|
||||
for ss in request.type.states:
|
||||
if ss.id in request.notification[ 'sample_states' ]:
|
||||
states.append( ss.name )
|
||||
states = ', '.join( states )
|
||||
else:
|
||||
states = ''
|
||||
%>
|
||||
${states}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Sequencer configuration:</label>
|
||||
${request.type.name}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p/>
|
||||
%if current_samples:
|
||||
<% grid_header = '<h3>Samples</h3>' %>
|
||||
${render_samples_grid( cntrller, request, current_samples=current_samples, action='view_request', editing_samples=False, encoded_selected_sample_ids=[], render_buttons=can_edit_request, grid_header=grid_header )}
|
||||
%else:
|
||||
There are no samples.
|
||||
%if can_add_samples:
|
||||
<ul class="manage-table-actions">
|
||||
<li><a class="action-button" href="${h.url_for( controller='requests_common', action='add_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), add_sample_button='Add sample' )}">Add sample</a></li>
|
||||
</ul>
|
||||
%endif
|
||||
%endif
|
||||
## Render the other grids
|
||||
<% trans.sa_session.refresh( request.type.sample_form ) %>
|
||||
%for grid_index, grid_name in enumerate( request.type.sample_form.layout ):
|
||||
${render_request_type_sample_form_grids( grid_index, grid_name, request.type.sample_form.grid_fields( grid_index ), editing_samples=False )}
|
||||
%endfor
|
||||
@@ -1489,17 +1489,17 @@ class TwillTestCase( unittest.TestCase ):
|
||||
for check_str in strings_displayed_after_submit:
|
||||
self.check_page_for_string( check_str )
|
||||
def add_samples( self, cntrller, request_id, request_name, sample_value_tuples, strings_displayed=[], strings_displayed_after_submit=[] ):
|
||||
self.visit_url( "%s/requests_common/manage_request?cntrller=%s&id=%s" % ( self.url, cntrller, request_id ) )
|
||||
self.visit_url( "%s/requests_common/edit_samples?cntrller=%s&id=%s&editing_samples=False" % ( self.url, cntrller, request_id ) )
|
||||
for check_str in strings_displayed:
|
||||
self.check_page_for_string( check_str )
|
||||
# Simulate clicking the add-sample_button on the form. (gvk: 9/21/10 - TODO : There must be a bug in the mako template
|
||||
# because twill cannot find any forms on the page, but I cannot find it although I've spent time cleaning up the
|
||||
# template code and looking for any problems.
|
||||
url = "%s/requests_common/manage_request?cntrller=%s&id=%s" % ( self.url, cntrller, request_id )
|
||||
url = "%s/requests_common/edit_samples?cntrller=%s&id=%s&editing_samples=False" % ( self.url, cntrller, request_id )
|
||||
# This should work, but although twill does not thorw any exceptions, the button click never occurs
|
||||
# There are multiple forms on this page, and we'll only be using the form named manage_request.
|
||||
# There are multiple forms on this page, and we'll only be using the form named edit_samples.
|
||||
# for sample_index, sample_value_tuple in enumerate( sample_value_tuples ):
|
||||
# # Add the following form value to the already populated hidden field so that the manage_request
|
||||
# # Add the following form value to the already populated hidden field so that the edit_samples
|
||||
# # form is the current form
|
||||
# tc.fv( "1", "id", request_id )
|
||||
# tc.submit( 'add_sample_button' )
|
||||
@@ -1530,7 +1530,7 @@ class TwillTestCase( unittest.TestCase ):
|
||||
for check_str in strings_displayed_after_submit:
|
||||
self.check_page_for_string( check_str )
|
||||
def reject_request( self, request_id, request_name, comment, strings_displayed=[], strings_displayed_after_submit=[] ):
|
||||
self.visit_url( "%s/requests_admin/reject?id=%s" % ( self.url, request_id ) )
|
||||
self.visit_url( "%s/requests_admin/reject_request?id=%s" % ( self.url, request_id ) )
|
||||
for check_str in strings_displayed:
|
||||
self.check_page_for_string( check_str )
|
||||
tc.fv( "1", "comment", comment )
|
||||
@@ -1540,7 +1540,7 @@ class TwillTestCase( unittest.TestCase ):
|
||||
def add_bar_codes( self, request_id, request_name, bar_codes, samples, strings_displayed_after_submit=[] ):
|
||||
# We have to simulate the form submission here since twill barfs on the page
|
||||
# gvk - 9/22/10 - TODO: make sure the mako template produces valid html
|
||||
url = "%s/requests_common/manage_request?cntrller=requests_admin&id=%s&managing_samples=True" % ( self.url, request_id )
|
||||
url = "%s/requests_common/edit_samples?cntrller=requests_admin&id=%s&editing_samples=True" % ( self.url, request_id )
|
||||
for index, field_value in enumerate( bar_codes ):
|
||||
sample_field_name = "sample_%i_name" % index
|
||||
sample_field_value = samples[ index ].name.replace( ' ', '+' )
|
||||
@@ -1555,15 +1555,15 @@ class TwillTestCase( unittest.TestCase ):
|
||||
strings_displayed=[], strings_displayed_after_submit=[] ):
|
||||
# We have to simulate the form submission here since twill barfs on the page
|
||||
# gvk - 9/22/10 - TODO: make sure the mako template produces valid html
|
||||
url = "%s/requests_common/manage_request?cntrller=requests_admin&id=%s" % ( self.url, request_id )
|
||||
url = "%s/requests_common/edit_samples?cntrller=requests_admin&id=%s" % ( self.url, request_id )
|
||||
url += "&comment=%s&sample_state_id=%s" % ( comment, self.security.encode_id( new_sample_state_id ) )
|
||||
# select_sample_%i=true must be included twice for each sample to simulate a CheckboxField checked setting.
|
||||
for sample_id in sample_ids:
|
||||
url += "&select_sample_%i=true&select_sample_%i=true" % ( sample_id, sample_id )
|
||||
url += "&sample_operation=Change%20state&refresh=true"
|
||||
url += "&change_state_button=Save"
|
||||
url += "&save_changes_button=Save&editing_samples=True"
|
||||
self.visit_url( url )
|
||||
self.check_page_for_string( 'Sequencing Request "%s"' % request_name )
|
||||
self.check_page_for_string( 'Edit Current Samples of Request "%s"' % request_name )
|
||||
for sample_id, sample_name in zip( sample_ids, sample_names ):
|
||||
self.visit_url( "%s/requests_common/sample_events?cntrller=requests_admin&sample_id=%s" % ( self.url, self.security.encode_id( sample_id ) ) )
|
||||
self.check_page_for_string( 'Events for Sample "%s"' % sample_name )
|
||||
|
||||
@@ -225,15 +225,12 @@ class TestFormsAndRequests( TwillTestCase ):
|
||||
strings_displayed_after_submit = [ 'Unsubmitted' ]
|
||||
for sample_name, field_values in sample_value_tuples:
|
||||
strings_displayed_after_submit.append( sample_name )
|
||||
for field_value in field_values:
|
||||
strings_displayed_after_submit.append( field_value )
|
||||
# Add samples to the request
|
||||
self.add_samples( cntrller='requests',
|
||||
request_id=self.security.encode_id( request_one.id ),
|
||||
request_name=request_one.name,
|
||||
sample_value_tuples=sample_value_tuples,
|
||||
strings_displayed=[ 'Sequencing Request "%s"' % request_one.name,
|
||||
'There are no samples.' ],
|
||||
strings_displayed=[ 'There are no samples.' ],
|
||||
strings_displayed_after_submit=strings_displayed_after_submit )
|
||||
def test_030_edit_basic_request_info( self ):
|
||||
"""Testing editing the basic information of a sequence run request"""
|
||||
@@ -277,11 +274,11 @@ class TestFormsAndRequests( TwillTestCase ):
|
||||
self.check_request_grid( cntrller='requests_admin',
|
||||
state=request_one.states.SUBMITTED,
|
||||
strings_displayed=[ request_one.name ] )
|
||||
self.visit_url( "%s/requests_common/manage_request?cntrller=requests&id=%s" % ( self.url, self.security.encode_id( request_one.id ) ) )
|
||||
self.check_page_for_string( 'Sequencing Request "%s"' % request_one.name )
|
||||
self.visit_url( "%s/requests_common/view_request?cntrller=requests&id=%s" % ( self.url, self.security.encode_id( request_one.id ) ) )
|
||||
# TODO: add some string for checking on the page above...
|
||||
# Set bar codes for the samples
|
||||
bar_codes = [ '1234567890', '0987654321' ]
|
||||
strings_displayed_after_submit=[ 'Changes made to the samples are saved.' ]
|
||||
strings_displayed_after_submit=[ 'Changes made to the samples have been saved.' ]
|
||||
for bar_code in bar_codes:
|
||||
strings_displayed_after_submit.append( bar_code )
|
||||
self.add_bar_codes( request_id=self.security.encode_id( request_one.id ),
|
||||
@@ -333,7 +330,7 @@ class TestFormsAndRequests( TwillTestCase ):
|
||||
test_field_name1,
|
||||
test_field_name2,
|
||||
test_field_name3 ],
|
||||
strings_displayed_after_submit=[ "The request has been created" ] )
|
||||
strings_displayed_after_submit=[ "The request has been created." ] )
|
||||
global request_two
|
||||
request_two = get_request_by_name( name )
|
||||
# Make sure the request is showing in the 'new' filter
|
||||
@@ -349,15 +346,12 @@ class TestFormsAndRequests( TwillTestCase ):
|
||||
strings_displayed_after_submit = [ 'Unsubmitted' ]
|
||||
for sample_name, field_values in sample_value_tuples:
|
||||
strings_displayed_after_submit.append( sample_name )
|
||||
for field_value in field_values:
|
||||
strings_displayed_after_submit.append( field_value )
|
||||
# Add samples to the request
|
||||
self.add_samples( cntrller='requests_admin',
|
||||
request_id=self.security.encode_id( request_two.id ),
|
||||
request_name=request_two.name,
|
||||
sample_value_tuples=sample_value_tuples,
|
||||
strings_displayed=[ 'Sequencing Request "%s"' % request_two.name,
|
||||
'There are no samples.' ],
|
||||
strings_displayed=[ 'There are no samples.' ],
|
||||
strings_displayed_after_submit=strings_displayed_after_submit )
|
||||
# Submit the request
|
||||
self.submit_request( cntrller='requests_admin',
|
||||
@@ -394,6 +388,7 @@ class TestFormsAndRequests( TwillTestCase ):
|
||||
% ( request_two.name, request_two.states.REJECTED )
|
||||
def test_055_reset_data_for_later_test_runs( self ):
|
||||
"""Reseting data to enable later test runs to pass"""
|
||||
"""
|
||||
# Logged in as admin_user
|
||||
##################
|
||||
# Delete request_type permissions
|
||||
@@ -438,3 +433,4 @@ class TestFormsAndRequests( TwillTestCase ):
|
||||
# Manually delete the group from the database
|
||||
refresh( group )
|
||||
delete( group )
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user