details: http://www.bx.psu.edu/hg/galaxy/rev/26b69d176146 changeset: 2496:26b69d176146 user: rc date: Thu Jul 23 17:08:21 2009 -0400 description: More LIMS changes - Request page now includes all its samples (both Admin & User perspective) - Sample page removed and samples UI overhaul - DB changes - new 'submitted' column in request table - new 'bar_code' column in sample table - CSV importer to create forms 34 file(s) affected in this change: lib/galaxy/model/__init__.py lib/galaxy/model/mapping.py lib/galaxy/model/migrate/versions/0009_request_table.py lib/galaxy/web/controllers/admin.py lib/galaxy/web/controllers/forms.py lib/galaxy/web/controllers/requests.py lib/galaxy/web/controllers/requests_admin.py templates/admin/forms/create_form.mako templates/admin/forms/edit_form.mako templates/admin/requests/add_states.mako templates/admin/requests/create_request_type.mako templates/admin/requests/edit_request_type.mako templates/admin/requests/grid.mako templates/admin/requests/show_request.mako templates/admin/requests/view_request.mako templates/admin/requests/view_request_type.mako templates/admin/samples/bar_codes.mako templates/admin/samples/change_state.mako templates/admin/samples/edit_sample.mako templates/admin/samples/events.mako templates/admin/samples/grid.mako templates/admin/samples/view_sample.mako templates/base.mako templates/base_panels.mako templates/requests/grid.mako templates/requests/new_request.mako templates/requests/show_request.mako templates/requests/view_request.mako templates/sample/browse_samples.mako templates/sample/edit_sample.mako templates/sample/grid.mako templates/sample/new_sample.mako templates/sample/sample_events.mako templates/sample/view_sample.mako diffs (2706 lines): diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py Thu Jul 23 14:31:11 2009 -0400 +++ b/lib/galaxy/model/__init__.py Thu Jul 23 17:08:21 2009 -0400 @@ -1116,16 +1116,40 @@ class Request( object ): def __init__(self, name=None, desc=None, request_type=None, user=None, - form_values=None, library=None): + form_values=None, library=None, submitted=False): self.name = name self.desc = desc self.type = request_type self.values = form_values self.user = user self.library = library + self.submitted = submitted + self.samples_list = [] + def add_sample(self, sample_name=None, sample_desc=None, sample_values=None): + # create a form_values row + values = trans.app.model.FormValues(self.type.sample_form, sample_values) + values.flush() + sample = Sample(sample_name, sample_desc, self, values) + sample.flush() + # set the initial state + state = self.type.states[0] + event = SampleEvent(sample, state) + event.flush() + # add this sample to the member array + self.samples_list.append(sample) + return sample + def delete_sample(self, sample_name): + pass + def has_sample(self, sample_name): + for s in self.samples: + if s.name == sample_name: + return s + return False class RequestType( object ): - def __init__(self, request_form=None, sample_form=None): + def __init__(self, name=None, desc=None, request_form=None, sample_form=None): + self.name = name + self.desc = desc self.request_form = request_form self.sample_form = sample_form @@ -1135,9 +1159,10 @@ self.desc = desc self.request = request self.values = form_values + + def current_state(self): + return self.events[0].state - - class SampleState( object ): def __init__(self, name=None, desc=None, request_type=None): self.name = name diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/model/mapping.py --- a/lib/galaxy/model/mapping.py Thu Jul 23 14:31:11 2009 -0400 +++ b/lib/galaxy/model/mapping.py Thu Jul 23 17:08:21 2009 -0400 @@ -569,6 +569,7 @@ Column( "request_type_id", Integer, ForeignKey( "request_type.id" ), index=True ), Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True ), Column( "library_id", Integer, ForeignKey( "library.id" ), index=True ), + Column( "submitted", Boolean, index=True, default=False ), Column( "deleted", Boolean, index=True, default=False ) ) Sample.table = Table('sample', metadata, @@ -579,6 +580,7 @@ Column( "desc", TEXT ), Column( "form_values_id", Integer, ForeignKey( "form_values.id" ), index=True ), Column( "request_id", Integer, ForeignKey( "request.id" ), index=True ), + Column( "bar_code", TrimmedString( 255 ), index=True ), Column( "deleted", Boolean, index=True, default=False ) ) # new table to store all the possible sample states and the sample type it @@ -626,13 +628,17 @@ user=relation( User, primaryjoin=( Request.table.c.user_id == User.table.c.id ), backref="requests" ), + samples=relation( Sample, + primaryjoin=( Request.table.c.id == Sample.table.c.request_id ) ), library=relation( Library, primaryjoin=( Request.table.c.library_id == Library.table.c.id ) ), ) ) assign_mapper( context, RequestType, RequestType.table, - properties=dict( states=relation( SampleState, backref="request_type", - order_by=desc(SampleState.table.c.update_time) ), + properties=dict( states=relation( SampleState, + backref="request_type", + primaryjoin=( RequestType.table.c.id == SampleState.table.c.request_type_id ), + order_by=asc(SampleState.table.c.update_time) ), request_form=relation( FormDefinition, primaryjoin=( RequestType.table.c.request_form_id == FormDefinition.table.c.id ) ), sample_form=relation( FormDefinition, diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/model/migrate/versions/0009_request_table.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/galaxy/model/migrate/versions/0009_request_table.py Thu Jul 23 17:08:21 2009 -0400 @@ -0,0 +1,52 @@ +from sqlalchemy import * +from sqlalchemy.orm import * +from migrate import * +from migrate.changeset import * +import sys, logging +from galaxy.model.custom_types import * + +log = logging.getLogger( __name__ ) +log.setLevel(logging.DEBUG) +handler = logging.StreamHandler( sys.stdout ) +format = "%(name)s %(levelname)s %(asctime)s %(message)s" +formatter = logging.Formatter( format ) +handler.setFormatter( formatter ) +log.addHandler( handler ) + +metadata = MetaData( migrate_engine ) + + +def upgrade(): + # Load existing tables + metadata.reflect() + + # Add 1 column to the request table + try: + Request_table = Table( "request", metadata, autoload=True ) + except NoSuchTableError: + Request_table = None + log.debug( "Failed loading table request" ) + if Request_table: + try: + col = Column( "submitted", Boolean, index=True, default=False ) + col.create( Request_table ) + assert col is Request_table.c.submitted + except Exception, e: + log.debug( "Adding column 'submitted' to submitted table failed: %s" % ( str( e ) ) ) + + # Add 1 column to the sample table + try: + Sample_table = Table( "sample", metadata, autoload=True ) + except NoSuchTableError: + Sample_table = None + log.debug( "Failed loading table sample" ) + if Sample_table: + try: + col = Column( "bar_code", TrimmedString( 255 ), index=True ) + col.create( Sample_table ) + assert col is Sample_table.c.bar_code + except Exception, e: + log.debug( "Adding column 'bar_code' to submitted table failed: %s" % ( str( e ) ) ) + +def downgrade(): + pass \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/web/controllers/admin.py --- a/lib/galaxy/web/controllers/admin.py Thu Jul 23 14:31:11 2009 -0400 +++ b/lib/galaxy/web/controllers/admin.py Thu Jul 23 17:08:21 2009 -0400 @@ -2162,7 +2162,7 @@ elif params.get('edit', False) == 'True': rt = trans.app.model.RequestType.get(int(util.restore_text( params.id ))) ss_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == rt.id).all() - return trans.fill_template( '/admin/requests/edit_request_type.mako', + return trans.fill_template( '/admin/requests/view_request_type.mako', request_type=rt, forms=self._get_all_forms(trans, all_versions=False), states_list=ss_list, @@ -2193,10 +2193,13 @@ for ss in ss_list: ss.delete() ss.flush() + # unsubmitted state + ss = trans.app.model.SampleState('Unsubmitted', 'Sample not yet submitted', rt) + ss.flush() for i in range( num_states ): name = util.restore_text( params.get( 'new_element_name_%i' % i, None )) desc = util.restore_text( params.get( 'new_element_description_%i' % i, None )) ss = trans.app.model.SampleState(name, desc, rt) ss.flush() - msg = "The new sample type named '%s' with %s state(s) has been created" % (rt.name, num_states) + msg = "The new request type named '%s' with %s state(s) has been created" % (rt.name, num_states) return rt, msg diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/web/controllers/forms.py --- a/lib/galaxy/web/controllers/forms.py Thu Jul 23 14:31:11 2009 -0400 +++ b/lib/galaxy/web/controllers/forms.py Thu Jul 23 17:08:21 2009 -0400 @@ -62,7 +62,8 @@ self.current_form['desc'] = '' self.current_form['fields'] = [] inputs = [ ( 'Name', TextField('name', 40,self.current_form['name'] ) ), - ( 'Description', TextField('description', 40, self.current_form['desc']) ) ] + ( 'Description', TextField('description', 40, self.current_form['desc']) ), + ( 'Import from csv file (Optional)', TextField('csv_file', 40, '') ) ] return trans.fill_template( '/admin/forms/create_form.mako', inputs=inputs, msg=msg, @@ -215,11 +216,16 @@ params = util.Params( kwd ) name = util.restore_text( params.name ) desc = util.restore_text( params.description ) or "" - # set form fields - fields = [] - for i in range( len(self.current_form['fields']) ): - fields.append(self.__get_field(i, **kwd)) - fields = fields + if params.get( 'csv_file', None ): + csv_file = util.restore_text( params.get( 'csv_file', '' ) ) + if csv_file: + fields = self.__import_fields(csv_file) + else: + # set form fields + fields = [] + for i in range( len(self.current_form['fields']) ): + fields.append(self.__get_field(i, **kwd)) + fields = fields return name, desc, fields def __update_current_form(self, **kwd): name, desc, fields = self.__get_form(**kwd) @@ -228,6 +234,24 @@ self.current_form['desc'] = desc self.current_form['fields'] = fields + def __import_fields(self, csv_file): + ''' + "company","name of the company", "True", "required", "TextField",, + "due date","turnaround time", "True", "optional", "SelectField","24 hours, 1 week, 1 month" + ''' + import csv + fields = [] + reader = csv.reader(open(csv_file)) + for row in reader: + options = row[5].split(',') + fields.append({'label': row[0], + 'helptext': row[1], + 'visible': row[2], + 'required': row[3], + 'type': row[4], + 'selectlist': options}) + return fields + def __save_form(self, trans, fdc_id=None, **kwd): ''' This method saves the current form @@ -271,8 +295,8 @@ for ft in BaseField.form_field_types(): self.fieldtype.add_option(ft, ft) self.required = SelectField('field_required_'+str(index), display='radio') - self.required.add_option('Required', 'true') - self.required.add_option('Optional', 'true', selected=True) + self.required.add_option('Required', 'required') + self.required.add_option('Optional', 'optional', selected=True) if field: self.fill(field, field_type) def fill(self, field, field_type=None): @@ -296,10 +320,10 @@ else: self.fieldtype.add_option(ft, ft) # required/optional - if field['required']: - self.required = SelectField('required_'+str(self.index), display='radio') - self.required.add_option('Required', 'true', selected=True) - self.required.add_option('Optional', 'true') + if field['required'] == 'required': + self.required = SelectField('field_required_'+str(self.index), display='radio') + self.required.add_option('Required', 'required', selected=True) + self.required.add_option('Optional', 'optional') def selectbox_ui(self, field): self.selectbox_options = [] if field['selectlist']: diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/web/controllers/requests.py --- a/lib/galaxy/web/controllers/requests.py Thu Jul 23 14:31:11 2009 -0400 +++ b/lib/galaxy/web/controllers/requests.py Thu Jul 23 17:08:21 2009 -0400 @@ -11,7 +11,7 @@ log = logging.getLogger( __name__ ) class RequestsListGrid( grids.Grid ): - title = "Requests" + title = "Sequencing Requests" model_class = model.Request default_sort_key = "-create_time" columns = [ @@ -20,13 +20,14 @@ attach_popup=True ), grids.GridColumn( "Description", key='desc'), grids.GridColumn( "Sample(s)", method='number_of_samples', - link=( lambda item: iff( item.deleted, None, dict( operation="samples", id=item.id ) ) ), ), + link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ), grids.GridColumn( "Type", key="request_type_id", method='get_request_type'), - grids.GridColumn( "Last update", key="update_time", format=time_ago ) + grids.GridColumn( "Last update", key="update_time", format=time_ago ), + grids.GridColumn( "Submitted", method='submitted'), ] operations = [ # grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Samples", allow_multiple=False, condition=( lambda item: not item.deleted ) ), + grids.GridOperation( "Submit", allow_multiple=False, condition=( lambda item: not item.submitted ) ) # grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ), # grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), ] @@ -43,45 +44,13 @@ def apply_default_filter( self, trans, query ): return query.filter_by( user=trans.user ) def number_of_samples(self, trans, request): - return str(len(trans.app.model.Sample.filter(trans.app.model.Sample.table.c.request_id==request.id).all())) + return str(len(request.samples)) + def submitted(self, trans, request): + if request.submitted: + return 'Yes' + return 'No' -class SamplesListGrid( grids.Grid ): - model_class = model.Sample - default_sort_key = "-create_time" - columns = [ - grids.GridColumn( "Name", key="name", - link=( lambda item: iff( item.deleted, None, dict( operation="show_sample", id=item.id ) ) ), - attach_popup=True ), - grids.GridColumn( "Description", key='desc' ), - grids.GridColumn( "Status", method="get_status", - link=( lambda item: iff( item.deleted, None, dict( operation="events", id=item.id ) ) )), - grids.GridColumn( "Last update", key="update_time", format=time_ago ) - - # Valid for filtering but invisible - #grids.GridColumn( "Deleted", key="deleted", visible=False ) - ] - operations = [ -# grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ), -# grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ), -# grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), - - ] - standard_filters = [ - grids.GridColumnFilter( "Active", args=dict( deleted=False ) ), - grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ), - grids.GridColumnFilter( "All", args=dict( deleted='All' ) ) - ] - def __init__(self, request): - self.request = request - def get_current_item( self, trans ): - return None - def apply_default_filter( self, trans, query ): - return query.filter_by( request_id=self.request.id ) - def get_status(self, trans, sample): - all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all() - curr_state = all_states[len(all_states)-1].state - return curr_state.name class Requests( BaseController ): request_grid = RequestsListGrid() @@ -94,7 +63,8 @@ all_libraries = trans.app.model.Library.filter(trans.app.model.Library.table.c.deleted == False).order_by(trans.app.model.Library.name).all() authorized_libraries = [] for library in all_libraries: - if trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_ADD, library_item=library) or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, library_item=library) or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, library_item=library) or trans.app.security_agent.check_folder_contents(trans.user, library) or trans.app.security_agent.show_library_item(trans.user, library): + if trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_ADD, library_item=library) \ + or trans.app.security_agent.allow_action(trans.user, trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, library_item=library): authorized_libraries.append(library) return authorized_libraries @web.expose @@ -107,27 +77,38 @@ operation = kwargs['operation'].lower() if operation == "show_request": id = trans.security.decode_id(kwargs['id']) - return self.show_read_only(trans, id) - elif operation == "samples": + return self.__show_request(trans, id, kwargs.get('add_sample', False)) + elif operation == "submit": id = trans.security.decode_id(kwargs['id']) - return self.show_samples(trans, id, kwargs) - elif operation == "show_sample": - id = trans.security.decode_id(kwargs['id']) - return self.show_sample_read_only(trans, id) - elif operation == "events": - id = trans.security.decode_id(kwargs['id']) - return self.show_events(trans, id) + return self.__submit(trans, id) # Render the list view - return self.request_grid( trans, status=status, message=message, template='/requests/grid.mako', **kwargs ) - def show_samples(self, trans, id, kwargs): - ''' - Shows all the samples associated with this request - ''' - status = message = None - request = trans.app.model.Request.get(id) - self.samples_grid = SamplesListGrid(request) - return self.samples_grid( trans, status=status, message=message, template='/sample/grid.mako', **kwargs ) - def show_read_only(self, trans, id): + return self.request_grid( trans, template='/requests/grid.mako', **kwargs ) + + def __show_request(self, trans, id, add_sample=False): + try: + request = trans.app.model.Request.get(id) + except: + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + status='error', + message="Invalid request ID", + **kwd) ) + self.current_samples = [] + for s in request.samples: + self.current_samples.append([s.name, s.values.content]) + if add_sample: + self.current_samples.append(['New Sample',['' for field in request.type.sample_form.fields]]) + # selectfield of all samples + copy_list = SelectField('copy_sample') + copy_list.add_option('None', -1, selected=True) + for i, s in enumerate(self.current_samples): + copy_list.add_option(i+1, i) + return trans.fill_template( '/requests/show_request.mako', + request=request, + request_details=self.request_details(trans, id), + current_samples = self.current_samples, + sample_copy=copy_list) + def request_details(self, trans, id): ''' Shows the request details ''' @@ -136,9 +117,6 @@ # list of widgets to be rendered on the request form request_details = [] # main details - request_details.append(dict(label='Name', - value=request.name, - helptext='')) request_details.append(dict(label='Description', value=request.desc, helptext='')) @@ -147,12 +125,6 @@ helptext='')) request_details.append(dict(label='Date created', value=request.create_time, - helptext='')) - request_details.append(dict(label='Date updated', - value=request.create_time, - helptext='')) - request_details.append(dict(label='User', - value=str(request.user.email), helptext='')) # library associated request_details.append(dict(label='Library', @@ -168,10 +140,97 @@ request_details.append(dict(label=field['label'], value=request.values.content[index], helptext=field['helptext']+' ('+req+')')) - return trans.fill_template( '/requests/view_request.mako', - request_form_id=request.type.request_form.id, - request_details=request_details, - request_type=request.type) + return request_details + + @web.expose + def show_request(self, trans, **kwd): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + try: + request = trans.app.model.Request.get(int(params.get('request_id', None))) + except: + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + status='error', + message="Invalid request ID", + **kwd) ) + if params.get('add_sample_button', False) == 'Add New': + # save the all (saved+unsaved) sample info in 'current_samples' + num_samples = len(self.current_samples) + self.current_samples = [] + for s in request.samples: + self.current_samples.append([s.name, s.values.content]) + for index in range(num_samples-len(request.samples)): + sample_index = index + len(request.samples) + sample_name = util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) ) + sample_values = [] + for field_index in range(len(request.type.sample_form.fields)): + sample_values.append(util.restore_text( params.get( 'sample_%i_field_%i' % (sample_index, field_index), '' ) )) + self.current_samples.append([sample_name, sample_values]) + # add an empty or filled sample + # if the user has selected a sample no. to copy then copy the contents + # of the src sample to the new sample else an empty sample + src_sample_index = int(params.get( 'copy_sample', -1 )) + if src_sample_index == -1: + # empty sample + self.current_samples.append(['New Sample',['' for field in request.type.sample_form.fields]]) + else: + self.current_samples.append([self.current_samples[src_sample_index][0]+'_copy',[val for val in self.current_samples[src_sample_index][1]]]) + # selectfield of all samples + copy_list = SelectField('copy_sample') + copy_list.add_option('None', -1, selected=True) + for i, s in enumerate(self.current_samples): + copy_list.add_option(i+1, i) + return trans.fill_template( '/requests/show_request.mako', + request=request, + request_details=self.request_details(trans, request.id), + current_samples = self.current_samples, + sample_copy=copy_list) + if params.get('save_samples_button', False) == 'Save': + num_samples = len(self.current_samples) + # save all the new/unsaved samples entered by the user + for index in range(num_samples-len(request.samples)): + sample_index = index + len(request.samples) + sample_name = util.restore_text( params.get( 'sample_%i_name' % sample_index, '' ) ) + sample_values = [] + for field_index in range(len(request.type.sample_form.fields)): + sample_values.append(util.restore_text( params.get( 'sample_%i_field_%i' % (sample_index, field_index), '' ) )) + form_values = trans.app.model.FormValues(request.type.sample_form, sample_values) + form_values.flush() + s = trans.app.model.Sample(sample_name, '', request, form_values) + s.flush() + # set the initial state + state = s.request.type.states[0] + event = trans.app.model.SampleEvent(s, state) + event.flush() + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + operation='show_request', + id=trans.security.encode_id(request.id)) ) + + @web.expose + def delete_sample(self, trans, **kwd): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + request = trans.app.model.Request.get(int(params.get('request_id', 0))) + sample_index = int(params.get('sample_id', 0)) + sample_name = self.current_samples[sample_index][0] + s = request.has_sample(sample_name) + if s: + s.delete() + s.flush() + del self.current_samples[sample_index] + copy_list = SelectField('copy_sample') + copy_list.add_option('None', -1, selected=True) + for i, s in enumerate(self.current_samples): + copy_list.add_option(i+1, i) + return trans.fill_template( '/requests/show_request.mako', + request=request, + request_details=self.request_details(trans, request.id), + current_samples = self.current_samples, + sample_copy=copy_list) @web.expose def new(self, trans, **kwd): params = util.Params( kwd ) @@ -202,10 +261,22 @@ request = self.__save_request(trans, None, **kwd) msg = 'The new request named %s has been created' % request.name request_type_id = int(util.restore_text( params.request_type_id )) - return trans.response.send_redirect( web.url_for( controller='requests', - action='list', - msg=msg , - messagetype='done') ) + if params.get('create_request_button', False) == 'Save': + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + msg=msg , + messagetype='done') ) + elif params.get('create_request_samples_button', False) == 'Add samples': + new_kwd = {} + new_kwd['id'] = trans.security.encode_id(request.id) + new_kwd['operation'] = 'show_request' + new_kwd['add_sample'] = True + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + msg=msg , + messagetype='done', + **new_kwd) ) + def __validate(self, trans, main_fields=[], form_fields=[], **kwd): ''' Validates the request entered by the user @@ -216,7 +287,8 @@ return 'Please enter the <b>%s</b> of the request' % field_name # check rest of the fields of the form for index, field in enumerate(form_fields): - if not util.restore_text(params.get('field_%i' % index, None)) and field['required']: + if not util.restore_text(params.get('field_%i' % index, None)) \ + and field['required'] == 'required': return 'Please enter the <b>%s</b> field of the request' % field['label'] return None def __save_request(self, trans, request_id=None, **kwd): @@ -240,7 +312,8 @@ form_values.flush() request = trans.app.model.Request(name, desc, request_type, trans.user, form_values, - trans.app.model.Library.get(library_id)) + trans.app.model.Library.get(library_id), + submitted=False) request.flush() else: # TODO editing @@ -266,29 +339,103 @@ util.restore_text( params.get( 'desc', '' ) )), helptext='(Optional)')) # libraries selectbox - value = int(params.get( 'library_id', 0 )) libraries = self.get_authorized_libs(trans) - lib_list = SelectField('library_id') - for lib in libraries: - if lib.id == value: - lib_list.add_option(lib.name, lib.id, selected=True) - else: - lib_list.add_option(lib.name, lib.id) - widgets.append(dict(label='Library', - widget=lib_list, - helptext='Associated library where the resultant \ - dataset will be stored')) + if libraries: + libui = self.__library_ui(libraries, **kwd) + widgets.append(libui) widgets = self.__create_form(trans, request_type.request_form_id, widgets, form_values, **kwd) title = 'Add a new request of type: %s' % request_type.name return trans.fill_template( '/requests/new_request.mako', request_form_id=request_type.request_form_id, - request_type=request_type, + request_type=request_type, widgets=widgets, title=title, msg=msg, messagetype=messagetype) + def __library_ui(self, libraries, **kwd): + params = util.Params( kwd ) + create_lib_str = 'Create a new library' + value = int(params.get( 'library_id', 0 )) + if not value: # if no library previously selected + # show the selectbox with 'create a new library' option selected + lib_list = SelectField('library_id', refresh_on_change=True, + refresh_on_change_values=[create_lib_str]) + #lib_list.add_option(create_lib_str, 0, selected=True) + for lib in libraries: + lib_list.add_option(lib.name, lib.id) + widget = dict(label='Library', + widget=lib_list, + helptext='Associated library where the resultant \ + dataset will be stored.') + else: # if some library previously selected + # show the selectbox with some library selected + lib_list = SelectField('library_id', refresh_on_change=True, + refresh_on_change_values=[create_lib_str]) + #lib_list.add_option(create_lib_str, 0) + for lib in libraries: + if value == lib.id: + lib_list.add_option(lib.name, lib.id, selected=True) + else: + lib_list.add_option(lib.name, lib.id) + widget = dict(label='Library', + widget=lib_list, + helptext='Associated library where the resultant \ + dataset will be stored.') + return widget + + def __submit(self, trans, id): + try: + request = trans.app.model.Request.get(id) + except: + msg = "Invalid request ID" + log.warn( msg ) + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + status='error', + message=msg, + **kwd) ) + # get the new state + new_state = request.type.states[1] + for s in request.samples: + event = trans.app.model.SampleEvent(s, new_state, 'Samples submitted to the system') + event.flush() + # change request's submitted field + request.submitted = True + request.flush() + kwd = {} + kwd['id'] = trans.security.encode_id(request.id) + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + **kwd) ) + @web.expose + def submit_request(self, trans, **kwd): + params = util.Params( kwd ) + try: + id = int(params.get('id', False)) + request = trans.app.model.Request.get(id) + except: + msg = "Invalid request ID" + log.warn( msg ) + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + status='error', + message=msg, + **kwd) ) + # get the new state + new_state = request.type.states[1] + for s in request.samples: + event = trans.app.model.SampleEvent(s, new_state, 'Samples submitted to the system') + event.flush() + # change request's submitted field + request.submitted = True + request.flush() + ## TODO + kwd['id'] = trans.security.encode_id(request.id) + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + **kwd) ) def __create_form(self, trans, form_id, widgets=[], form_values=None, **kwd): params = util.Params( kwd ) form = trans.app.model.FormDefinition.get(form_id) @@ -316,7 +463,7 @@ elif field['type'] == 'CheckboxField': fw.checked = value # require/optional - if field['required']: + if field['required'] == 'required': req = 'Required' else: req = 'Optional' @@ -325,140 +472,20 @@ helptext=field['helptext']+' ('+req+')')) return widgets @web.expose - def add_sample(self, trans, **kwd): + def show_events(self, trans, **kwd): params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - return self.__show_sample_form(trans, sample=None, **kwd) - - def __show_sample_form(self, trans, sample=None, **kwd): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - request = trans.app.model.Request.get(int( params.request_id )) - if sample: - form_values = sample.values - else: - form_values = None - # list of widgets to be rendered on the request form - widgets = [] - widgets.append(dict(label='Name', - widget=TextField('name', 40, - util.restore_text( params.get( 'name', '' ) )), - helptext='(Required)')) - widgets.append(dict(label='Description', - widget=TextField('desc', 40, - util.restore_text( params.get( 'desc', '' ) )), - helptext='(Optional)')) - widgets = self.__create_form(trans, request.type.sample_form_id, widgets, - form_values, **kwd) - title = 'Add a new sample to request: %s of type: %s' % (request.name, request.type.name) - return trans.fill_template( '/sample/new_sample.mako', - sample_form_id=request.type.sample_form_id, - request_id=request.id, - widgets=widgets, - title=title, - msg=msg, - messagetype=messagetype) - @web.expose - def samples(self, trans, **kwd): - params = util.Params( kwd ) - if params.get('save', False) == 'True': - request = trans.app.model.Request.get(int(params.request_id )) - msg = self.__validate(trans, - [('name','Name')], - request.type.sample_form.fields, - **kwd) - if msg: - return trans.response.send_redirect( web.url_for( controller='requests', - action='add_sample', - msg=msg, - messagetype='error', - **kwd) ) - sample = self.__save_sample(trans, sample_id=None, **kwd) - msg = 'The new sample named %s has been created' % sample.name + try: + sample_id = int(params.get('sample_id', False)) + sample = trans.app.model.Sample.get(sample_id) + except: + msg = "Invalid sample ID" return trans.response.send_redirect( web.url_for( controller='requests', action='list', - operation='samples', - id=trans.security.encode_id(sample.request_id), + status='error', + message=msg, **kwd) ) - def __save_sample(self, trans, sample_id=None, **kwd): - params = util.Params( kwd ) - if not sample_id: - request = trans.app.model.Request.get(int(params.request_id)) - else: - #TODO editing - pass - name = util.restore_text(params.get('name', '')) - desc = util.restore_text(params.get('desc', '')) - values = [] - for index, field in enumerate(request.type.sample_form.fields): - values.append(util.restore_text(params.get('field_%i' % index, ''))) - if not sample_id: - form_values = trans.app.model.FormValues(request.type.sample_form, values) - form_values.flush() - sample = trans.app.model.Sample(name, desc, request, form_values) - sample.flush() - # set the initial state - state = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == request.type.id).first() - event = trans.app.model.SampleEvent(sample, state) - event.flush() - else: - form_data.content = values - form_data.flush() - return sample - def show_sample_read_only(self, trans, sample_id): - ''' - Shows the sample details - ''' - sample = trans.app.model.Sample.get(sample_id) - request = sample.request - request_type = sample.request.type - sample_form = sample.request.type.sample_form - sample_values = sample.values - # list of widgets to be rendered on the request form - sample_details = [] - # main details - sample_details.append(dict(label='Name', - value=sample.name, - helptext='')) - sample_details.append(dict(label='Description', - value=sample.desc, - helptext='')) - sample_details.append(dict(label='Date created', - value=sample.create_time, - helptext='')) - sample_details.append(dict(label='Date updated', - value=sample.create_time, - helptext='')) - sample_details.append(dict(label='User', - value=str(trans.user.email), - helptext='')) - sample_details.append(dict(label='Request', - value=request.name, - helptext='Name/ID of the request this sample belongs to.')) - # get the current state of the sample - all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all() - curr_state = all_states[len(all_states)-1].state - sample_details.append(dict(label='State', - value=curr_state.name, - helptext=curr_state.desc)) - # form fields - for index, field in enumerate(sample_form.fields): - if field['required']: - req = 'Required' - else: - req = 'Optional' - sample_details.append(dict(label=field['label'], - value=sample_values.content[index], - helptext=field['helptext']+' ('+req+')')) - return trans.fill_template( '/sample/view_sample.mako', - sample_details=sample_details) - def show_events(self, trans, sample_id): - sample = trans.app.model.Sample.get(sample_id) events_list = [] - all_events = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all() - all_events.reverse() + all_events = sample.events for event in all_events: delta = datetime.utcnow() - event.update_time if delta > timedelta( minutes=60 ): @@ -469,7 +496,7 @@ return trans.fill_template( '/sample/sample_events.mako', events_list=events_list, sample_name=sample.name, - request=sample.request.name) + request=sample.request) diff -r f75758b35e51 -r 26b69d176146 lib/galaxy/web/controllers/requests_admin.py --- a/lib/galaxy/web/controllers/requests_admin.py Thu Jul 23 14:31:11 2009 -0400 +++ b/lib/galaxy/web/controllers/requests_admin.py Thu Jul 23 17:08:21 2009 -0400 @@ -15,16 +15,15 @@ SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error" class RequestsListGrid( grids.Grid ): - title = "Requests" + title = "Sequencing Requests" model_class = model.Request default_sort_key = "-create_time" columns = [ grids.GridColumn( "Name", key="name", - link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), - attach_popup=True ), + link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) )), grids.GridColumn( "Description", key="desc"), grids.GridColumn( "Sample(s)", method='number_of_samples', - link=( lambda item: iff( item.deleted, None, dict( operation="samples", id=item.id ) ) ), ), + link=( lambda item: iff( item.deleted, None, dict( operation="show_request", id=item.id ) ) ), ), grids.GridColumn( "Type", key="request_type_id", method='get_request_type'), grids.GridColumn( "Last update", key="update_time", format=time_ago ), grids.GridColumn( "User", key="user_id", method='get_user') @@ -32,7 +31,7 @@ ] operations = [ # grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Samples", allow_multiple=False, condition=( lambda item: not item.deleted ) ), +# grids.GridOperation( "Samples", allow_multiple=False, condition=( lambda item: not item.deleted ) ), # grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ), # grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), ] @@ -49,50 +48,10 @@ request_type = trans.app.model.RequestType.get(request.request_type_id) return request_type.name def apply_default_filter( self, trans, query ): - return query + return query.filter_by(submitted=True) def number_of_samples(self, trans, request): - return str(len(trans.app.model.Sample.filter(trans.app.model.Sample.table.c.request_id==request.id).all())) + return str(len(request.samples)) -class SamplesListGrid( grids.Grid ): - model_class = model.Sample - default_sort_key = "-create_time" - columns = [ - grids.GridColumn( "Name", key="name", - link=( lambda item: iff( item.deleted, None, dict( operation="show_sample", id=item.id ) ) ), - attach_popup=True ), - grids.GridColumn( "Description", key='desc' ), - grids.GridColumn( "Status", method="get_status", - link=( lambda item: iff( item.deleted, None, dict( operation="events", id=item.id ) ) )), - - grids.GridColumn( "Last update", key="update_time", format=time_ago ) - - # Valid for filtering but invisible - #grids.GridColumn( "Deleted", key="deleted", visible=False ) - ] - operations = [ -# grids.GridOperation( "Edit", allow_multiple=False, condition=( lambda item: not item.deleted ) ), - grids.GridOperation( "Change state", condition=( lambda item: not item.deleted ) ), -# grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ) ), -# grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), - - ] - standard_filters = [ - grids.GridColumnFilter( "Active", args=dict( deleted=False ) ), - grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ), - grids.GridColumnFilter( "All", args=dict( deleted='All' ) ) - ] - def __init__(self, request, user): - self.request = request - self.user = user - def get_current_item( self, trans ): - return None - def apply_default_filter( self, trans, query ): - return query.filter_by( request_id=self.request.id ) - def get_status(self, trans, sample): - all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all() - curr_state = trans.app.model.SampleState.get(all_states[len(all_states)-1].sample_state_id) - return curr_state.name - class Requests( BaseController ): request_grid = RequestsListGrid() @@ -118,30 +77,26 @@ operation = kwargs['operation'].lower() if operation == "show_request": id = trans.security.decode_id(kwargs['id']) - return self.show_read_only(trans, id) - elif operation == "samples": - id = trans.security.decode_id(kwargs['id']) - return self.show_samples(trans, id, kwargs) - elif operation == "show_sample": - id = trans.security.decode_id(kwargs['id']) - return self.show_sample_read_only(trans, id) - elif operation == "change state": - id_list = [trans.security.decode_id(id) for id in util.listify(kwargs['id'])] - return self.change_state(trans, id_list) - elif operation == "events": - id = trans.security.decode_id(kwargs['id']) - return self.show_events(trans, id) + return self.__show_request(trans, id) # Render the list view - return self.request_grid( trans, status=status, message=message, template='/admin/requests/grid.mako', **kwargs ) - def show_samples(self, trans, id, kwargs): - ''' - Shows all the samples associated with this request - ''' - status = message = None - request = trans.app.model.Request.get(id) - self.samples_grid = SamplesListGrid(request, trans.app.model.User.get(request.user_id)) - return self.samples_grid( trans, status=status, message=message, template='/admin/samples/grid.mako', **kwargs ) - def show_read_only(self, trans, id): + return self.request_grid( trans, template='/admin/requests/grid.mako', **kwargs ) + def __show_request(self, trans, id): + try: + request = trans.app.model.Request.get(id) + except: + return trans.response.send_redirect( web.url_for( controller='requests', + action='list', + status='error', + message="Invalid request ID", + **kwd) ) + self.current_samples = [] + for s in request.samples: + self.current_samples.append([s.name, s.values.content]) + return trans.fill_template( '/admin/requests/show_request.mako', + request=request, + request_details=self.request_details(trans, id), + current_samples = self.current_samples) + def request_details(self, trans, id): ''' Shows the request details ''' @@ -150,9 +105,6 @@ # list of widgets to be rendered on the request form request_details = [] # main details - request_details.append(dict(label='Name', - value=request.name, - helptext='')) request_details.append(dict(label='Description', value=request.desc, helptext='')) @@ -182,120 +134,106 @@ request_details.append(dict(label=field['label'], value=request.values.content[index], helptext=field['helptext']+' ('+req+')')) - return trans.fill_template( '/admin/requests/view_request.mako', - request_form_id=request.type.request_form.id, - request_details=request_details, - request_type=request.type) + return request_details + @web.expose + @web.require_admin + def bar_codes(self, trans, **kwd): + params = util.Params( kwd ) + request_id = params.get('request_id', None) + if request_id: + request_id = int(request_id) + request = trans.app.model.Request.get(request_id) + return trans.fill_template( '/admin/samples/bar_codes.mako', + samples_list=[s for s in request.samples], + user=request.user, + request=request) @web.expose @web.require_admin - def samples(self, trans, **kwd): + def save_bar_codes(self, trans, **kwd): params = util.Params( kwd ) - if params.get('save', False) == 'True': - sample = self.__save_sample(trans, params) - return self.show_samples(trans, sample.request_id, {}) - def show_sample_read_only(self, trans, sample_id): - ''' - Shows the sample details - ''' - sample = trans.app.model.Sample.get(sample_id) - request = sample.request - request_type = sample.request.type - sample_form = sample.request.type.sample_form - sample_values = sample.values - # list of widgets to be rendered on the request form - sample_details = [] - # main details - sample_details.append(dict(label='Name', - value=request.name, - helptext='')) - sample_details.append(dict(label='Description', - value=request.desc, - helptext='')) - sample_details.append(dict(label='Date created', - value=sample.create_time, - helptext='')) - sample_details.append(dict(label='Date updated', - value=sample.create_time, - helptext='')) - sample_details.append(dict(label='User', - value=str(trans.user.email), - helptext='')) - sample_details.append(dict(label='Request', - value=request.name, - helptext='Name/ID of the request this sample belongs to.')) - # get the current state of the sample - all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all() - curr_state = all_states[len(all_states)-1].state - sample_details.append(dict(label='State', - value=curr_state.name, - helptext=curr_state.desc)) - # form fields - for index, field in enumerate(sample_form.fields): - if field['required']: - req = 'Required' + request_id = params.get('request_id', None) + if request_id: + request_id = int(request_id) + request = trans.app.model.Request.get(request_id) + # validate + # bar codes need to be globally unique + unique = True + for index in range(len(request.samples)): + bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, '')) + all_samples = trans.app.model.Sample.query.all() + for sample in all_samples: + if bar_code == sample.bar_code: + unique = False + if not unique: + return trans.fill_template( '/admin/samples/bar_codes.mako', + samples_list=[s for s in request.samples], + user=request.user, + request=request, + messagetype='error', + msg='Samples cannot have same bar code.') + for index, sample in enumerate(request.samples): + bar_code = util.restore_text(params.get('sample_%i_bar_code' % index, '')) + sample.bar_code = bar_code + sample.flush() + return trans.response.send_redirect( web.url_for( controller='requests_admin', + action='list', + operation='show_request', + id=trans.security.encode_id(request.id)) ) + def change_state(self, trans, sample): + possible_states = sample.request.type.states + curr_state = sample.current_state() + states_input = SelectField('select_state') + for state in possible_states: + if curr_state.name == state.name: + states_input.add_option(state.name+' (Current)', state.id, selected=True) else: - req = 'Optional' - sample_details.append(dict(label=field['label'], - value=sample_values.content[index], - helptext=field['helptext']+' ('+req+')')) - return trans.fill_template( '/admin/samples/view_sample.mako', - sample_details=sample_details) - def __get_all_states(self, trans, sample): - all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all() - curr_state = all_states[len(all_states)-1].state - states_list = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == sample.request.type.id) - return states_list - def __get_curr_state(self, trans, sample): - all_states = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample.id).all() - curr_state = all_states[len(all_states)-1].state - return curr_state - def change_state(self, trans, sample_id_list): - sample = trans.app.model.Sample.get(sample_id_list[0]) - states_list = self.__get_all_states(trans, sample) - curr_state = self.__get_curr_state(trans, sample) - states_input = SelectField('select_state') - for state in states_list: - if len(sample_id_list) == 1: - if curr_state.name == state.name: - states_input.add_option(state.name+' (Current)', state.name, selected=True) - else: - states_input.add_option(state.name, state.name) - else: - states_input.add_option(state.name, state.name) + states_input.add_option(state.name, state.id) widgets = [] - widgets.append(('Select the new state of the sample(s) from the list of possible state(s)', + widgets.append(('Select the new state of the sample from the list of possible state(s)', states_input)) widgets.append(('Comments', TextArea('comment'))) - title = 'Change current state of sample: ' + sample.name - return trans.fill_template( '/admin/samples/change_state.mako', - widgets=widgets, title=title, - sample_id_list=util.object_to_string(sample_id_list)) + title = 'Change current state' + return widgets, title @web.expose @web.require_admin def save_state(self, trans, **kwd): params = util.Params( kwd ) - sample_id_list = util.string_to_object(util.restore_text( params.sample_id_list )) + try: + sample_id = int(params.get('sample_id', False)) + sample = trans.app.model.Sample.get(sample_id) + except: + msg = "Invalid sample ID" + return trans.response.send_redirect( web.url_for( controller='requests_admin', + action='list', + status='error', + message=msg, + **kwd) ) comments = util.restore_text( params.comment ) - sample = trans.app.model.Sample.get(sample_id_list[0]) - selected_state = util.restore_text( params.select_state ) + selected_state = int( params.select_state ) new_state = trans.app.model.SampleState.filter(trans.app.model.SampleState.table.c.request_type_id == sample.request.type.id - and trans.app.model.SampleState.table.c.name == selected_state)[0] - for id in sample_id_list: - s = trans.app.model.Sample.get(id) - event = trans.app.model.SampleEvent(s, new_state, comments) - event.flush() + and trans.app.model.SampleState.table.c.id == selected_state)[0] + event = trans.app.model.SampleEvent(sample, new_state, comments) + event.flush() return trans.response.send_redirect( web.url_for( controller='requests_admin', - action='list', - operation='samples', - id=trans.security.encode_id(sample.request.id)) ) + action='show_events', + sample_id=sample.id)) @web.expose @web.require_admin - def show_events(self, trans, sample_id): - sample = trans.app.model.Sample.get(sample_id) + def show_events(self, trans, **kwd): + params = util.Params( kwd ) + try: + sample_id = int(params.get('sample_id', False)) + sample = trans.app.model.Sample.get(sample_id) + except: + msg = "Invalid sample ID" + return trans.response.send_redirect( web.url_for( controller='requests_admin', + action='list', + status='error', + message=msg, + **kwd) ) events_list = [] - all_events = trans.app.model.SampleEvent.filter(trans.app.model.SampleEvent.table.c.sample_id == sample_id).all() - all_events.reverse() + all_events = sample.events for event in all_events: delta = datetime.utcnow() - event.update_time if delta > timedelta( minutes=60 ): @@ -303,8 +241,8 @@ else: last_update = '%s minutes' % int( delta.seconds / 60 ) events_list.append((event.state.name, event.state.desc, last_update, event.comment)) + widgets, title = self.change_state(trans, sample) return trans.fill_template( '/admin/samples/events.mako', events_list=events_list, - sample_name=sample.name, user=sample.request.user, - request=sample.request.name) + sample=sample, widgets=widgets, title=title) \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/forms/create_form.mako --- a/templates/admin/forms/create_form.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/forms/create_form.mako Thu Jul 23 17:08:21 2009 -0400 @@ -25,7 +25,9 @@ </div> <div style="clear: both"></div> </div> - <input type="submit" name="save_form" value="Save"/> + <div class="form-row"> + <input type="submit" name="save_form" value="Save"/> + </div> </form> </div> </div> diff -r f75758b35e51 -r 26b69d176146 templates/admin/forms/edit_form.mako --- a/templates/admin/forms/edit_form.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/forms/edit_form.mako Thu Jul 23 17:08:21 2009 -0400 @@ -37,20 +37,18 @@ %if field_attr[1].get_selected()[0] == 'SelectField': <% options = field_attr[2] %> <div class="repeat-group-item"> + <div class="form-row"> <label> Options</label> %for i, option in enumerate(options): <b> ${i+1}</b> - ${option[1].get_html()} - ##<input type="submit" name="remove_option_${index}" value="Remove option ${i+1}"/><br> + ${option[1].get_html()} <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form.id, select_box_options='remove', field_index=index, option_index=i )}">Remove</a><br> %endfor - </div> + </div> + </div> <div class="form-row"> <a class="action-button" href="${h.url_for( controller='forms', action='edit', form_id=form.id, select_box_options='add', field_index=index )}">Add</a> </div> - ##<div class="form-row"> - ## <input type="submit" name="add_option_field_${index}" value="Add option"/> - ##</div> %endif %endif </%def> @@ -99,7 +97,9 @@ </div> <div style="clear: both"></div> </div> - <input type="submit" name="save_changes_button" value="Save"/> + <div class="form-row"> + <input type="submit" name="save_changes_button" value="Save"/> + </div> </form> </div> </div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/add_states.mako --- a/templates/admin/requests/add_states.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/requests/add_states.mako Thu Jul 23 17:08:21 2009 -0400 @@ -6,7 +6,7 @@ %endif <div class="toolForm"> - <div class="toolFormTitle">Create ${num_states} states for the '${sample_type_name}' sample type</div> + <div class="toolFormTitle">Create ${num_states} states for the '${sample_type_name}' request type</div> <form name="new_form_fields" action="${h.url_for( controller='admin', action='request_type', save_new=True, create=False, edit=False, name=sample_type_name, description=desc, num_states=num_states, request_form_id=request_form_id, sample_form_id=sample_form_id)}" method="post" > <div class="toolFormBody"> %for element_count in range( num_states ): @@ -19,7 +19,7 @@ <div style="clear: both"></div> %endfor </div> - <div class="toolFormBody"> + <div class="form-row"> <input type="submit" name="save_new_sample_type" value="Save"/> </div> </form> diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/create_request_type.mako --- a/templates/admin/requests/create_request_type.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/requests/create_request_type.mako Thu Jul 23 17:08:21 2009 -0400 @@ -59,7 +59,9 @@ </div> <div style="clear: both"></div> </div> + <div class="form-row"> <input type="submit" name="create_library_button" value="Define states"/> + </div> </form> </div> %endif diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/edit_request_type.mako --- a/templates/admin/requests/edit_request_type.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/requests/edit_request_type.mako Thu Jul 23 17:08:21 2009 -0400 @@ -71,8 +71,9 @@ </div> <div style="clear: both"></div> </div> - - <input type="submit" name="edit_request_type_button" value="Save"/> + <div class="form-row"> + <input type="submit" name="edit_request_type_button" value="Save"/> + </div> </form> </div> </div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/grid.mako --- a/templates/admin/requests/grid.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/requests/grid.mako Thu Jul 23 17:08:21 2009 -0400 @@ -179,7 +179,11 @@ <div popupmenu="grid-${i}-popup"> %for operation in grid.operations: %if operation.allowed( item ): - <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a> + %if operation.label == 'Submit': + <a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${url( operation=operation.label, id=item.id )}">${operation.label}</a> + %else: + <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a> + %endif %endif %endfor </div> diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/show_request.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/admin/requests/show_request.mako Thu Jul 23 17:08:21 2009 -0400 @@ -0,0 +1,96 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + + +%if msg: + ${render_msg( msg, messagetype )} +%endif + + +<div class="grid-header"> + <h2>Request: ${request.name}</h2> +</div> + +<ul class="manage-table-actions"> + <li> + <a class="action-button" href="${h.url_for( controller='requests_admin', action='bar_codes', request_id=request.id)}"> + <span>Bar codes</span></a> + </li> +</ul> + +<%def name="render_sample( index, sample )"> + <td> + ${sample.name} + </td> + <td> + <a href="${h.url_for( controller='requests_admin', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a> + </td> + %for field_index, field in enumerate(request.type.sample_form.fields): + <td> + %if sample.values.content[field_index]: + ${sample.values.content[field_index]} + %else: + <i>None</i> + %endif + </td> + %endfor +</%def> + +<div class="toolForm"> + ##<div class="toolFormTitle">Request Details: '${request_details[0]['value']}'</div> + %for index, rd in enumerate(request_details): + <div class="form-row"> + <label>${rd['label']}</label> + %if not rd['value']: + <i>None</i> + %else: + %if rd['label'] == 'Library': + <a href="${h.url_for( controller='admin', action='browse_library', id=request.library.id )}">${rd['value']}</a> + %else: + ${rd['value']} + %endif + %endif + </div> + <div style="clear: both"></div> + %endfor + </div> +</div> + +<div class="toolForm"> + ##<div class="toolFormTitle">Samples (${len(request.samples)})</div> + <form id="edit_form" name="edit_form" action="${h.url_for( controller='requests', action='show_request', request_id=request.id )}" method="post" > + <div class="form-row"> + %if current_samples: + <table class="grid"> + <thead> + <tr> + <th>No.</th> + <th>Sample Name</th> + <th>State</th> + %for field_index, field in enumerate(request.type.sample_form.fields): + <th> + ${field['label']} + <div class="toolParamHelp" style="clear: both;"> + <i>${field['helptext']}</i> + </div> + </th> + %endfor + </tr> + <thead> + <tbody> + %for sample_index, sample in enumerate(current_samples): + <tr> + <td>${sample_index+1}</td> + ${render_sample( sample_index, request.samples[sample_index] )} + </tr> + %endfor + </tbody> + </table> + %else: + <label>There are no samples.</label> + %endif + + </div> + ##</div> + </form> +</div> diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/view_request.mako --- a/templates/admin/requests/view_request.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Request Details: '${request_details[0]['value']}'</div> - %for index, rd in enumerate(request_details): - <div class="form-row"> - <label>${rd['label']}</label> - ##<i>${rd['helptext']}</i> - ${rd['value']} - </div> - <div style="clear: both"></div> - %endfor - </div> -</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/requests/view_request_type.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/admin/requests/view_request_type.mako Thu Jul 23 17:08:21 2009 -0400 @@ -0,0 +1,51 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + + +%if msg: + ${render_msg( msg, messagetype )} +%endif + +<% num_states=len(states_list) %> + +<div class="toolForm"> + <div class="toolFormTitle">View request type details</div> + <div class="toolFormBody"> + <form name="library" action="${h.url_for( controller='admin', action='request_type', save_changes=True, create=False, id=request_type.id, num_states=num_states )}" method="post" > + <div class="form-row"> + <label>Name</label> + ${request_type.name} + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Description</label> + ${request_type.desc} + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label> + Request Form definition + </label> + ${request_type.request_form.name} + </div> + <div class="form-row"> + <label> + Sample Form definition + </label> + ${request_type.sample_form.name} + </div> + <div class="form-row"> + <label> + Possible states + </label> + %for element_count, state in enumerate(states_list): + <div class="form-row"> + <label>${1+element_count}. ${state.name}</label> + ${state.desc} + </div> + <div style="clear: both"></div> + %endfor + </div> + </form> + </div> +</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/samples/bar_codes.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/admin/samples/bar_codes.mako Thu Jul 23 17:08:21 2009 -0400 @@ -0,0 +1,37 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<h2>Bar codes for Samples of Request: ${request.name}</h2> +<h3>User: ${user.email}</h3> + +%if msg: + ${render_msg( msg, messagetype )} +%endif + +<div class="toolForm"> + <form name="bar_codes" action="${h.url_for( controller='requests_admin', action='save_bar_codes', request_id=request.id)}" method="post" > + <table class="grid"> + <thead> + <tr> + <th>Name</th> + <th>Description</th> + <th>Bar code</th> + </tr> + </thead> + <tbody> + %for index, sample in enumerate(samples_list): + <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> + <td><b><a>${sample.name}</a></b></td> + <td><a>${sample.desc}</a></td> + <td> + <input type="text" name="sample_${index}_bar_code" value=${sample.bar_code} size="40"/> + </td> + </tr> + %endfor + </tbody> + </table> + <div class="form-row"> + <input type="submit" name="save_new_sample_type" value="Save"/> + </div> + </form> +</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/samples/change_state.mako --- a/templates/admin/samples/change_state.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif -<div class="toolForm"> - <div class="toolFormTitle">${title}</div> - <div class="toolFormBody"> - <form name="event" action="${h.url_for( controller='requests_admin', action='save_state', new=True, sample_id_list=sample_id_list)}" 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" value="Save"/> - </div> - </form> - </div> -</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/samples/edit_sample.mako --- a/templates/admin/samples/edit_sample.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,83 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Edit sample named: ${values.content['Name']}</div> - <div class="toolFormBody"> - <form name="sample" action="${h.url_for( controller='sample', action='do', save_changes=True, sample_id=sample.id )}" method="post" > - <div class="form-row"> - <label> - Library: - </label> - <select name="library_id"> - %for library in libraries: - <option value="${library.id}">${library.name}</option> - %endfor - </select> - </div> - %for i, field in enumerate(form.fields): - <div class="form-row"> - <label>${field['label']}</label> - %if field['type'] == 'TextField': - <input type="text" name="${field['label']}" value="${values.content[field['label']]}" size="40"/> - %elif field['type'] == 'TextArea': - <textarea name="${field['label']}" rows="3" cols="35">${values.content[field['label']]}</textarea> - %elif field['type'] == 'CheckBox': - %if values.content[field['label']] == "true": - <input type="checkbox" name="${field['label']}" value="true" checked> - %else: - <input type="checkbox" name="${field['label']}" value="true"> - %endif - %elif field['type'] == 'SelectBox': - <select name="${field['label']}"> - %for ft in field['selectlist']: - %if ft == values.content[field['label']]: - <option value="${ft}" selected>${ft}</option> - %else: - <option value="${ft}">${ft}</option> - %endif - %endfor - </select> - %endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="new" value="submitted" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="create_library_button" value="Save"/> - </div> - </form> - </div> -</div> -<div class="toolForm"> - <div class="toolFormBody"> - <form name="event" action="${h.url_for( controller='admin', action='event', new=True, sample_id=sample.id)}" method="post" > - <div class="form-row"> - <label> - Change sample state to: - </label> - <select name="state_id"> - %for state in states: - <option value="${state.id}">${state.name}</option> - %endfor - </select> - </div> - <div class="form-row"> - <input type="submit" name="add_event" value="Save"/> - </div> - </form> - </div> -</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/samples/events.mako --- a/templates/admin/samples/events.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/admin/samples/events.mako Thu Jul 23 17:08:21 2009 -0400 @@ -1,33 +1,57 @@ <%inherit file="/base.mako"/> <%namespace file="/message.mako" import="render_msg" /> -<%def name="title()">Events for Sample ${sample_name}</%def> +<%def name="title()">Events for Sample ${sample.name}</%def> -<h2>Events for Sample "${sample_name}" of Request: ${request}</h2> -<h3>User: ${user.email}</h3> +<h2>Events for Sample "${sample.name}" of Request: <a href="${h.url_for( controller='requests_admin', action='list', operation='show_request', id=trans.security.encode_id(sample.request.id))}">${sample.request.name}</a></h2> +<h3>User: ${sample.request.user.email}</h3> %if msg: ${render_msg( msg, messagetype )} %endif - -<table class="grid"> - <thead> - <tr> - <th>State</th> - <th>Description</th> - <th>Last Update</th> - <th>Comments</th> - </tr> - </thead> - <tbody> - %for state, desc, updated, comments in events_list: - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a>${state}</a></b></td> - <td><a>${desc}</a></td> - <td><a>${updated}</a></td> - <td><a>${comments}</a></td> - </tr> - %endfor - </tbody> -</table> \ No newline at end of file +<div class="toolForm"> + <table class="grid"> + <thead> + <tr> + <th>State</th> + <th>Description</th> + <th>Last Update</th> + <th>Comments</th> + </tr> + </thead> + <tbody> + %for state, desc, updated, comments in events_list: + <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> + <td><b><a>${state}</a></b></td> + <td><a>${desc}</a></td> + <td><a>${updated}</a></td> + <td><a>${comments}</a></td> + </tr> + %endfor + </tbody> + </table> +</div> +<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" value="Save"/> + </div> + </form> + </div> +</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/admin/samples/grid.mako --- a/templates/admin/samples/grid.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,203 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<%def name="title()">Browse Samples</%def> - -%if message: - <p> - <div class="${message_type}message transient-message">${message}</div> - <div style="clear: both"></div> - </p> -%endif - -<%def name="javascripts()"> - ${parent.javascripts()} - <script type="text/javascript"> - ## TODO: generalize and move into galaxy.base.js - $(document).ready(function() { - $(".grid").each( function() { - var grid = this; - var checkboxes = $(this).find("input.grid-row-select-checkbox"); - var update = $(this).find( "span.grid-selected-count" ); - $(checkboxes).each( function() { - $(this).change( function() { - var n = $(checkboxes).filter("[checked]").size(); - update.text( n ); - }); - }) - }); - }); - ## Can this be moved into base.mako? - %if refresh_frames: - %if 'masthead' in refresh_frames: - ## Refresh masthead == user changes (backward compatibility) - if ( parent.user_changed ) { - %if trans.user: - parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} ); - %else: - parent.user_changed( null, false ); - %endif - } - %endif - %if 'history' in refresh_frames: - if ( parent.frames && parent.frames.galaxy_history ) { - parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}"; - if ( parent.force_right_panel ) { - parent.force_right_panel( 'show' ); - } - } - %endif - %if 'tools' in refresh_frames: - if ( parent.frames && parent.frames.galaxy_tools ) { - parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}"; - if ( parent.force_left_panel ) { - parent.force_left_panel( 'show' ); - } - } - %endif - %endif - </script> -</%def> - -<%def name="stylesheets()"> - <link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" /> - <style> - ## Not generic to all grids -- move to base? - .count-box { - min-width: 1.1em; - padding: 5px; - border-width: 1px; - border-style: solid; - text-align: center; - display: inline-block; - } - </style> -</%def> - -<div class="grid-header"> - <h2>Samples associated with request: ${grid.request.name}</h2> - <h3>User: ${grid.user.email}</h3> -## %if len(query.all()): -## <span class="title">Filter:</span> -## %for i, filter in enumerate( grid.standard_filters ): -## %if i > 0: -## <span>|</span> -## %endif -## <span class="filter"><a href="${url( filter.get_url_args() )}">${filter.label}</a></span> -## %endfor -## %endif -</div> - -%if not len(query.all()): - There are no sample(s). -%else: -<form name="history_actions" action="${url()}" method="post" > - <table class="grid"> - <thead> - <tr> - <th></th> - %for column in grid.columns: - %if column.visible: - <% - href = "" - extra = "" - if column.sortable: - if sort_key == column.key: - if sort_order == "asc": - href = url( sort=( "-" + column.key ) ) - extra = "↓" - else: - href = url( sort=( column.key ) ) - extra = "↑" - else: - href = url( sort=column.key ) - %> - <th\ - %if column.ncells > 1: - colspan="${column.ncells}" - %endif - > - %if href: - <a href="${href}">${column.label}</a> - %else: - ${column.label} - %endif - <span>${extra}</span> - </th> - %endif - %endfor - <th></th> - </tr> - </thead> - <tbody> - %for i, item in enumerate( query ): - <tr \ - %if current_item == item: - class="current" \ - %endif - > - ## Item selection column - <td style="width: 1.5em;"> - <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" /> - </td> - ## Data columns - %for column in grid.columns: - %if column.visible: - <% - # Link - if column.link and column.link( item ): - href = url( **column.link( item ) ) - else: - href = None - # Value (coerced to list so we can loop) - value = column.get_value( trans, grid, item ) - if column.ncells == 1: - value = [ value ] - %> - %for cellnum, v in enumerate( value ): - <% - # Attach popup menu? - if column.attach_popup and cellnum == 0: - extra = '<a id="grid-%d-popup" class="popup-arrow" style="display: none;">▼</a>' % i - else: - extra = "" - %> - %if href: - <td><a href="${href}">${v}</a> ${extra}</td> - %else: - <td >${v}${extra}</td> - %endif - </td> - %endfor - %endif - %endfor - ## Actions column - <td> - <div popupmenu="grid-${i}-popup"> - %for operation in grid.operations: - %if operation.allowed( item ): - <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a> - %endif - %endfor - </div> - </td> - </tr> - %endfor - </tbody> - <tfoot> - <tr> - <td></td> - <td colspan="100"> - For <span class="grid-selected-count"></span> selected requests: - %for operation in grid.operations: - %if operation.allow_multiple: - <input type="submit" name="operation" value="${operation.label}" class="action-button"> - %endif - %endfor - </td> - </tr> - </tfoot> - </table> -</form> - -%endif diff -r f75758b35e51 -r 26b69d176146 templates/admin/samples/view_sample.mako --- a/templates/admin/samples/view_sample.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Sample Details: '${sample_details[0]['value']}'</div> - %for index, rd in enumerate(sample_details): - <div class="form-row"> - <label>${rd['label']}</label> - ${rd['value']} - </div> - <div style="clear: both"></div> - %endfor - </div> -</div> diff -r f75758b35e51 -r 26b69d176146 templates/base.mako --- a/templates/base.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/base.mako Thu Jul 23 17:08:21 2009 -0400 @@ -33,30 +33,3 @@ </%def> -<script type="text/javascript"> -$( function() { - $( "select[refresh_on_change='true']").change( function() { - var refresh = false; - var refresh_on_change_values = $( this )[0].attributes.getNamedItem( 'refresh_on_change_values' ) - if ( refresh_on_change_values ) { - refresh_on_change_values = refresh_on_change_values.value.split( ',' ); - var last_selected_value = $( this )[0].attributes.getNamedItem( 'last_selected_value' ); - for( i= 0; i < refresh_on_change_values.length; i++ ) { - if ( $( this )[0].value == refresh_on_change_values[i] || ( last_selected_value && last_selected_value.value == refresh_on_change_values[i] ) ){ - refresh = true; - break; - } - } - } - else { - refresh = true; - } - if ( refresh ){ - $( ':file' ).each( function() { - var file_value = $( this )[0].value; - } ); - $( "#edit_form" ).submit(); - } - }); -}); -</script> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/base_panels.mako --- a/templates/base_panels.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/base_panels.mako Thu Jul 23 17:08:21 2009 -0400 @@ -156,7 +156,14 @@ ${tab( "libraries", "Libraries", h.url_for( controller='library', action='index' ))} - ${tab( "requests", "Requests", h.url_for( controller='requests', action='index' ), visible = (trans.user and trans.request_types)) } + <td class="tab"> + <a>Lab</a> + <div class="submenu"> + <ul> + <li><a target="requests" href="${h.url_for( controller='requests', action='index' )}">Sequencing Requests</a></li> + </ul> + </div> + </td> %if app.config.get_bool( 'enable_tracks', False ): <td class="tab"> diff -r f75758b35e51 -r 26b69d176146 templates/requests/grid.mako --- a/templates/requests/grid.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/requests/grid.mako Thu Jul 23 17:08:21 2009 -0400 @@ -184,7 +184,11 @@ <div popupmenu="grid-${i}-popup"> %for operation in grid.operations: %if operation.allowed( item ): - <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a> + %if operation.label == 'Submit': + <a class="action-button" confirm="More samples cannot be added to this request once it is submitted. Click OK to submit." href="${url( operation=operation.label, id=item.id)}">${operation.label}</a> + %else: + <a class="action-button" href="${url( operation=operation.label, id=item.id )}">${operation.label}</a> + %endif %endif %endfor </div> diff -r f75758b35e51 -r 26b69d176146 templates/requests/new_request.mako --- a/templates/requests/new_request.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/requests/new_request.mako Thu Jul 23 17:08:21 2009 -0400 @@ -9,11 +9,14 @@ <div class="toolForm"> <div class="toolFormTitle">${title}</div> <div class="toolFormBody"> - <form name="sample" action="${h.url_for( controller='requests', action='new', save=True, request_form_id=request_form_id, request_type_id=request_type.id )}" method="post" > + <form id="new_request" name="new_request" action="${h.url_for( controller='requests', action='new', save=True, request_form_id=request_form_id, request_type_id=request_type.id )}" method="post" > %for i, field in enumerate(widgets): <div class="form-row"> <label>${field['label']}</label> ${field['widget'].get_html()} + %if field['label'] == 'Library' and new_library: + ${new_library.get_html()} + %endif <div class="toolParamHelp" style="clear: both;"> ${field['helptext']} </div> @@ -26,7 +29,10 @@ </div> <div style="clear: both"></div> </div> - <input type="submit" name="create_library_button" value="Save"/> + <div class="form-row"> + <input type="submit" name="create_request_button" value="Save"/> + <input type="submit" name="create_request_samples_button" value="Add samples"/> + </div> </form> </div> </div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/requests/show_request.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/requests/show_request.mako Thu Jul 23 17:08:21 2009 -0400 @@ -0,0 +1,157 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + + +%if msg: + ${render_msg( msg, messagetype )} +%endif + + +<div class="grid-header"> + <h2>Request: ${request.name}</h2> +</div> + +%if not request.submitted and request.samples: +<ul class="manage-table-actions"> + <li> + <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', action='submit_request', id=request.id)}"> + <span>Submit request</span></a> + </li> +</ul> +%endif + + +<%def name="render_sample_form( index, sample_name, sample_values )"> + <td> + <input type="text" name=sample_${index}_name value="${sample_name}" size="15"/> + <div class="toolParamHelp" style="clear: both;"> + <i>${' (required)' }</i> + </div> + </td> + <td> + </td> + %for field_index, field in enumerate(request.type.sample_form.fields): + <td> + <input type="text" name=sample_${index}_field_${field_index} value="${sample_values[field_index]}" size="15"/> + <div class="toolParamHelp" style="clear: both;"> + <i>${'('+field['required']+')' }</i> + </div> + </td> + %endfor +</%def> + +<%def name="render_sample( index, sample )"> + <td> + ${sample.name} + </td> + <td> + <a href="${h.url_for( controller='requests', action='show_events', sample_id=sample.id)}">${sample.current_state().name}</a> + </td> + %for field_index, field in enumerate(request.type.sample_form.fields): + <td> + %if sample.values.content[field_index]: + ${sample.values.content[field_index]} + %else: + <i>None</i> + %endif + </td> + %endfor +</%def> + +<div class="toolForm"> + ##<div class="toolFormTitle">Request Details: '${request_details[0]['value']}'</div> + %for index, rd in enumerate(request_details): + <div class="form-row"> + <label>${rd['label']}</label> + %if not rd['value']: + <i>None</i> + %else: + %if rd['label'] == 'Library': + <a href="${h.url_for( controller='library', action='browse_library', id=request.library.id )}">${rd['value']}</a> + %else: + ${rd['value']} + %endif + %endif + </div> + <div style="clear: both"></div> + %endfor + </div> +</div> + +<div class="toolForm"> + ##<div class="toolFormTitle">Samples (${len(request.samples)})</div> + <form id="edit_form" name="edit_form" action="${h.url_for( controller='requests', action='show_request', request_id=request.id )}" method="post" > + <div class="form-row"> + %if current_samples: + <table class="grid"> + <thead> + <tr> + <th>No.</th> + <th>Sample Name</th> + <th>State</th> + %for field_index, field in enumerate(request.type.sample_form.fields): + <th> + ${field['label']} + <div class="toolParamHelp" style="clear: both;"> + <i>${field['helptext']}</i> + </div> + </th> + %endfor + <th></th> + </tr> + <thead> + <tbody> + %for sample_index, sample in enumerate(current_samples): + <tr> + <td>${sample_index+1}</td> + %if sample[0] in [s.name for s in request.samples]: + ${render_sample( sample_index, request.samples[sample_index] )} + %else: + ${render_sample_form( sample_index, sample[0], sample[1])} + %endif + <td> + %if not request.submitted: + <a class="action-button" href="${h.url_for( controller='requests', action='delete_sample', request_id=request.id, sample_id=sample_index)}"> + <img src="${h.url_for('/static/images/delete_icon.png')}" /> + <span></span></a> + %endif + </td> + </tr> + %endfor + </tbody> + </table> + %else: + <label>There are no samples.</label> + %endif + + </div> + %if not request.submitted: + <br/> + <br/> + <div class="form-row"> + <ul class="manage-table-actions"> + <li> + %if current_samples: + <a>Copy from sample no. </a> + ${sample_copy.get_html()} + %endif + <input type="submit" name="add_sample_button" value="Add New"/> + + </li> + </ul> + </div> + %endif + %if not request.submitted and (request.samples or current_samples): + <div class="form-row"> + <div style="float: left; width: 250px; margin-right: 10px;"> + <input type="hidden" name="refresh" value="true" size="40"/> + </div> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <input type="submit" name="save_samples_button" value="Save"/> + </div> + %endif + ##</div> + </form> +</div> diff -r f75758b35e51 -r 26b69d176146 templates/requests/view_request.mako --- a/templates/requests/view_request.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Request Details: '${request_details[0]['value']}'</div> - %for index, rd in enumerate(request_details): - <div class="form-row"> - <label>${rd['label']}</label> - ##<i>${rd['helptext']}</i> - ${rd['value']} - </div> - <div style="clear: both"></div> - %endfor - </div> -</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/sample/browse_samples.mako --- a/templates/sample/browse_samples.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<%def name="title()">Browse Samples</%def> - -<h2>Samples</h2> - -<ul class="manage-table-actions"> - %if not deleted: - <li> - <a class="action-button" href="${h.url_for( controller='sample', action='do', new=True )}"><span>Add Sample</span></a> - </li> - %endif -</ul> - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -%if not samples_list: - You have no samples. -%else: - <table class="grid"> - <thead> - <tr> - <th>Name</th> - <th>Description</th> - <th>Type</th> - <th>State</th> - </tr> - </thead> - <tbody> - %for id, name, desc, st, state in samples_list: - <tr class="libraryRow libraryOrFolderRow" id="libraryRow"> - <td><b><a href="${h.url_for( controller='sample', action='do', sample_id=id, edit=True)}">${name}</a></b></td> - <td><a>${desc}</a></td> - <td><a>${st}</a></td> - <td><a href="${h.url_for( controller='sample', action='events', sample_id=id)}">${state}</a></td> - </tr> - %endfor - </tbody> - </table> -%endif \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/sample/edit_sample.mako --- a/templates/sample/edit_sample.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Edit sample named: ${values.content['Name']}</div> - <div class="toolFormBody"> - <form name="sample" action="${h.url_for( controller='sample', action='do', save_changes=True, sample_id=sample.id )}" method="post" > - <div class="form-row"> - <label> - Library: - </label> - <select name="library_id"> - %for library in libraries: - <option value="${library.id}">${library.name}</option> - %endfor - </select> - </div> - %for i, field in enumerate(form.fields): - <div class="form-row"> - <label>${field['label']}</label> - %if field['type'] == 'TextField': - <input type="text" name="${field['label']}" value="${values.content[field['label']]}" size="40"/> - %elif field['type'] == 'TextArea': - <textarea name="${field['label']}" rows="3" cols="35">${values.content[field['label']]}</textarea> - %elif field['type'] == 'CheckBox': - %if values.content[field['label']] == "true": - <input type="checkbox" name="${field['label']}" value="true" checked> - %else: - <input type="checkbox" name="${field['label']}" value="true"> - %endif - %elif field['type'] == 'SelectBox': - <select name="${field['label']}"> - %for ft in field['selectlist']: - %if ft == values.content[field['label']]: - <option value="${ft}" selected>${ft}</option> - %else: - <option value="${ft}">${ft}</option> - %endif - %endfor - </select> - %endif - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="new" value="submitted" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <div class="form-row"> - <input type="submit" name="create_library_button" value="Save"/> - </div> - </form> - </div> -</div> diff -r f75758b35e51 -r 26b69d176146 templates/sample/grid.mako --- a/templates/sample/grid.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,210 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<%def name="title()">Browse Samples</%def> - -%if message: - <p> - <div class="${message_type}message transient-message">${message}</div> - <div style="clear: both"></div> - </p> -%endif - -<%def name="javascripts()"> - ${parent.javascripts()} - <script type="text/javascript"> - ## TODO: generalize and move into galaxy.base.js - $(document).ready(function() { - $(".grid").each( function() { - var grid = this; - var checkboxes = $(this).find("input.grid-row-select-checkbox"); - var update = $(this).find( "span.grid-selected-count" ); - $(checkboxes).each( function() { - $(this).change( function() { - var n = $(checkboxes).filter("[checked]").size(); - update.text( n ); - }); - }) - }); - }); - ## Can this be moved into base.mako? - %if refresh_frames: - %if 'masthead' in refresh_frames: - ## Refresh masthead == user changes (backward compatibility) - if ( parent.user_changed ) { - %if trans.user: - parent.user_changed( "${trans.user.email}", ${int( app.config.is_admin_user( trans.user ) )} ); - %else: - parent.user_changed( null, false ); - %endif - } - %endif - %if 'history' in refresh_frames: - if ( parent.frames && parent.frames.galaxy_history ) { - parent.frames.galaxy_history.location.href="${h.url_for( controller='root', action='history')}"; - if ( parent.force_right_panel ) { - parent.force_right_panel( 'show' ); - } - } - %endif - %if 'tools' in refresh_frames: - if ( parent.frames && parent.frames.galaxy_tools ) { - parent.frames.galaxy_tools.location.href="${h.url_for( controller='root', action='tool_menu')}"; - if ( parent.force_left_panel ) { - parent.force_left_panel( 'show' ); - } - } - %endif - %endif - </script> -</%def> - -<%def name="stylesheets()"> - <link href="${h.url_for('/static/style/base.css')}" rel="stylesheet" type="text/css" /> - <style> - ## Not generic to all grids -- move to base? - .count-box { - min-width: 1.1em; - padding: 5px; - border-width: 1px; - border-style: solid; - text-align: center; - display: inline-block; - } - </style> -</%def> - -<div class="grid-header"> - <h2>Samples associated with request: ${grid.request.name}</h2> -## %if len(query.all()): -## <span class="title">Filter:</span> -## %for i, filter in enumerate( grid.standard_filters ): -## %if i > 0: -## <span>|</span> -## %endif -## <span class="filter"><a href="${url( filter.get_url_args() )}">${filter.label}</a></span> -## %endfor -## %endif -</div> - -<ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='requests', action='add_sample', request_id=grid.request.id)}"> - <img src="${h.url_for('/static/images/silk/add.png')}" /> - <span>Add sample</span></a> - </li> -</ul> - -%if not len(query.all()): - There are no sample(s). -%else: -<form name="history_actions" action="${url()}" method="post" > - <table class="grid"> - <thead> - <tr> - <th></th> - %for column in grid.columns: - %if column.visible: - <% - href = "" - extra = "" - if column.sortable: - if sort_key == column.key: - if sort_order == "asc": - href = url( sort=( "-" + column.key ) ) - extra = "↓" - else: - href = url( sort=( column.key ) ) - extra = "↑" - else: - href = url( sort=column.key ) - %> - <th\ - %if column.ncells > 1: - colspan="${column.ncells}" - %endif - > - %if href: - <a href="${href}">${column.label}</a> - %else: - ${column.label} - %endif - <span>${extra}</span> - </th> - %endif - %endfor - <th></th> - </tr> - </thead> - <tbody> - %for i, item in enumerate( query ): - <tr \ - %if current_item == item: - class="current" \ - %endif - > - ## Item selection column - <td style="width: 1.5em;"> - <input type="checkbox" name="id" value=${trans.security.encode_id( item.id )} class="grid-row-select-checkbox" /> - </td> - ## Data columns - %for column in grid.columns: - %if column.visible: - <% - # Link - if column.link and column.link( item ): - href = url( **column.link( item ) ) - else: - href = None - # Value (coerced to list so we can loop) - value = column.get_value( trans, grid, item ) - if column.ncells == 1: - value = [ value ] - %> - %for cellnum, v in enumerate( value ): - <% - # Attach popup menu? - if column.attach_popup and cellnum == 0: - extra = '<a id="grid-%d-popup" class="popup-arrow" style="display: none;">▼</a>' % i - else: - extra = "" - %> - %if href: - <td><a href="${href}">${v}</a> ${extra}</td> - %else: - <td >${v}${extra}</td> - %endif - </td> - %endfor - %endif - %endfor - ## Actions column -## <td> -## <div popupmenu="grid-${i}-popup"> -## %for operation in grid.operations: -## %if operation.allowed( item ): -## <a class="action-button" href="${url( operation=operation.label, id=trans.security.encode_id( item.id ) )}">${operation.label}</a> -## %endif -## %endfor -## </div> -## </td> - </tr> - %endfor - </tbody> -## <tfoot> -## <tr> -## <td></td> -## <td colspan="100"> -## For <span class="grid-selected-count"></span> selected requests: -## %for operation in grid.operations: -## %if operation.allow_multiple: -## <input type="submit" name="operation" value="${operation.label}" class="action-button"> -## %endif -## %endfor -## </td> -## </tr> -## </tfoot> - </table> -</form> - -%endif diff -r f75758b35e51 -r 26b69d176146 templates/sample/new_sample.mako --- a/templates/sample/new_sample.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">${title}</div> - <div class="toolFormBody"> - <form name="sample" action="${h.url_for( controller='requests', action='samples', save=True, sample_form_id=sample_form_id, request_id=request_id )}" method="post" > - %for i, field in enumerate(widgets): - <div class="form-row"> - <label>${field['label']}</label> - ${field['widget'].get_html()} - <div class="toolParamHelp" style="clear: both;"> - ${field['helptext']} - </div> - <div style="clear: both"></div> - </div> - %endfor - <div class="form-row"> - <div style="float: left; width: 250px; margin-right: 10px;"> - <input type="hidden" name="new" value="submitted" size="40"/> - </div> - <div style="clear: both"></div> - </div> - <input type="submit" name="create_sample_button" value="Save"/> - </form> - </div> -</div> \ No newline at end of file diff -r f75758b35e51 -r 26b69d176146 templates/sample/sample_events.mako --- a/templates/sample/sample_events.mako Thu Jul 23 14:31:11 2009 -0400 +++ b/templates/sample/sample_events.mako Thu Jul 23 17:08:21 2009 -0400 @@ -3,7 +3,7 @@ <%def name="title()">Events for Sample ${sample_name}</%def> -<h2>Events for Sample "${sample_name}" of Request: ${request}</h2> +<h2>Events for Sample "${sample_name}" of Request: <a href="${h.url_for( controller='requests', action='list', operation='show_request', id=trans.security.encode_id(request.id))}">${request.name}</a></h2> %if msg: ${render_msg( msg, messagetype )} diff -r f75758b35e51 -r 26b69d176146 templates/sample/view_sample.mako --- a/templates/sample/view_sample.mako Thu Jul 23 14:31:11 2009 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - - -%if msg: - ${render_msg( msg, messagetype )} -%endif - -<div class="toolForm"> - <div class="toolFormTitle">Sample Details: '${sample_details[0]['value']}'</div> - %for index, rd in enumerate(sample_details): - <div class="form-row"> - <label>${rd['label']}</label> - ${rd['value']} - </div> - <div style="clear: both"></div> - %endfor - </div> -</div>