# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User rc # Date 1283200417 14400 # Node ID 667fb4f9cd16237bb74b15c13e7ff5f166a89177 # Parent 651228876e99e39af9c2f0cef70f8d60780f2b71 lims: added basic UI framework for operations on multiple samples - first pass for state change mechanism for multiple samples - UI enhancements: checkboxes to select samples & selectfield to select specific operation - removed state change UI for individual samples in the sample_events page next is selecting library for multiple samples --- a/scripts/galaxy_messaging/server/galaxyweb_interface.py +++ b/scripts/galaxy_messaging/server/galaxyweb_interface.py @@ -106,11 +106,10 @@ class GalaxyWebInterface(object): # Encrypt return id_cipher.encrypt( s ).encode( 'hex' ) - def update_request_state(self, request_id, sample_id): + def update_request_state(self, request_id): params = urllib.urlencode(dict( cntrller='requests_admin', - request_id=request_id, - sample_id=sample_id)) - url = self.base_url + "/requests_admin/update_request_state" + request_id=request_id)) + url = self.base_url + "/requests_common/update_request_state" f = self.opener.open(url, params) print url print params --- a/scripts/galaxy_messaging/server/amqp_consumer.py +++ b/scripts/galaxy_messaging/server/amqp_consumer.py @@ -108,7 +108,7 @@ def recv_callback(msg): webconfig.get("data_transfer_user_login_info", "email"), webconfig.get("data_transfer_user_login_info", "password"), config.get("app:main", "id_secret")) - galaxyweb.update_request_state(galaxydb.get_request_id(sample_id), sample_id) + galaxyweb.update_request_state(galaxydb.get_request_id(sample_id)) galaxyweb.logout() def main(): --- a/templates/requests/common/sample_events.mako +++ b/templates/requests/common/sample_events.mako @@ -45,28 +45,3 @@ </tbody></table></div> -%if cntrller == 'requests_admin' and trans.user_is_admin(): - <div class="toolForm"> - <div class="toolFormTitle">Change current state</div> - <div class="toolFormBody"> - <form name="event" action="${h.url_for( controller='requests_admin', action='save_state', new=True, sample_id=sample.id)}" method="post" > - %for w in widgets: - <div class="form-row"> - <label> - ${w[0]} - </label> - ${w[1].get_html()} - %if w[0] == 'Comments': - <div class="toolParamHelp" style="clear: both;"> - Optional - </div> - %endif - </div> - %endfor - <div class="form-row"> - <input type="submit" name="add_event_button" value="Save"/> - </div> - </form> - </div> - </div> -%endif --- a/test/functional/test_forms_and_requests.py +++ b/test/functional/test_forms_and_requests.py @@ -301,8 +301,8 @@ class TestFormsAndRequests( TwillTestCas self.add_bar_codes( request_one.id, request_one.name, bar_codes, request_one.samples ) # change the states of all the samples of this request for sample in request_one.samples: - self.change_sample_state( sample.name, sample.id, request_type.states[1].id, request_type.states[1].name ) - self.change_sample_state( sample.name, sample.id, request_type.states[2].id, request_type.states[2].name ) + self.change_sample_state( request_one.id, request_one.name, sample.name, sample.id, request_type.states[1].id, request_type.states[1].name ) + self.change_sample_state( request_one.id, request_one.name, sample.name, sample.id, request_type.states[2].id, request_type.states[2].name ) self.home() sa_session.refresh( request_one ) self.logout() --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -1629,6 +1629,7 @@ All samples in state: %(sample_state event = trans.app.model.RequestEvent(self, self.state(), comments) trans.sa_session.add(event) trans.sa_session.flush() + return comments class RequestEvent( object ): def __init__(self, request=None, request_state=None, comment=''): @@ -1651,6 +1652,28 @@ class RequestType( object ): self.datatx_info = datatx_info def last_state(self): return self.states[-1] + + def change_state_widgets(self, trans, sample=None): + if sample: + curr_state = sample.current_state() + else: + curr_state = self.states[0] + states_input = SelectField('select_state') + for state in self.states: + if curr_state.name == state.name: + states_input.add_option(state.name, state.id, selected=True) + else: + states_input.add_option(state.name, state.id) + widgets = [] + if sample: + widgets.append(('Select the new state of the sample from the list of possible state(s)', + states_input)) + else: + widgets.append(('Select the new state of the selected sample(s) from the list of possible state(s)', + states_input)) + widgets.append(('Comments', TextArea('comment'))) + title = 'Change current state' + return widgets, title class RequestTypePermissions( object ): def __init__( self, action, request_type, role ): @@ -1659,6 +1682,8 @@ class RequestTypePermissions( object ): self.role = role class Sample( object ): + bulk_operations = Bunch(CHANGE_STATE = 'Change state', + SELECT_LIBRARY = 'Select data library and folder') transfer_status = Bunch( NOT_STARTED = 'Not started', IN_QUEUE = 'In queue', TRANSFERRING = 'Transferring dataset', --- a/lib/galaxy/web/controllers/requests_common.py +++ b/lib/galaxy/web/controllers/requests_common.py @@ -515,7 +515,7 @@ class RequestsCommon( BaseController, Us @web.require_login( "create/submit sequencing requests" ) def events(self, trans, **kwd): params = util.Params( kwd ) - cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + cntrller = params.get( 'cntrller', 'requests' ) try: request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) except: @@ -533,21 +533,63 @@ class RequestsCommon( BaseController, Us cntrller=cntrller, events_list=events_list, request=request) @web.expose - @web.require_login( "create/submit sequencing requests" ) - def settings(self, trans, **kwd): + @web.require_admin + def update_request_state( self, trans, **kwd ): params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) cntrller = params.get( 'cntrller', 'requests' ) try: - request = trans.sa_session.query( trans.app.model.Request ).get( trans.security.decode_id(kwd['id']) ) + request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) except: + return trans.response.send_redirect( web.url_for( controller='requests_admin', + action='list', + status='error', + message="Invalid request ID", + **kwd) ) + # check if all the samples of the current request are in the sample state + common_state = request.common_state() + if not common_state: + # if the current request state is complete and one of its samples moved from + # the final sample state, then move the request state to In-progress + if request.complete(): + status='done' + message = "One or more samples' state moved from the final sample state. Now request in '%s' state" % request.states.SUBMITTED + event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, message) + trans.sa_session.add( event ) + trans.sa_session.flush() + else: + message = '' + status = 'ok' return trans.response.send_redirect( web.url_for( controller=cntrller, action='list', - status='error', - message="Invalid request ID") ) - return trans.fill_template( '/requests/common/settings.mako', - cntrller=cntrller, request=request) - + operation='show', + id=trans.security.encode_id(request.id), + status=status, + message=message ) ) + final_state = False + if common_state.id == request.type.last_state().id: + # since all the samples are in the final state, change the request state to 'Complete' + comments = "All samples of this request are in the last sample state (%s). " % request.type.last_state().name + state = request.states.COMPLETE + final_state = True + else: + comments = "All samples are in %s state. " % common_state.name + state = request.states.SUBMITTED + event = trans.app.model.RequestEvent(request, state, comments) + trans.sa_session.add( event ) + trans.sa_session.flush() + # check if an email notification is configured to be sent when the samples + # are in this state + retval = request.send_email_notification(trans, common_state, final_state) + if retval: + message = comments + retval + else: + message = comments + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id), + status='done', + message=message ) ) @web.expose @web.require_login( "create/submit sequencing requests" ) def show(self, trans, **kwd): @@ -588,9 +630,10 @@ class RequestsCommon( BaseController, Us folder_widget=folder_widget)) return trans.fill_template( '/requests/common/show_request.mako', cntrller=cntrller, - request=request, + request=request, selected_samples=[], request_details=self.request_details(trans, request.id), current_samples=current_samples, + sample_ops=self.__sample_operation_selectbox(trans, request, **kwd), sample_copy=self.__copy_sample(current_samples), details='hide', edit_mode=util.restore_text( params.get( 'edit_mode', 'False' ) ), message=message, status=status ) @@ -663,7 +706,7 @@ class RequestsCommon( BaseController, Us else: break return current_samples, details, edit_mode, libraries - + def __library_widgets(self, trans, user, sample_index, libraries, sample=None, lib_id=None, folder_id=None, **kwd): ''' This method creates the data library & folder selectbox for creating & @@ -736,7 +779,6 @@ class RequestsCommon( BaseController, Us else: folder_widget.add_option(f.name, f.id) return lib_widget, folder_widget - def __copy_sample(self, current_samples): copy_list = SelectField('copy_sample') copy_list.add_option('None', -1, selected=True) @@ -744,6 +786,44 @@ class RequestsCommon( BaseController, Us copy_list.add_option(s['name'], i) return copy_list + def __sample_operation_selectbox(self, trans, request, **kwd): + params = util.Params( kwd ) + cntrller = util.restore_text( params.get( 'cntrller', 'requests' ) ) + if cntrller == 'requests_admin' and trans.user_is_admin(): + if request.complete(): + bulk_operations = [trans.app.model.Sample.bulk_operations.CHANGE_STATE] + if request.rejected(): + bulk_operations = [trans.app.model.Sample.bulk_operations.SELECT_LIBRARY] + else: + bulk_operations = [s for i, s in trans.app.model.Sample.bulk_operations.items()] + else: + if request.complete(): + bulk_operations = [] + else: + bulk_operations = [trans.app.model.Sample.bulk_operations.SELECT_LIBRARY] + op_list = SelectField('select_sample_operation', + refresh_on_change=True, + refresh_on_change_values=bulk_operations) + sel_op = kwd.get('select_sample_operation', 'none') + if sel_op == 'none': + op_list.add_option('Select operation', 'none', True) + else: + op_list.add_option('Select operation', 'none') + for s in bulk_operations: + if s == sel_op: + op_list.add_option(s, s, True) + else: + op_list.add_option(s, s) + return op_list + + def __selected_samples(self, trans, request, **kwd): + params = util.Params( kwd ) + selected_samples = [] + for s in request.samples: + if CheckboxField.is_checked(params.get('select_sample_%i' % s.id, '')): + selected_samples.append(s.id) + return selected_samples + @web.expose @web.require_login( "create/submit sequencing requests" ) def request_page(self, trans, **kwd): @@ -760,6 +840,15 @@ class RequestsCommon( BaseController, Us message="Invalid request ID") ) # get the user entered sample details current_samples, details, edit_mode, libraries = self.__update_samples( trans, request, **kwd ) + selected_samples = self.__selected_samples(trans, request, **kwd) + sample_ops = self.__sample_operation_selectbox(trans, request,**kwd) + if params.get('select_sample_operation', 'none') != 'none' and not len(selected_samples): + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id), + status='error', + message='Select at least one sample before selecting an operation.' )) if params.get('import_samples_button', False) == 'Import samples': return self.__import_samples(trans, cntrller, request, current_samples, details, libraries, **kwd) elif params.get('add_sample_button', False) == 'Add New': @@ -805,7 +894,8 @@ class RequestsCommon( BaseController, Us request_details=self.request_details(trans, request.id), current_samples=current_samples, sample_copy=self.__copy_sample(current_samples), - details=details, + details=details, selected_samples=selected_samples, + sample_ops=sample_ops, edit_mode=edit_mode) elif params.get('save_samples_button', False) == 'Save': # check for duplicate sample names @@ -826,11 +916,12 @@ class RequestsCommon( BaseController, Us if message: return trans.fill_template( '/requests/common/show_request.mako', cntrller=cntrller, - request=request, + request=request, selected_samples=selected_samples, request_details=self.request_details(trans, request.id), current_samples = current_samples, sample_copy=self.__copy_sample(current_samples), details=details, edit_mode=edit_mode, + sample_ops=sample_ops, status='error', message=message) # save all the new/unsaved samples entered by the user if edit_mode == 'False': @@ -899,10 +990,11 @@ class RequestsCommon( BaseController, Us edit_mode = 'True' return trans.fill_template( '/requests/common/show_request.mako', cntrller=cntrller, - request=request, + request=request, selected_samples=selected_samples, request_details=self.request_details(trans, request.id), current_samples=current_samples, sample_copy=self.__copy_sample(current_samples), + sample_ops=sample_ops, details=details, libraries=libraries, edit_mode=edit_mode) elif params.get('cancel_changes_button', False) == 'Cancel': @@ -910,14 +1002,33 @@ class RequestsCommon( BaseController, Us action='list', operation='show', id=trans.security.encode_id(request.id)) ) + elif params.get('change_state_button', False) == 'Save': + comments = util.restore_text( params.comment ) + selected_state = int( params.select_state ) + new_state = trans.sa_session.query( trans.app.model.SampleState ).get( selected_state ) + for sample_id in selected_samples: + sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id ) + event = trans.app.model.SampleEvent(sample, new_state, comments) + trans.sa_session.add( event ) + trans.sa_session.flush() + return trans.response.send_redirect( web.url_for( controller='requests_common', + cntrller=cntrller, + action='update_request_state', + request_id=request.id )) + elif params.get('change_state_button', False) == 'Cancel': + return trans.response.send_redirect( web.url_for( controller=cntrller, + action='list', + operation='show', + id=trans.security.encode_id(request.id)) ) else: return trans.fill_template( '/requests/common/show_request.mako', - cntrller=cntrller, - request=request, + cntrller=cntrller, + request=request, selected_samples=selected_samples, request_details=self.request_details(trans, request.id), current_samples=current_samples, sample_copy=self.__copy_sample(current_samples), details=details, libraries=libraries, + sample_ops=sample_ops, edit_mode=edit_mode, status=status, message=message) def __import_samples(self, trans, cntrller, request, current_samples, details, libraries, **kwd): @@ -1014,21 +1125,12 @@ class RequestsCommon( BaseController, Us trans.sa_session.delete( s.values ) trans.sa_session.delete( s ) trans.sa_session.flush() - del current_samples[sample_index] return trans.response.send_redirect( web.url_for( controller=cntrller, action='list', operation='show', id=trans.security.encode_id(request.id), status='done', message='Sample <b>%s</b> has been deleted.' % sample_name )) - return trans.fill_template( '/requests/common/show_request.mako', - controller=cntrller, - request=request, - request_details=self.request_details(trans, request.id), - current_samples = current_samples, - sample_copy=self.__copy_sample(current_samples), - details=details, - edit_mode=edit_mode) def request_details(self, trans, id): ''' Shows the request details @@ -1087,11 +1189,10 @@ class RequestsCommon( BaseController, Us events_list.append((event.state.name, event.state.desc, time_ago(event.update_time), event.comment)) - widgets, title = self.__change_state_widgets(trans, sample) return trans.fill_template( '/requests/common/sample_events.mako', cntrller=cntrller, events_list=events_list, - sample=sample, widgets=widgets, title=title) + sample=sample) def __change_state_widgets(self, trans, sample): possible_states = sample.request.type.states curr_state = sample.current_state() --- a/lib/galaxy/web/controllers/requests_admin.py +++ b/lib/galaxy/web/controllers/requests_admin.py @@ -321,8 +321,6 @@ class RequestsAdmin( BaseController, Use return self.__reject_request( trans, **kwd ) elif operation == "view_type": return self.__view_request_type( trans, **kwd ) - elif operation == "upload_datasets": - return self.__upload_datasets( trans, **kwd ) # Render the grid view return self.request_grid( trans, **kwd ) @@ -399,191 +397,6 @@ class RequestsAdmin( BaseController, Use action='list', status='done', message='Request <b>%s</b> has been rejected.' % request.name) ) - - def __upload_datasets(self, trans, **kwd): - return trans.fill_template( '/admin/requests/upload_datasets.mako' ) - - - @web.expose - @web.require_admin - def bar_codes(self, trans, **kwd): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - request_id = params.get( 'request_id', None ) - if request_id: - request = trans.sa_session.query( trans.app.model.Request ).get( int( request_id )) - if not request: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - widgets = [] - for index, sample in enumerate(request.samples): - if sample.bar_code: - bc = sample.bar_code - else: - bc = util.restore_text(params.get('sample_%i_bar_code' % index, '')) - widgets.append(TextField('sample_%i_bar_code' % index, - 40, - bc)) - return trans.fill_template( '/admin/samples/bar_codes.mako', - samples_list=[s for s in request.samples], - user=request.user, request=request, widgets=widgets, - status=status, - message=message) - @web.expose - @web.require_admin - def save_bar_codes(self, trans, **kwd): - params = util.Params( kwd ) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - # validate - # bar codes need to be globally unique - message = '' - for index in range(len(request.samples)): - bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, '')) - # check for empty bar code - if not bar_code.strip(): - message = 'Please fill the barcode for sample <b>%s</b>.' % request.samples[index].name - break - # check all the unsaved bar codes - count = 0 - for i in range(len(request.samples)): - if bar_code == util.restore_text(params.get('sample_%i_bar_code' % i, '')): - count = count + 1 - if count > 1: - message = '''The barcode <b>%s</b> of sample <b>%s</b> belongs - another sample in this request. The sample barcodes must - be unique throughout the system''' % \ - (bar_code, request.samples[index].name) - break - # check all the saved bar codes - all_samples = trans.sa_session.query( trans.app.model.Sample ) - for sample in all_samples: - if bar_code == sample.bar_code: - message = '''The bar code <b>%s</b> of sample <b>%s</b> - belongs another sample. The sample bar codes must be - unique throughout the system''' % \ - (bar_code, request.samples[index].name) - break - if message: - break - if message: - widgets = [] - for index, sample in enumerate(request.samples): - if sample.bar_code: - bc = sample.bar_code - else: - bc = util.restore_text(params.get('sample_%i_bar_code' % index, '')) - widgets.append(TextField('sample_%i_bar_code' % index, - 40, - util.restore_text(params.get('sample_%i_bar_code' % index, '')))) - return trans.fill_template( '/admin/samples/bar_codes.mako', - samples_list=[s for s in request.samples], - user=request.user, request=request, widgets=widgets, status='error', - message=message) - # now save the bar codes - for index, sample in enumerate(request.samples): - bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, '')) - sample.bar_code = bar_code - trans.sa_session.add( sample ) - trans.sa_session.flush() - # change the state of all the samples to the next state - # get the new state - new_state = request.type.states[1] - for s in request.samples: - event = trans.app.model.SampleEvent(s, new_state, 'Bar code added to this sample') - trans.sa_session.add( event ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='show_request', - id=trans.security.encode_id(request.id), - message='Bar codes have been saved for this request', - status='done')) - @web.expose - @web.require_admin - def update_request_state( self, trans, **kwd ): - params = util.Params( kwd ) - try: - request = trans.sa_session.query( trans.app.model.Request ).get( int( params.get( 'request_id', None ) ) ) - sample_id = int(params.get('sample_id', False)) - except: - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message="Invalid request ID", - **kwd) ) - # check if all the samples of the current request are in the sample state - common_state = request.common_state() - if not common_state: - # if the current request state is complete and one of its samples moved from - # the final sample state, then move the request state to In-progress - if request.complete(): - event = trans.app.model.RequestEvent(request, request.states.SUBMITTED, "One or more samples' state moved from the final sample state.") - trans.sa_session.add( event ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests_common', - cntrller='requests_admin', - action='sample_events', - sample_id=sample_id)) - final_state = False - if common_state.id == request.type.last_state().id: - # since all the samples are in the final state, change the request state to 'Complete' - comments = "All samples of this request are in the last sample state (%s)." % request.type.last_state().name - state = request.states.COMPLETE - final_state = True - else: - comments = "All samples are in %s state." % common_state.name - state = request.states.SUBMITTED - event = trans.app.model.RequestEvent(request, state, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - # check if an email notification is configured to be sent when the samples - # are in this state -# if common_state.id in request.notification['sample_states']: - request.send_email_notification(trans, common_state, final_state) - return trans.response.send_redirect( web.url_for( controller='requests_common', - cntrller='requests_admin', - action='sample_events', - sample_id=sample_id)) - - @web.expose - @web.require_admin - def save_state(self, trans, **kwd): - params = util.Params( kwd ) - try: - sample_id = int(params.get('sample_id', False)) - sample = trans.sa_session.query( trans.app.model.Sample ).get( sample_id ) - except: - message = "Invalid sample ID" - return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - status='error', - message=message, - **kwd) ) - comments = util.restore_text( params.comment ) - selected_state = int( params.select_state ) - new_state = trans.sa_session.query( trans.app.model.SampleState ) \ - .filter( and_( trans.app.model.SampleState.table.c.request_type_id == sample.request.type.id, - trans.app.model.SampleState.table.c.id == selected_state ) ) \ - .first() - event = trans.app.model.SampleEvent(sample, new_state, comments) - trans.sa_session.add( event ) - trans.sa_session.flush() - return trans.response.send_redirect( web.url_for( controller='requests_admin', - cntrller='requests_admin', - action='update_request_state', - request_id=sample.request.id, - sample_id=sample.id)) # # Data transfer from sequencer # --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -1562,13 +1562,17 @@ class TwillTestCase( unittest.TestCase ) self.check_page_for_string( 'Changes made to the sample(s) are saved.' ) for index, bar_code in enumerate(bar_codes): self.check_page_for_string( bar_code ) - def change_sample_state( self, sample_name, sample_id, new_state_id, new_state_name, comment='' ): + def change_sample_state( self, request_id, request_name, sample_name, sample_id, new_state_id, new_state_name, comment='' ): self.home() + url = "%s/requests/list?operation=show&id=%s" % ( self.url, self.security.encode_id( request_id ) ) + self.visit_url( url ) + self.check_page_for_string( 'Sequencing Request "%s"' % request_name ) + url = "%s/requests_common/request_page?cntrller=requests_admin&edit_mode=False&id=%s&comment=%s&change_state_button=Save&select_sample_operation=%s&refresh=true&select_sample_%i=true&select_sample_%i=true&select_state=%i" % \ + (self.url, self.security.encode_id( request_id ), comment, "Change%20state", sample_id, sample_id, new_state_id ) + self.visit_url( url ) + self.check_page_for_string( 'Sequencing Request "%s"' % request_name ) self.visit_url( "%s/requests_common/sample_events?cntrller=requests_admin&sample_id=%i" % (self.url, sample_id) ) self.check_page_for_string( 'Events for Sample "%s"' % sample_name ) - tc.fv( "1", "select_state", str(new_state_id) ) - tc.fv( "1", "comment", comment ) - tc.submit( "add_event_button" ) self.check_page_for_string( new_state_name ) def add_user_address( self, user_id, address_dict ): self.home() --- a/templates/requests/common/show_request.mako +++ b/templates/requests/common/show_request.mako @@ -113,6 +113,36 @@ function showContent(vThis) } }); }; + + 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><style type="text/css"> @@ -261,6 +291,40 @@ function showContent(vThis) %if current_samples: ## first render the basic info grid ${render_basic_info_grid()} + %if not request.new() and edit_mode == 'False' and len(sample_ops.options) > 1: + <div class="form-row" style="background-color:#FAFAFA;"> + For selected sample(s): + ${sample_ops.get_html()} + </div> + %if 'none' not in sample_ops.get_selected() and len(selected_samples): + <div class="form-row" style="background-color:#FAFAFA;"> + %if trans.app.model.Sample.bulk_operations.CHANGE_STATE in sample_ops.get_selected(): + <% + widgets, title = request.type.change_state_widgets(trans) + %> + %for w in widgets: + <div class="form-row"> + <label> + ${w[0]}: + </label> + ${w[1].get_html()} + %if w[0] == 'Comments': + <div class="toolParamHelp" style="clear: both;"> + Optional + </div> + %endif + </div> + %endfor + <div class="form-row"> + <input type="submit" name="change_state_button" value="Save"/> + <input type="submit" name="change_state_button" value="Cancel"/> + </div> + %elif trans.app.model.Sample.bulk_operations.SELECT_LIBRARY in sample_ops.get_selected(): + ${current_samples[0]} + %endif + </div> + %endif + %endif ## then render the other grid(s) <% trans.sa_session.refresh( request.type.sample_form ) %> %for grid_index, grid_name in enumerate(request.type.sample_form.layout): @@ -407,6 +471,7 @@ function showContent(vThis) <table class="grid"><thead><tr> + <th><input type="checkbox" id="checkAll" name=select_all_samples value="true" onclick='checkAllFields(1);'><input type="hidden" name=select_all_samples value="true"></th><th>Name</th><th>Barcode</th><th>State</th> @@ -436,6 +501,11 @@ function showContent(vThis) %else: <tr> %if sample_index in range(len(request.samples)): + %if 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.unsubmitted(): @@ -486,6 +556,7 @@ function showContent(vThis) </%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;">