PageRenderTime 29ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 1ms

/templates/requests/common/common.mako

https://bitbucket.org/cistrome/cistrome-harvard/
Mako | 722 lines | 683 code | 15 blank | 24 comment | 11 complexity | 76197468d7204c1fc9697163bd656c98 MD5 | raw file
  1<%namespace file="/requests/common/sample_state.mako" import="render_sample_state" />
  2<%namespace file="/message.mako" import="render_msg" />
  3
  4<%def name="javascripts()">
  5   ${self.common_javascripts()}
  6</%def>
  7
  8<%def name="common_javascripts()">
  9    <script type="text/javascript">
 10        function showContent(vThis)
 11        {
 12            // http://www.javascriptjunkie.com
 13            // alert(vSibling.className + " " + vDef_Key);
 14            vParent = vThis.parentNode;
 15            vSibling = vParent.nextSibling;
 16            while (vSibling.nodeType==3) { 
 17                // Fix for Mozilla/FireFox Empty Space becomes a TextNode or Something
 18                vSibling = vSibling.nextSibling;
 19            };
 20            if(vSibling.style.display == "none")
 21            {
 22                vThis.src="/static/images/silk/resultset_bottom.png";
 23                vThis.alt = "Hide";
 24                vSibling.style.display = "block";
 25            } else {
 26                vSibling.style.display = "none";
 27                vThis.src="/static/images/silk/resultset_next.png";
 28                vThis.alt = "Show";
 29            }
 30            return;
 31        }
 32        $(document).ready(function(){
 33            //hide the all of the element with class msg_body
 34            $(".msg_body").hide();
 35            //toggle the component with class msg_body
 36            $(".msg_head").click(function(){
 37                $(this).next(".msg_body").slideToggle(0);
 38            });
 39        });
 40
 41        function checkAllFields()
 42        {
 43            var chkAll = document.getElementById('checkAll');
 44            var checks = document.getElementsByTagName('input');
 45            var boxLength = checks.length;
 46            var allChecked = false;
 47            var totalChecked = 0;
 48            if ( chkAll.checked == true )
 49            {
 50                for ( i=0; i < boxLength; i++ )
 51                {
 52                    if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
 53                    {
 54                       checks[i].checked = true;
 55                    }
 56                }
 57            }
 58            else
 59            {
 60                for ( i=0; i < boxLength; i++ )
 61                {
 62                    if ( checks[i].name.indexOf( 'select_sample_' ) != -1)
 63                    {
 64                       checks[i].checked = false
 65                    }
 66                }
 67            }
 68        }
 69
 70        // Sample State Updater
 71        // 
 72        // Looks for changes in sample states using an async request. Keeps
 73        // calling itself (via setTimeout) until all samples are in a terminal
 74        // state.
 75        var sample_state_updater = function ( sample_states ) {
 76            // Check if there are any items left to track
 77            var empty = true;
 78            for ( i in sample_states ) {
 79                empty = false;
 80                break;
 81            }
 82            if ( ! empty ) {
 83                setTimeout( function() { sample_state_updater_callback( sample_states ) }, 3000 );
 84            }
 85        };
 86        var sample_state_updater_callback = function ( sample_states ) {
 87            // Build request data
 88            var ids = []
 89            var states = []
 90            $.each( sample_states, function ( id, state ) {
 91                ids.push( id );
 92                states.push( state );
 93            });
 94            // Make ajax call
 95            $.ajax( {
 96                type: "POST",
 97                url: "${h.url_for( controller='requests_common', action='sample_state_updates' )}",
 98                dataType: "json",
 99                data: { ids: ids.join( "," ), states: states.join( "," ) },
100                success : function ( data ) {
101                    $.each( data, function( id, val ) {
102                        // Replace sample state HTML
103                        var cell1 = $("#sampleState-" + id);
104                        cell1.html( val.html_state );
105                        sample_states[ parseInt( id ) ] = val.state;
106                    });
107                    sample_state_updater( sample_states ); 
108                },
109                error: function() {
110                    // Just retry, like the old method, should try to be smarter
111                    sample_state_updater( sample_states );
112                }
113            });
114        };
115        
116        
117        // Sample Datasets Updater
118        // 
119        // Looks for changes in the number sample datasets using an async request. Keeps
120        // calling itself (via setTimeout) until all samples are in a terminal
121        // state.
122        var sample_datasets_updater = function ( sample_datasets ) {
123            // Check if there are any items left to track
124            var empty = true;
125            for ( i in sample_datasets ) {
126                empty = false;
127                break;
128            }
129            if ( ! empty ) {
130                setTimeout( function() { sample_datasets_updater_callback( sample_datasets ) }, 3000 );
131            }
132        };
133        var sample_datasets_updater_callback = function ( sample_datasets ) {
134            // Build request data
135            var ids = []
136            var datasets = []
137            $.each( sample_datasets, function ( id, num_of_datasets ) {
138                ids.push( id );
139                datasets.push( num_of_datasets );
140            });
141            // Make ajax call
142            $.ajax( {
143                type: "POST",
144                url: "${h.url_for( controller='requests_common', action='sample_datasets_updates' )}",
145                dataType: "json",
146                data: { ids: ids.join( "," ), datasets: datasets.join( "," ) },
147                success : function ( data ) {
148                    $.each( data, function( id, val ) {
149                        // Replace sample datasets HTML
150                        var cell2 = $("#sampleDatasets-" + id);
151                        cell2.html( val.html_datasets );
152                        sample_datasets[ parseInt( id ) ] = val.datasets;
153
154                    });
155                    sample_datasets_updater( sample_datasets ); 
156                },
157                error: function() {
158                    // Just retry, like the old method, should try to be smarter
159                    sample_datasets_updater( sample_datasets ); 
160                }
161            });
162        };
163        
164        // Sample Dataset Transfer Status Updater
165        //
166        // It is used to update the transfer status on Manage Datasets page for a sample 
167        // of a sequencing request
168        // Looks for changes in sample dataset transfer status using an async request. Keeps
169        // calling itself (via setTimeout) until transfer_status is complete
170        var dataset_transfer_status_updater = function ( dataset_transfer_status_list ) {
171            // Check if there are any items left to track
172            var empty = true;
173            for ( i in dataset_transfer_status_list ) {
174                empty = false;
175                break;
176            }
177            if ( ! empty ) {
178                setTimeout( function() { dataset_transfer_status_updater_callback( dataset_transfer_status_list ) }, 3000 );
179            }
180        };
181        var dataset_transfer_status_updater_callback = function ( dataset_transfer_status_list ) {
182            // Build request data
183            var ids = []
184            var transfer_status_list = []
185            $.each( dataset_transfer_status_list, function ( id, dataset_transfer_status ) {
186                ids.push( id );
187                transfer_status_list.push( dataset_transfer_status );
188            });
189            // Make ajax call
190            $.ajax( {
191                type: "POST",
192                url: "${h.url_for( controller='requests_common', action='dataset_transfer_status_updates' )}",
193                dataType: "json",
194                data: { ids: ids.join( "," ), transfer_status_list: transfer_status_list.join( "," ) },
195                success : function ( data ) {
196                    $.each( data, function( id, val ) {
197                        // Replace HTML
198                        var cell1 = $("#datasetTransferStatus-" + id);
199                        cell1.html( val.html_status );
200                        dataset_transfer_status_list[ id ] = val.status;
201                    });
202                    dataset_transfer_status_updater( dataset_transfer_status_list ); 
203                },
204                error: function() {
205                    // Just retry, like the old method, should try to be smarter
206                    dataset_transfer_status_updater( dataset_transfer_status_list ); 
207                }
208            });
209        };
210    </script>
211</%def>
212
213<%def name="transfer_status_updater()">
214    <% 
215        can_update = False
216        if query.count():
217            # Get the first sample dataset to get to the parent sample
218            sample_dataset = query[0]
219            sample = sample_dataset.sample
220            is_complete = sample.request.is_complete
221            is_submitted = sample.request.is_submitted
222            can_update = is_complete or is_submitted and sample.untransferred_dataset_files
223    %>
224    %if can_update:
225        <script type="text/javascript">
226            // Sample dataset transfer status updater
227            dataset_transfer_status_updater( {${ ",".join( [ '"%s" : "%s"' % ( trans.security.encode_id( sd.id ), sd.status ) for sd in query ] ) }});
228        </script>
229    %endif
230</%def>
231
232<%def name="render_editable_sample_row( cntrller, request, sample, sample_widget_index, sample_widget, encoded_selected_sample_ids, adding_new_samples=False )">
233    <%
234        trans.sa_session.refresh( request )
235        is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
236        is_rejected = request.is_rejected
237        is_complete = request.is_complete
238        is_submitted = request.is_submitted
239        is_unsubmitted = request.is_unsubmitted
240        if sample:
241            can_delete_samples = not adding_new_samples and request.samples and ( ( is_admin and not is_complete ) or is_unsubmitted )
242            display_checkboxes = not adding_new_samples and ( is_complete or is_rejected or is_submitted )
243            display_datasets = request.samples and ( is_complete or is_submitted )
244        else:
245            can_delete_samples = False
246            display_checkboxes = False
247            display_datasets = False
248        display_bar_code = request.samples and ( is_complete or is_rejected or is_submitted )
249    %>
250    <%
251        if display_checkboxes and trans.security.encode_id( sample.id ) in encoded_selected_sample_ids:
252            checked_str = "checked"
253        else:
254            checked_str = ""
255    %>
256    %if display_checkboxes:
257        <td valign="top"><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>
258    %endif
259    <td valign="top">
260        <input type="text" name="sample_${sample_widget_index}_name" value="${sample_widget['name']}" size="10"/>
261        <div class="toolParamHelp" style="clear: both;">
262            <i>${' (required)' }</i>
263        </div>
264    </td>
265    %if display_bar_code:
266        <td valign="top">
267            %if is_admin and is_submitted:
268                <input type="text" name="sample_${sample_widget_index}_bar_code" value="${sample_widget['bar_code']}" size="10"/>
269            %else:
270                ${sample_widget['bar_code']}
271                <input type="hidden" name="sample_${sample_widget_index}_bar_code" value="${sample_widget['bar_code']}"/>
272            %endif
273        </td>
274    %endif
275    %if sample:
276        %if is_unsubmitted:
277            <td>Unsubmitted</td>
278        %else:
279            <td valign="top"><a href="${h.url_for( controller='requests_common', action='view_sample_history', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${sample.state.name}</a></td>
280        %endif
281    %else:
282        <td></td>
283    %endif
284    <td valign="top">${sample_widget['library_select_field'].get_html()}</td>
285    <td valign="top">${sample_widget['folder_select_field'].get_html()}</td>
286    <td valign="top">${sample_widget['history_select_field'].get_html()}</td>
287    <td valign="top">
288    ${sample_widget['workflow_select_field'][0].get_html()}
289    %if len(sample_widget['workflow_select_field']) > 1:
290        <br/>
291        ${'<br/>'.join(["%s:<br/>%s" % (w_l, w_i.get_html()) for w_l, w_i in sample_widget['workflow_select_field'][1:]])}
292    %endif
293    </td>
294    %if display_datasets:
295        <td valign="top">
296            ## An admin can select the datasets to transfer, while a non-admin can only view what has been selected
297            %if is_admin:
298                ## This link will direct the admin to a page allowing them to manage datasets.
299                <a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_admin', action='manage_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.datasets )}</a>
300            %elif sample.datasets:
301                ## Since this is a regular user, only display a link if there is at least 1
302                ## selected dataset for the sample.
303                <a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_common', action='view_sample_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.datasets )}</a>
304            %else:
305                ## Since this is a regular user, do not display a link if there are no datasets.
306                <a id="sampleDatasets-${sample.id}">${len( sample.datasets )}</a>
307            %endif
308        </td>
309    %endif
310    %if can_delete_samples:
311        ## Delete button
312        <td valign="top"><a class="action-button" confirm="This sample is not recoverable after deletion. Click Ok to delete." href="${h.url_for( controller='requests_common', action='delete_sample', cntrller=cntrller, request_id=trans.security.encode_id( request.id ), sample_id=sample_widget_index )}"><img src="${h.url_for('/static/images/delete_icon.png')}" style="cursor:pointer;"/></a></td>
313    %endif
314</%def>
315
316<%def name="render_samples_grid( cntrller, request, displayable_sample_widgets, action, adding_new_samples=False, encoded_selected_sample_ids=[], render_buttons=False, grid_header='<h3>Samples</h3>' )">
317    ## Displays the "Samples" grid
318<%
319    trans.sa_session.refresh( request )
320    is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
321    is_complete = request.is_complete
322    is_rejected = request.is_rejected
323    is_submitted = request.is_submitted
324    is_unsubmitted = request.is_unsubmitted
325    if is_admin:
326       can_add_samples = not is_complete
327    else:
328       can_add_samples = is_unsubmitted
329    can_delete_samples = not adding_new_samples and request.samples and ( ( is_admin and not is_complete ) or is_unsubmitted )
330    can_edit_samples = request.samples and ( is_admin or not is_complete )
331    can_select_datasets = is_admin and displayable_sample_widgets and ( is_submitted or is_complete )
332    can_transfer_datasets = is_admin and request.samples and not request.is_rejected
333    display_checkboxes = not adding_new_samples and ( is_complete or is_rejected or is_submitted )
334    display_bar_code = request.samples and ( is_complete or is_rejected or is_submitted )
335    display_datasets = request.samples and ( is_complete or is_submitted )
336%>
337    ${grid_header}
338    %if render_buttons and ( can_add_samples or can_edit_samples ):
339        <ul class="manage-table-actions">
340            %if can_add_samples:
341                <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>
342            %endif
343            %if can_edit_samples:
344                <li><a class="action-button" href="${h.url_for( controller='requests_common', action='edit_samples', cntrller=cntrller, id=trans.security.encode_id( request.id ) )}">Edit samples</a></li>
345            %endif
346        </ul>
347    %endif
348    <table class="grid">
349        <thead>
350            <tr>
351                %if display_checkboxes:
352                    <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>
353                %endif
354                <th>Name</th>
355                %if display_bar_code:
356                    <th>Barcode</th>
357                %endif
358                <th>State</th>
359                <th>Data Library</th>
360                <th>Folder</th>
361                <th>History</th>
362                <th>Workflow</th>
363                %if display_datasets:
364                    <th>Run Datasets</th>
365                %endif
366                <th>
367                    %if can_delete_samples:
368                        Delete
369                    %endif
370                </th>
371            </tr>
372        <thead>
373        <tbody>
374            <% trans.sa_session.refresh( request ) %>
375            ## displayable_sample_widgets is a dictionary whose keys are:
376            ## id, name, bar_code, library, folder, field_values, library_select_field, folder_select_field
377            ## A displayable_sample_widget will have an id == None if the widget's associated sample has not
378            ## yet been saved (i.e., the use clicked the "Add sample" button but has not yet clicked the
379            ## "Save" button.
380            %for sample_widget_index, sample_widget in enumerate( displayable_sample_widgets ):
381                <%
382                    sample_widget_name = sample_widget[ 'name' ]
383                    sample_widget_bar_code = sample_widget[ 'bar_code' ]
384                    sample_widget_library = sample_widget[ 'library' ]
385                    sample_widget_history = sample_widget[ 'history' ]
386                    sample_widget_workflow = sample_widget[ 'workflow' ]
387                    if sample_widget_library:
388                        if cntrller == 'requests':
389                            library_cntrller = 'library'
390                        elif is_admin:
391                            library_cntrller = 'library_admin'
392                        else:
393                            library_cntrller = None
394                    sample_widget_folder = sample_widget[ 'folder' ]
395                    try:
396                        sample = request.samples[ sample_widget_index ]
397                    except:
398                        sample = None 
399                %>
400                %if not adding_new_samples:
401                    <tr>${render_editable_sample_row( cntrller, request, sample, sample_widget_index, sample_widget, encoded_selected_sample_ids, adding_new_samples=False )}</tr>
402                %elif sample:
403                    <tr>
404                        <td>
405                            %if sample.state and ( can_select_datasets or can_transfer_datasets ):
406                                ## A sample will have a state only after the request has been submitted.
407                                <%
408                                    encoded_id = trans.security.encode_id( sample.id )
409                                    transferred_dataset_files = sample.transferred_dataset_files
410                                    if not transferred_dataset_files:
411                                        transferred_dataset_files = []
412                                %>
413                                <div style="float: left; margin-left: 2px;" class="menubutton split popup" id="sample-${sample.id}-popup">
414                                    <a class="view-info" href="${h.url_for( controller='requests_common', action='view_sample', cntrller=cntrller, id=trans.security.encode_id( sample.id ) )}">${sample.name}</a>
415                                </div>
416                                <div popupmenu="sample-${sample.id}-popup">
417                                    %if can_select_datasets:
418                                        %for external_service in sample.request.type.get_external_services_for_manual_data_transfer( trans ):
419                                            <%
420                                                menu_item_label = "Select datasets to transfer using %s" % external_service.name
421                                            %>
422                                            <li><a class="action-button" href="${h.url_for( controller='requests_admin', action='select_datasets_to_transfer', external_service_id=trans.security.encode_id( external_service.id ), request_id=trans.security.encode_id( request.id ), sample_id=trans.security.encode_id( sample.id ) )}">${menu_item_label}</a></li>
423                                        %endfor
424                                    %endif
425                                    %if sample.datasets and len( sample.datasets ) > len( transferred_dataset_files ) and sample.library and sample.folder:
426                                        <li><a class="action-button" href="${h.url_for( controller='requests_admin', action='manage_datasets', sample_id=trans.security.encode_id( sample.id ) )}">Manage selected datasets</a></li>
427                                    %elif sample.datasets and len(sample.datasets ) == len( transferred_dataset_files ):
428                                        <li><a class="action-button" href="${h.url_for( controller='requests_common', action='view_sample_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ), transfer_status=trans.model.SampleDataset.transfer_status.COMPLETE )}">View transferred datasets</a></li>
429                                    %endif
430                                </div>
431                            %else:
432                                ${sample_widget_name}
433                            %endif
434                        </td>
435                        %if display_bar_code:
436                            <td>${sample_widget_bar_code}</td>
437                        %endif
438                        %if is_unsubmitted:
439                            <td>Unsubmitted</td>
440                        %else:
441                            <td><a id="sampleState-${sample.id}" href="${h.url_for( controller='requests_common', action='view_sample_history', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${render_sample_state( sample )}</a></td>
442                        %endif
443                        %if sample_widget_library and library_cntrller is not None:
444                            <td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller=library_cntrller, id=trans.security.encode_id( sample_widget_library.id ) )}">${sample_widget_library.name}</a></td>                                  
445                        %else:
446                            <td></td>
447                        %endif
448                        %if sample_widget_folder:
449                            <td>${sample_widget_folder.name}</td>
450                        %else:
451                            <td></td>
452                        %endif
453                        %if sample_widget_history:
454                            %if trans.user == sample_widget_history.user:
455                                <td>
456                                    <a target='_parent' href="${h.url_for( controller='history', action='list', operation="Switch", id=trans.security.encode_id(sample_widget_history.id), use_panels=False )}">
457                                    ${sample_widget_history.name}
458                                    </a>
459                                </td>
460                            %else:
461                                <td>${sample_widget_history.name}</td>
462                            %endif
463                        %else:
464                            <td></td>
465                        %endif
466                        %if sample_widget_workflow:
467                            %if trans.user == sample_widget_workflow.stored_workflow.user:
468                                <td>
469                                    <a target='_parent' href="${h.url_for( controller='workflow', action='editor', id=trans.security.encode_id(sample_widget_workflow.stored_workflow.id) )}">
470                                    ${sample_widget_workflow.name}
471                                    </a>
472                                </td>
473                            %else:
474                                <td>${sample_widget_workflow.name}</td>
475                            %endif
476                        %else:
477                            <td></td>
478                        %endif
479                        %if is_submitted or is_complete:
480                            <td>
481                                ## An admin can select the datasets to transfer, while a non-admin can only view what has been selected
482                                %if sample.library and is_admin:
483                                    ## This link will direct the admin to a page allowing them to manage datasets.
484                                    <a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_admin', action='manage_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.datasets )}</a>
485                                %elif sample.library and sample.datasets:
486                                    ## Since this is a regular user, only display a link if there is at least 1
487                                    ## selected dataset for the sample.
488                                    <a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_common', action='view_sample_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.datasets )}</a>
489                                %else:
490                                    ## Since this is a regular user, do not display a link if there are no datasets.
491                                    <a id="sampleDatasets-${sample.id}">${len( sample.datasets )}</a>
492                                %endif
493                            </td>
494                        %endif
495                    </tr>
496                %else:
497                    ## The Add sample button was clicked for this sample_widget
498                    <tr>${render_editable_sample_row( cntrller, request, None, sample_widget_index, sample_widget, encoded_selected_sample_ids, adding_new_samples=True )}</tr>
499                %endif
500            %endfor
501        </tbody>
502    </table>
503</%def>
504
505<%def name="render_sample_form( index, sample_name, sample_values, fields_dict, display_only )">
506    <tr>
507        <td>${sample_name}</td>
508        %for field_index, field in fields_dict.items():
509            <% 
510                field_type = field[ 'type' ]
511                field_name = field[ 'name' ]
512                field_value = sample_values[ field_name ]
513            %>
514            <td>
515                %if display_only:
516                    %if field_value:
517                        %if field_type == 'WorkflowField':
518                            %if str( field_value ) != 'none':
519                                <% workflow = trans.sa_session.query( trans.app.model.StoredWorkflow ).get( int( field_value ) ) %>
520                                <a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id( workflow.id ) )}">${workflow.name}</a>
521                            %endif
522                        %else:
523                            ${field_value}
524                        %endif
525                    %else:
526                        <i>None</i>
527                    %endif
528                %else:
529                    %if field_type == 'TextField':
530                        <input type="text" name="sample_${index}_field_${field_index}" value="${field_value}" size="7"/>
531                    %elif field_type == 'SelectField':
532                        <select name="sample_${index}_field_${field_index}" last_selected_value="2">
533                            %for option_index, option in enumerate(field[ 'selectlist' ]):
534                                %if option == field_value:
535                                    <option value="${option}" selected>${option}</option>
536                                %else:
537                                    <option value="${option}">${option}</option>
538                                %endif
539                            %endfor
540                        </select>
541                    %elif field_type == 'WorkflowField':
542                        <select name="sample_${index}_field_${field_index}">
543                            %if str( field_value ) == 'none':
544                                <option value="none" selected>Select one</option>
545                            %else:
546                                <option value="none">Select one</option>
547                            %endif
548                            %for option_index, option in enumerate(request.user.stored_workflows):
549                                %if not option.deleted:
550                                    %if str( option.id ) == str( field_value ):
551                                        <option value="${option.id}" selected>${option.name}</option>
552                                    %else:
553                                        <option value="${option.id}">${option.name}</option>
554                                    %endif
555                                %endif
556                            %endfor
557                        </select>
558                    %elif field_type == 'WorkflowMappingField':
559                        ##DBTODO Make this useful, use form_builder approach to displaying this stuff.
560                        <select name="sample_${index}_field_${field_index}">
561                            %if str( field_value ) == 'none':
562                                <option value="none" selected>Select one</option>
563                            %else:
564                                <option value="none">Select one</option>
565                            %endif
566                            %for option_index, option in enumerate(request.user.stored_workflows):
567                                %if not option.deleted:
568                                    %if str( option.id ) == str( field_value ):
569                                        <option value="${option.id}" selected>${option.name}</option>
570                                    %else:
571                                        <option value="${option.id}">${option.name}</option>
572                                    %endif
573                                %endif
574                            %endfor
575                        </select>
576                    %elif field_type == 'HistoryField':
577                        <select name="sample_${index}_field_${field_index}">
578                            %if str( field_value ) == 'none':
579                                <option value="none" selected>Select one</option>
580                            %else:
581                                <option value="none">Select one</option>
582                            %endif
583                            %for option_index, option in enumerate(request.user.histories):
584                                %if not option.deleted:
585                                    %if str( option.id ) == str( field_value ):
586                                        <option value="${option.id}" selected>${option.name}</option>
587                                    %else:
588                                        <option value="${option.id}">${option.name}</option>
589                                    %endif
590                                %endif
591                            %endfor
592                        </select>
593                    %elif field_type == 'CheckboxField':
594                        %if field_value is True:
595                            <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes" checked="checked"/><input type="hidden" name="sample_${index}_field_${field_index}" value="Yes"/>
596                        %else:
597                            <input type="checkbox" name="sample_${index}_field_${field_index}" value="Yes"/><input type="hidden" name="sample_${index}_field_${field_index}" value="Yes"/>
598                        %endif
599                    %endif
600                    <div class="toolParamHelp" style="clear: both;">
601                        <i>${'('+field['required']+')' }</i>
602                    </div>
603                %endif
604            </td>
605        %endfor
606    </tr> 
607</%def>
608
609<%def name="render_request_type_sample_form_grids( grid_index, grid_name, fields_dict, displayable_sample_widgets, show_saved_samples_read_only )">
610    <%
611        if not grid_name:
612            grid_name = "Sample form layout %s" % str( grid_index )
613    %>
614    <h4><img src="/static/images/silk/resultset_next.png" alt="Hide" onclick="showContent(this);" style="cursor:pointer;"/> ${grid_name}</h4>
615    <div style="display:none;">
616        <table class="grid">
617            <thead>
618                <tr>
619                    <th>Name</th>
620                    %for index, field in fields_dict.items():
621                        <th>
622                            <a class="display tooltip" title="${field['helptext']}" >${field['label']}</a>
623                        </th>
624                    %endfor
625                    <th></th>
626                </tr>
627            <thead>
628            <tbody>
629                <% trans.sa_session.refresh( request ) %>
630                %for sample_index, sample in enumerate( displayable_sample_widgets ):
631                    <%
632                        if not show_saved_samples_read_only or sample_index >= len( request.samples ):
633                            display_only = False
634                        else:
635                            display_only = True
636                    %>
637                    ${render_sample_form( sample_index, sample['name'], sample['field_values'], fields_dict, display_only )}    
638                %endfor
639            </tbody>
640        </table>
641    </div>
642</%def>
643
644<%def name="render_sample_datasets( cntrller, sample, sample_datasets, title )">
645    ## The list of sample_datasets may not be the same as sample.datasets because it may be
646    ## filtered by a transfer_status value.  The value of title changes based on this filter.
647    %if sample_datasets:
648        <%
649            trans.sa_session.refresh( sample )
650            is_admin = cntrller == 'requests_admin' and trans.user_is_admin()
651            is_complete = sample.request.is_complete
652            is_submitted = sample.request.is_submitted
653            can_select_datasets = is_admin and ( is_complete or is_submitted )
654            can_transfer_datasets = is_admin and sample.untransferred_dataset_files
655        %>
656        ## The transfer status should update only when the request has been submitted or complete
657        ## and when the sample has in-progress datasets.
658        %if ( is_complete or is_submitted ) and sample.inprogress_dataset_files: 
659            <script type="text/javascript">
660                // Sample dataset transfer status updater
661                dataset_transfer_status_updater( {${ ",".join( [ '"%s" : "%s"' % ( trans.security.encode_id( sd.id ), sd.status ) for sd in sample_datasets ] ) }});
662            </script>
663        %endif
664        <h3>${title}</h3>
665        <table class="grid">
666            <thead>
667                <tr>
668                    <th>Name</th>
669                    <th>Size</th>
670                    <th>Data library</th>
671                    <th>Folder</th>
672                    <th>Transfer status</th>
673                </tr>
674            <thead>
675            <tbody>
676                %for dataset in sample_datasets:
677                    <% encoded_id = trans.security.encode_id( dataset.id ) %>
678                    <tr>
679                        <td>
680                            %if is_admin:
681                                <span class="expandLink dataset-${dataset}-click"><span class="rowIcon"></span>
682                                    <div style="float: left; margin-left: 2px;" class="menubutton split popup" id="dataset-${dataset.id}-popup">
683                                        <a class="dataset-${encoded_id}-click" href="${h.url_for( controller='requests_admin', action='manage_datasets', operation='view', id=trans.security.encode_id( dataset.id ) )}">${dataset.name}</a>
684                                    </div>
685                                </span>
686                                <div popupmenu="dataset-${dataset.id}-popup">
687                                    %if can_transfer_datasets and dataset in sample.untransferred_dataset_files:
688                                        <li><a class="action-button" href="${h.url_for( controller='requests_admin', action='initiate_data_transfer', sample_id=trans.security.encode_id( sample.id ), sample_dataset_id=trans.security.encode_id( dataset.id ) )}">Transfer</a></li>
689                                    %endif
690                                </div>
691                            %else:
692                                ${dataset.name}
693                            %endif
694                        </td>
695                        <td>${dataset.size}</td>
696                        <td><a href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=trans.security.encode_id( sample.library.id ) )}">${dataset.sample.library.name}</a></td>
697                        <td>${dataset.sample.folder.name}</td>
698                        <td id="datasetTransferStatus-${encoded_id}">${dataset.status}</td>
699                    </tr>
700                %endfor
701            </tbody>
702        </table>
703    %else:
704        No datasets for this sample.
705    %endif
706</%def>
707
708<%def name="render_samples_messages( request, is_admin=False, is_submitted=False, message=None, status=None)">
709    %if request.is_rejected:
710        <div class='errormessage'>
711            ${request.last_comment}
712        </div><br/>
713    %endif
714    %if is_admin and is_submitted and request.samples_without_library_destinations:
715        <div class='infomessage'>
716            Select a target data library and folder for a sample before selecting it's datasets to transfer from the external service.
717        </div><br/>
718    %endif
719    %if message:
720        ${render_msg( message, status )}
721    %endif
722</%def>