# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User Greg Von Kuster <greg@bx.psu.edu> # Date 1289839599 18000 # Node ID bde1ca8b6134079a9323d76bcaf057b3cc4166c1 # Parent 095dc06e0728556426a9288e6448fd1114e24063 First pass at cleaning up the Galaxy Form Definition UI ( forms controller still needs a re-write ). --- a/lib/galaxy/webapps/community/controllers/__init__.py +++ b/lib/galaxy/webapps/community/controllers/__init__.py @@ -1,1 +1,1 @@ -"""Galaxy community space controllers.""" +"""Galaxy tool shed controllers.""" --- a/templates/admin/forms/edit_form.mako +++ /dev/null @@ -1,137 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<script type="text/javascript"> -$(document).ready(function(){ - //hide the all of the element with class msg_body - $(".msg_body").hide(); - //toggle the componenet with class msg_body - $(".msg_head").click(function(){ - $(this).next(".msg_body").slideToggle(450); - }); -}); -</script> -<style type="text/css"> -.msg_head { - padding: 0px 0px; - cursor: pointer; -} - -} -</style> - -<%def name="render_selectbox_options( index, field_attr )"> - %if field_attr[0] == 'Type': - %if field_attr[1].get_selected( return_label=True ) == 'SelectField': - <% options = field_attr[2] %> - <div class="repeat-group-item"> - <div class="form-row"> - <label> Options</label> - %for i, option in enumerate(options): - <div class="form-row"> - <b> ${i+1}</b> - ${option[1].get_html()} - <input type="submit" name="removeoption_${index}_${i}" value="Remove"/> - </div> - %endfor - </div> - </div> - <div class="form-row"> - <input type="submit" name="addoption_${index}" value="Add"/> - </div> - %endif - %endif -</%def> - -<%def name="render_field( index, field, saved )"> - %if saved: - <h4 class="msg_head"> - <div class="form-row">${index+1}. ${field[0][1].value} (${field[2][1].get_selected( return_value=True )})</div> - </h4> - <div class="msg_body"> - %else: - <div class="msg_body2"> - %endif - <div class="repeat-group-item"> - %for field_attr in field: - <div class="form-row"> - <label>${field_attr[0]}</label> - ${field_attr[1].get_html()} - ${render_selectbox_options( index, field_attr )} - </div> - %endfor - <div class="form-row"> - <input type="submit" name="remove_button" value="Remove field ${index+1}"/> - </div> - </div> - </div> -</%def> - -<%def name="render_layout( index, widget )"> - <div class="repeat-group-item"> - <div class="form-row"> - <b> ${index+1}</b> - ${widget.get_html()} - <input type="submit" name="remove_layout_grid_button" value="Remove grid ${index+1}"/> - </div> - </div> -</%def> - -<div class="toolForm"> - <div class="toolFormTitle">Edit form definition "${form.name}"</div> - <form id="edit_form" name="edit_form" action="${h.url_for( controller='forms', action='edit', id=trans.security.encode_id(form.current.id) )}" method="post" > - %if response_redirect: - <input type="hidden" name="response_redirect" value="${response_redirect}" size="40" /> - %endif - %for label, input in form_details: - <div class="form-row"> - ## TODO: RC, this will keep the form type select list label - ## from being displayed here. At this point, the select list is a hidden field. - ## Make sure this is the best solution to this problem. - %if label != 'Type': - <label>${label}</label> - %endif - <div style="float: left; width: 250px; margin-right: 10px;"> - ${input.get_html()} - </div> - <div style="clear: both"></div> - </div> - %endfor - %if current_form_type == trans.app.model.FormDefinition.types.SAMPLE: - <div class="toolFormTitle">Form Layout</div> - <div class="form-row"> - <label>Layout grid names</label> - </div> - %for index, lg in enumerate(layout_grids): - ${render_layout( index, lg )} - %endfor - <div class="form-row"> - <input type="submit" name="add_layout_grid" value="Add layout grid"/> - </div> - %endif - <div class="toolFormTitle">Fields (${len(form.fields)})</div> - %for ctr, field in enumerate(field_details): - %if ctr < len(form.fields): - ${render_field( ctr, field, True )} - %else: - ${render_field( ctr, field, False )} - %endif - %endfor - <div class="form-row"> - <input type="submit" name="add_field_button" value="Add field"/> - </div> - <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_changes_button" value="Save"/> - </div> - </form> -</div> --- a/lib/galaxy/security/__init__.py +++ b/lib/galaxy/security/__init__.py @@ -19,14 +19,14 @@ class Action( object ): class RBACAgent: """Class that handles galaxy security""" permitted_actions = Bunch( - DATASET_MANAGE_PERMISSIONS = Action( "manage permissions", "Role members can manage the roles associated with permissions on this dataset", "grant" ), - DATASET_ACCESS = Action( "access", "Role members can import this dataset into their history for analysis", "restrict" ), - LIBRARY_ACCESS = Action( "access library", "Restrict access to this library to only role members", "restrict" ), - LIBRARY_ADD = Action( "add library item", "Role members can add library items to this library item", "grant" ), - LIBRARY_MODIFY = Action( "modify library item", "Role members can modify this library item", "grant" ), - LIBRARY_MANAGE = Action( "manage library permissions", "Role members can manage roles associated with permissions on this library item", "grant" ), + DATASET_MANAGE_PERMISSIONS = Action( "manage permissions", "Users having associated role can manage the roles associated with permissions on this dataset", "grant" ), + DATASET_ACCESS = Action( "access", "Users having associated role can import this dataset into their history for analysis", "restrict" ), + LIBRARY_ACCESS = Action( "access library", "Restrict access to this library to only users having assocaited role", "restrict" ), + LIBRARY_ADD = Action( "add library item", "Users having associated role can add library items to this library item", "grant" ), + LIBRARY_MODIFY = Action( "modify library item", "Users having associated role can modify this library item", "grant" ), + LIBRARY_MANAGE = Action( "manage library permissions", "Users having associated role can manage roles associated with permissions on this library item", "grant" ), # Request type permissions - REQUEST_TYPE_ACCESS = Action( "access request_type", "Restrict access to this request_type to only role members", "restrict" ) + REQUEST_TYPE_ACCESS = Action( "access request_type", "Restrict access to only users having associated role", "restrict" ) ) def get_action( self, name, default=None ): @@ -912,9 +912,6 @@ class GalaxyRBACAgent( RBACAgent ): else: hidden_folder_ids = '%d' % sub_folder.id return False, hidden_folder_ids - # - # RequestType Permissions - # def can_access_request_type( self, roles, request_type ): action = self.permitted_actions.REQUEST_TYPE_ACCESS request_type_actions = [] --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -312,6 +312,9 @@ use_interactive = True # -- Beta features +# Enable Galaxy to communicate directly with a sequencer +#enable_sequencer_communication = False + # Enable Galaxy's built-in visualization module, Trackster. #enable_tracks = False --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -1494,6 +1494,9 @@ class MetadataFile( object ): return os.path.abspath( os.path.join( path, "metadata_%d.dat" % self.id ) ) class FormDefinition( object ): + # The following form_builder classes are supported by the FormDefinition class. + # AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField + supported_field_types = [ AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField ] types = Bunch( REQUEST = 'Sequencing Request Form', SAMPLE = 'Sequencing Sample Form', LIBRARY_INFO_TEMPLATE = 'Library information template', @@ -1587,6 +1590,19 @@ class FormDefinition( object ): widget=field_widget, helptext=helptext ) ) return widgets + def field_as_html( self, field ): + """Generates disabled html for a field""" + type = field[ 'type' ] + form_field = None + for field_type in self.supported_field_types: + if type == field_type.__name__: + # Name it AddressField, CheckboxField, etc. + form_field = field_type( type ) + break + if form_field: + return form_field.get_html( disabled=True ) + # Return None if unsupported field type + return None class FormDefinitionCurrent( object ): def __init__(self, form_definition=None): --- a/templates/webapps/galaxy/admin/index.mako +++ b/templates/webapps/galaxy/admin/index.mako @@ -101,11 +101,11 @@ </div><div class="toolSectionPad"></div><div class="toolSectionTitle"> - <span>Forms</span> + <span>Form Definitions</span></div><div class="toolSectionBody"><div class="toolSectionBg"> - <div class="toolTitle"><a href="${h.url_for( controller='forms', action='manage' )}" target="galaxy_main">Manage forms</a></div> + <div class="toolTitle"><a href="${h.url_for( controller='forms', action='manage' )}" target="galaxy_main">Manage form definitions</a></div></div></div><div class="toolSectionPad"></div> @@ -114,7 +114,7 @@ </div><div class="toolSectionBody"><div class="toolSectionBg"> - <div class="toolTitle"><a href="${h.url_for( controller='requests_admin', action='browse_request_types' )}" target="galaxy_main">Sequencer configurations</a></div> + <div class="toolTitle"><a href="${h.url_for( controller='requests_admin', action='browse_request_types' )}" target="galaxy_main">Manage sequencers</a></div><div class="toolTitle"><a href="${h.url_for( controller='requests_admin', action='browse_requests' )}" target="galaxy_main">Sequencing requests</a></div><div class="toolTitle"><a href="${h.url_for( controller='requests_common', action='find_samples', cntrller='requests_admin' )}" target="galaxy_main">Find samples</a></div></div> --- a/templates/admin/requests/view_request_type.mako +++ b/templates/admin/requests/view_request_type.mako @@ -1,78 +1,102 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> +<% + states_list = request_type.states + can_edit_permissions = not request_type.deleted + can_delete = not request_type.deleted + can_undelete = request_type.deleted +%> + +<br/><br/> +<ul class="manage-table-actions"> + %if can_edit_permissions: + <li><a class="action-button" href="${h.url_for( controller='requests_admin', action='request_type_permissions', id=trans.security.encode_id( request_type.id ) )}">Edit permissions</a></li> + %endif + %if can_delete: + <li><a class="action-button" href="${h.url_for( controller='requests_admin', action='delete_request_type', id=trans.security.encode_id( request_type.id ) )}">Delete</a></li> + %endif + %if can_undelete: + <li><a class="action-button" href="${h.url_for( controller='requests_common', action='undelete_request_type', id=trans.security.encode_id( request_type.id ) )}">Undelete</a></li> + %endif +</ul> + %if message: ${render_msg( message, status )} %endif -<% states_list = request_type.states %> - -<h2>Sequencer Configuration "${request_type.name}"</h2> - <div class="toolForm"> - <div class="toolFormTitle">Sequencer configuration information</div> + <div class="toolFormTitle">"${request_type.name}" sequencer configuration</div> + <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> +<p/> +<div class="toolForm"> + <div class="toolFormTitle">Sample states defined for this sequencer configuration</div> + %for state in states_list: + <div class="form-row"> + <label>${state.name}</label> + ${state.desc} + </div> + <div style="clear: both"></div> + %endfor +</div> +<p/> +<div class="toolForm"> + <div class="toolFormTitle">Sequencer login information</div><form name="view_request_type" action="${h.url_for( controller='requests_admin', action='create_request_type', rt_id=trans.security.encode_id( request_type.id ))}" method="post" ><div class="form-row"> - <label>Name</label> - ${request_type.name} - <div style="clear: both"></div> + This information is needed only if you will transfer datasets from the sequencer to a target Galaxy data library </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="toolFormTitle">Possible sample states</div> - %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 class="toolFormTitle">Sequencer information</div> - <div class="form-row"> - This information is only needed for transferring data from sequencer to Galaxy - </div> + <div style="clear: both"></div><div class="form-row"><label>Hostname or IP Address:</label><input type="text" name="host" value="${request_type.datatx_info['host']}" size="40"/></div> + <div style="clear: both"></div><div class="form-row"><label>Username:</label><input type="text" name="username" value="${request_type.datatx_info['username']}" size="40"/></div> + <div style="clear: both"></div><div class="form-row"><label>Password:</label><input type="password" name="password" value="${request_type.datatx_info['password']}" size="40"/></div> + <div style="clear: both"></div><div class="form-row"><label>Data directory:</label><input type="text" name="data_dir" value="${request_type.datatx_info.get('data_dir', '')}" size="40"/></div> + <div style="clear: both"></div><div class="form-row"> - <label>Add experiment name and the sample name to the dataset name?</label> + <label>Prepend the experiment name and sample name to the dataset name?</label> ${rename_dataset_select_field.get_html()} <div class="toolParamHelp" style="clear: both;"> - The datasets are renamed by prepending the experiment name and the sample name to the dataset name. <br/>This - makes sure that dataset names remain unique in Galaxy even when they have the - same name in the sequencer. + Galaxy datasets are renamed by prepending the experiment name and sample name to the dataset name, ensuring<br/> + dataset names remain unique in Galaxy even when multiple datasets have the same name on the sequencer. </div></div> + <div style="clear: both"></div><div class="form-row"> - <input type="submit" name="save_changes" value="Save changes"/> + <input type="submit" name="save_changes" value="Save changes"/></div> + <div style="clear: both"></div></form></div> --- a/templates/library/common/ldda_permissions.mako +++ b/templates/library/common/ldda_permissions.mako @@ -12,9 +12,7 @@ <br/><br/><ul class="manage-table-actions"> - <li> - <a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=library_id, use_panels=use_panels, show_deleted=show_deleted )}"><span>Browse this data library</span></a> - </li> + <li><a class="action-button" href="${h.url_for( controller='library_common', action='browse_library', cntrller=cntrller, id=library_id, use_panels=use_panels, show_deleted=show_deleted )}"><span>Browse this data library</span></a></li></ul> %if message: --- a/lib/galaxy/web/controllers/forms.py +++ b/lib/galaxy/web/controllers/forms.py @@ -105,7 +105,7 @@ class Forms( BaseController ): action='manage', message='Invalid form', status='error' ) ) - return trans.fill_template( '/admin/forms/show_form_read_only.mako', + return trans.fill_template( '/admin/forms/view_form_definition.mako', form_definition=fdc.latest_form ) def __form_types_widget(self, trans, selected='none'): form_type_selectbox = SelectField( 'form_type_selectbox' ) @@ -223,8 +223,13 @@ class Forms( BaseController ): # unsaved form, with the error message if not fd_new: current_form = self.__get_form( trans, **kwd ) - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status='error', response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status='error', + response_redirect=response_redirect, + **kwd ) # everything went fine. form saved successfully. Show the saved form or redirect # to response_redirect if appropriate. if response_redirect: @@ -232,8 +237,13 @@ class Forms( BaseController ): fd = fd_new current_form = self.__get_saved_form( fd ) message = "The form '%s' has been updated with the changes." % fd.name - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) # # Add a layout grid # @@ -241,8 +251,13 @@ class Forms( BaseController ): current_form = self.__get_form( trans, **kwd ) current_form['layout'].append('') # show the form again - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) # # Delete a layout grid # @@ -250,8 +265,13 @@ class Forms( BaseController ): current_form = self.__get_form( trans, **kwd ) index = int( kwd[ 'remove_layout_grid_button' ].split( ' ' )[2] ) - 1 del current_form['layout'][index] - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) # # Add a field # @@ -259,8 +279,13 @@ class Forms( BaseController ): current_form = self.__get_form( trans, **kwd ) current_form['fields'].append( self.empty_field ) # show the form again with one empty field - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) # # Delete a field # @@ -269,8 +294,13 @@ class Forms( BaseController ): # find the index of the field to be removed from the remove button label index = int( kwd[ 'remove_button' ].split( ' ' )[2] ) - 1 del current_form['fields'][index] - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) # # Add SelectField option # @@ -286,15 +316,25 @@ class Forms( BaseController ): # elif params.get( 'refresh', False ): current_form = self.__get_form( trans, **kwd ) - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) # # Show the form for editing # else: current_form = self.__get_saved_form( fd ) - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) def __add_selectbox_option( self, trans, fd, message, status, response_redirect=None, **kwd ): ''' @@ -311,13 +351,22 @@ class Forms( BaseController ): break if index == -1: # something wrong happened - return self.__show( trans=trans, form=fd, current_form=current_form, + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, message='Error in adding selectfield option', - status='error', response_redirect=response_redirect, **kwd ) + status='error', + response_redirect=response_redirect, + **kwd ) # add an empty option current_form[ 'fields' ][ index ][ 'selectlist' ].append( '' ) - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) def __remove_selectbox_option( self, trans, fd, message, status, response_redirect=None, **kwd ): ''' This method removes a selectbox option. The kwd dict searched for @@ -334,13 +383,22 @@ class Forms( BaseController ): break if option == -1: # something wrong happened - return self.__show( trans=trans, form=fd, current_form=current_form, + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, message='Error in removing selectfield option', - status='error', response_redirect=response_redirect, **kwd ) + status='error', + response_redirect=response_redirect, + **kwd ) # remove the option del current_form[ 'fields' ][ index ][ 'selectlist' ][ option ] - return self.__show( trans=trans, form=fd, current_form=current_form, - message=message, status=status, response_redirect=response_redirect, **kwd ) + return self.__show( trans=trans, + form_definition=fd, + current_form=current_form, + message=message, + status=status, + response_redirect=response_redirect, + **kwd ) def __get_field(self, index, **kwd): @@ -356,22 +414,22 @@ class Forms( BaseController ): layout = params.get( 'field_layout_%i' % index, '' ) default = params.get( 'field_default_%i' % index, '' ) if field_type == 'SelectField': - selectlist = self.__get_selectbox_options(index, **kwd) - return {'label': name, - 'helptext': helptext, - 'visible': True, - 'required': required, - 'type': field_type, - 'selectlist': selectlist, - 'layout': layout, - 'default': default } - return {'label': name, - 'helptext': helptext, - 'visible': True, - 'required': required, - 'type': field_type, - 'layout': layout, - 'default': default} + options = self.__get_selectbox_options(index, **kwd) + return { 'label': name, + 'helptext': helptext, + 'visible': True, + 'required': required, + 'type': field_type, + 'selectlist': selectlist, + 'layout': layout, + 'default': default } + return { 'label': name, + 'helptext': helptext, + 'visible': True, + 'required': required, + 'type': field_type, + 'layout': layout, + 'default': default } def __get_selectbox_options(self, index, **kwd): ''' This method gets all the options entered by the user for field when @@ -452,23 +510,23 @@ class Forms( BaseController ): continue options = row[5].split(',') if len(row) >= 8: - fields.append({'label': row[0], - 'helptext': row[1], - 'visible': row[2], - 'required': row[3], - 'type': row[4], - 'selectlist': options, - 'layout':row[6], - 'default': row[7]}) + fields.append( { 'label': row[0], + 'helptext': row[1], + 'visible': row[2], + 'required': row[3], + 'type': row[4], + 'selectlist': options, + 'layout':row[6], + 'default': row[7] } ) layouts.add(row[6]) else: - fields.append({'label': row[0], - 'helptext': row[1], - 'visible': row[2], - 'required': row[3], - 'type': row[4], - 'selectlist': options, - 'default': row[6]}) + fields.append( { 'label': row[0], + 'helptext': row[1], + 'visible': row[2], + 'required': row[3], + 'type': row[4], + 'selectlist': options, + 'default': row[6] } ) except: return trans.response.send_redirect( web.url_for( controller='forms', action='create_form', @@ -570,8 +628,8 @@ class Forms( BaseController ): refresh_on_change_values=['SelectField']) if field_type: field['type'] = unicode(field_type) - if field_type == 'SelectField' and not field['selectlist']: - field['selectlist'] = ['', ''] + if field_type == 'SelectField' and not field[ 'selectlist' ]: + field[ 'selectlist' ] = ['', ''] # if the form is for defining samples, then use the sample field types # which does not include TextArea & AddressField if form_type == trans.app.model.FormDefinition.types.SAMPLE: @@ -605,8 +663,8 @@ class Forms( BaseController ): self.layout_selectbox.add_option("%i. %s" %(i+1, grid_name), i) def selectbox_ui(self, field): self.selectbox_options = [] - if field['selectlist']: - for ctr, option in enumerate(field['selectlist']): + if field[ 'selectlist' ]: + for ctr, option in enumerate(field[ 'selectlist' ]): self.selectbox_options.append(('Option '+str(ctr+1), TextField('field_'+str(self.index)+'_option_'+str(ctr), 40, option))) @@ -628,17 +686,14 @@ class Forms( BaseController ): def label(self): return str(self.index)+'.'+self.label - def __show( self, trans, form, current_form, message='', status='done', response_redirect=None, **kwd ): - ''' - This method displays the form and any of the changes made to it, - The empty_form param allows for this method to simulate clicking - the "add_field_button" on the edit_form.mako page so that the page - is displayed with the first field to be added, saving a mouse click. - ''' + def __show( self, trans, form_definition, current_form, message='', status='done', response_redirect=None, **kwd ): + """ + Displays the form and any of the changes made to it, The empty_form param allows for this method to + simulate clicking the "add_field_button" on the edit_form_definition.mako page so that the page is + displayed with the first field to be added, saving a mouse click. + """ params = util.Params( kwd ) # name & description - # TODO: RC, I've changed Type to be a hidden field since it should not be displayed on the edit_form.mako - # template. Make sure this is the optimal solution for this problem. See my additional TODO in edit_form.mako. form_details = [ ( 'Name', TextField( 'name', 40, current_form[ 'name' ] ) ), ( 'Description', TextField( 'description', 40, current_form[ 'desc' ] ) ), ( 'Type', HiddenField( 'form_type_selectbox', current_form['type']) ) ] @@ -654,10 +709,10 @@ class Forms( BaseController ): else: field_ui = self.FieldUI( trans, None, index, field, form_type=current_form['type'] ) field_details.append( field_ui.get() ) - return trans.fill_template( '/admin/forms/edit_form.mako', + return trans.fill_template( '/admin/forms/edit_form_definition.mako', form_details=form_details, field_details=field_details, - form=form, + form_definition=form_definition, field_types=BaseField.form_field_types(), message=message, status=status, --- a/templates/admin/requests/create_request_type.mako +++ b/templates/admin/requests/create_request_type.mako @@ -69,12 +69,11 @@ <input type="text" name="data_dir" value="" size="40"/></div><div class="form-row"> - <label>Add experiment name and the sample name to the dataset name?</label> + <label>Prepend the experiment name and sample name to the dataset name?</label> ${rename_dataset_select_field.get_html()} <div class="toolParamHelp" style="clear: both;"> - The datasets are renamed by prepending the experiment name and the sample name to the dataset name. <br/>This - makes sure that dataset names remain unique in Galaxy even when they have the - same name in the sequencer. + Galaxy datasets are renamed by prepending the experiment name and sample name to the dataset name, ensuring<br/> + dataset names remain unique in Galaxy even when multiple datasets have the same name on the sequencer. </div></div><div class="form-row"> --- a/test/functional/test_library_security.py +++ b/test/functional/test_library_security.py @@ -393,8 +393,8 @@ class TestLibrarySecurity( TwillTestCase # admin_user is associated with role1, so should have all permissions on imported datasets check_edit_page( latest_3_lddas, strings_displayed=[ 'Manage dataset permissions on', - 'Role members can manage the roles associated with permissions on this dataset', - 'Role members can import this dataset into their history for analysis' ] ) + 'can manage the roles associated with permissions on this dataset', + 'can import this dataset into their history for analysis' ] ) self.logout() # regular_user1 is associated with role1, so should have all permissions on imported datasets self.login( email=regular_user1.email ) @@ -423,8 +423,8 @@ class TestLibrarySecurity( TwillTestCase check_edit_page( latest_3_lddas, strings_displayed=[ 'View Permissions' ], strings_not_displayed=[ 'Manage dataset permissions on', - 'Role members can manage roles associated with permissions on this library item', - 'Role members can import this dataset into their history for analysis' ] ) + 'can manage roles associated with permissions on this library item', + 'can import this dataset into their history for analysis' ] ) def test_060_restrict_access_to_library2( self ): """Testing restricting access to library2""" # Logged in as admin_user --- a/templates/admin/forms/show_form_read_only.mako +++ /dev/null @@ -1,115 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - -<%def name="render_grid( grid_index, grid_name, fields_dict )"> - %if grid_name: - <div class="form-row"> - <h4>${grid_name}</h4> - </div> - %endif - <div style="clear: both"></div> - <table class="grid"> - <thead> - <tr> - %for index, field in fields_dict.items(): - <th> - ${field['label']} - <div class="toolParamHelp" style="clear: both;"> - <i>${field['helptext']}</i> - </div> - </th> - %endfor - <th></th> - </tr> - <thead> - <tbody> - <tr> - %for index, field in fields_dict.items(): - <td> - <div>${field['required']}</div> -## <div>${field['type']}</div> - </td> - %endfor - <th></th> - </tr> - %for index, field in fields_dict.items(): - <td> -## <div>${field['required']}</div> - <div><i>Type:</i></div> - <div>${field['type']}</div> - </td> - %endfor - <th></th> - </tr> - <tr> - %for index, field in fields_dict.items(): - <td> - %if field['type'] == 'SelectField': - <div><i>Options:</i></div> - %for option in field['selectlist']: - <div>${option}</div> - %endfor - %endif - </td> - %endfor - <th></th> - </tr> - <tbody> - </table> -</%def> - -<div class="toolForm"> - %if form_definition.desc: - <div class="toolFormTitle">${form_definition.name} - <i> ${form_definition.desc}</i> (${form_definition.type}) - <a id="form_definition-${form_definition.id}-popup" class="popup-arrow" style="display: none;">▼</a> - <div popupmenu="form_definition-${form_definition.id}-popup"> - <a class="action-button" href="${h.url_for( controller='forms', action='manage', operation='Edit', id=trans.security.encode_id(form_definition.current.id) )}">Edit</a> - </div> - </div> - %else: - <div class="toolFormTitle">${form_definition.name} (${form_definition.type}) - <a id="form_definition-${form_definition.id}-popup" class="popup-arrow" style="display: none;">▼</a> - <div popupmenu="form_definition-${form_definition.id}-popup"> - <a class="action-button" href="${h.url_for( controller='forms', action='manage', operation='Edit', id=trans.security.encode_id(form_definition.current.id) )}">Edit</a> - </div> - </div> - %endif - <form name="library" action="${h.url_for( controller='forms', action='manage' )}" method="post" > - %if form_definition.type == trans.app.model.FormDefinition.types.SAMPLE: - %if not len(form_definition.layout): - ${render_grid( 0, '', form_definition.grid_fields( None ) )} - %else: - %for grid_index, grid_name in enumerate(form_definition.layout): - ${render_grid( grid_index, grid_name, form_definition.grid_fields( grid_index ) )} - %endfor - %endif - %else: - %for index, field in enumerate(form_definition.fields): - <div class="form-row"> - <label>${field['label']}</label> - %if field['helptext']: - <div class="toolParamHelp" style="clear: both;"> - <i>${field['helptext']}</i> - </div> - %endif - <div>${field['required']}</div> - <i>Type: </i> ${field['type']} - %if field['type'] == 'SelectField': - <div> - <div><i>Options:</i></div> - %for option in field['selectlist']: - <div>${option}</div> - %endfor - </div> - %endif - </div> - <div style="clear: both"></div> - %endfor - %endif - </form> - </div> -</div> --- a/lib/galaxy/web/controllers/requests_admin.py +++ b/lib/galaxy/web/controllers/requests_admin.py @@ -57,7 +57,7 @@ class RequestTypeGrid( grids.Grid ): columns = [ NameColumn( "Name", key="name", - link=( lambda item: iff( item.deleted, None, dict( operation="view", id=item.id ) ) ), + link=( lambda item: iff( item.deleted, None, dict( operation="view_request_type", id=item.id ) ) ), attach_popup=True, filterable="advanced" ), DescriptionColumn( "Description", @@ -78,12 +78,12 @@ class RequestTypeGrid( grids.Grid ): visible=False, filterable="standard" ) ) operations = [ - grids.GridOperation( "Permissions", allow_multiple=False, condition=( lambda item: not item.deleted ) ), + grids.GridOperation( "Edit permissions", allow_multiple=False, condition=( lambda item: not item.deleted ) ), grids.GridOperation( "Delete", allow_multiple=True, condition=( lambda item: not item.deleted ) ), grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ) ), ] global_actions = [ - grids.GridAction( "Create new sequencer configuration", dict( controller='requests_admin', action='create_request_type' ) ) + grids.GridAction( "Create new configuration", dict( controller='requests_admin', action='create_request_type' ) ) ] class DataTransferGrid( grids.Grid ): @@ -638,23 +638,21 @@ class RequestsAdmin( BaseController, Use err_msg += "Set your API Key in your User Preferences to transfer datasets." # check if library_import_dir is set if not trans.app.config.library_import_dir: - err_msg = "'The library_import_dir' setting is not set in the Galaxy config file." + err_msg = "'The library_import_dir' setting is not correctly set in the Galaxy config file." # check the RabbitMQ server settings in the config file for k, v in trans.app.config.amqp.items(): if not v: - err_msg += 'Set RabbitMQ server settings in the "galaxy_amqp" section of the Galaxy config file. %s is not set.' % k + err_msg += 'Set RabbitMQ server settings in the "galaxy_amqp" section of the Galaxy config file, specifically "%s" is not set.' % k break return err_msg @web.expose @web.require_admin def initiate_data_transfer( self, trans, sample_id, sample_datasets=[], sample_dataset_id='' ): ''' - This method initiates the transfer of the datasets from the sequencer. It - happens in the following steps: - - The current admin user needs to have LIBRARY_ADD permission for the - target library and folder - - Create an XML message encapsulating all the data transfer info and send it - to the message queue (RabbitMQ broker) + Initiate the transfer of the datasets from the sequencer to the target Galaxy data library: + - The admin user must have LIBRARY_ADD permission for the target library and folder + - Create an XML message encapsulating all the data transfer information and send it + to the message queue (RabbitMQ broker). ''' try: sample = trans.sa_session.query( trans.model.Sample ).get( trans.security.decode_id( sample_id ) ) @@ -735,13 +733,13 @@ class RequestsAdmin( BaseController, Use obj_id = kwd.get( 'id', None ) if operation == "view_form_definition": return self.view_form_definition( trans, **kwd ) - elif operation == "view": + elif operation == "view_request_type": return self.view_request_type( trans, **kwd ) elif operation == "delete": return self.delete_request_type( trans, **kwd ) elif operation == "undelete": return self.undelete_request_type( trans, **kwd ) - elif operation == "permissions": + elif operation == "edit permissions": return self.request_type_permissions( trans, **kwd ) # Render the grid view return self.requesttype_grid( trans, **kwd ) @@ -888,11 +886,9 @@ class RequestsAdmin( BaseController, Use request_type = trans.sa_session.query( trans.model.RequestType ).get( trans.security.decode_id( request_type_id ) ) except: return invalid_id_redirect( trans, 'requests_admin', request_type_id, action='browse_request_types' ) - forms = self.get_all_forms( trans ) rename_dataset_select_field = self.__build_rename_dataset_select_field( trans, request_type ) return trans.fill_template( '/admin/requests/view_request_type.mako', request_type=request_type, - forms=forms, rename_dataset_select_field=rename_dataset_select_field ) @web.expose @web.require_admin @@ -902,7 +898,7 @@ class RequestsAdmin( BaseController, Use form_definition = trans.sa_session.query( trans.model.FormDefinition ).get( trans.security.decode_id( form_definition_id ) ) except: return invalid_id_redirect( trans, 'requests_admin', form_definition_id, action='browse_request_types' ) - return trans.fill_template( '/admin/forms/show_form_read_only.mako', + return trans.fill_template( '/admin/forms/view_form_definition.mako', form_definition=form_definition ) @web.expose @web.require_admin --- a/test/base/twilltestcase.py +++ b/test/base/twilltestcase.py @@ -1494,7 +1494,7 @@ class TwillTestCase( unittest.TestCase ) def view_request_type( self, request_type_id, request_type_name, sample_states, strings_displayed=[] ): '''View request_type details''' self.home() - self.visit_url( "%s/requests_admin/browse_request_types?operation=view&id=%s" % ( self.url, request_type_id ) ) + self.visit_url( "%s/requests_admin/view_request_type?id=%s" % ( self.url, request_type_id ) ) self.check_page_for_string( 'Sequencer configuration information' ) self.check_page_for_string( request_type_name ) for name, desc in sample_states: --- /dev/null +++ b/templates/admin/forms/edit_form_definition.mako @@ -0,0 +1,140 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<script type="text/javascript"> +$(document).ready(function(){ + //hide the all of the element with class msg_body + $(".msg_body").hide(); + //toggle the componenet with class msg_body + $(".msg_head").click(function(){ + $(this).next(".msg_body").slideToggle(450); + }); +}); +</script> +<style type="text/css"> +.msg_head { + padding: 0px 0px; + cursor: pointer; +} + +} +</style> + +<%def name="render_selectbox_options( index, field_attr )"> + %if field_attr[0] == 'Type': + %if field_attr[1].get_selected( return_label=True ) == 'SelectField': + <% options = field_attr[2] %> + <div class="repeat-group-item"> + <div class="form-row"> + <label> Options</label> + %for i, option in enumerate(options): + <div class="form-row"> + <b> ${i+1}</b> + ${option[1].get_html()} + <input type="submit" name="removeoption_${index}_${i}" value="Remove"/> + </div> + %endfor + </div> + </div> + <div class="form-row"> + <input type="submit" name="addoption_${index}" value="Add"/> + </div> + %endif + %endif +</%def> + +<%def name="render_field( index, field, saved )"> + %if saved: + <h4 class="msg_head"> + <div class="form-row">${index+1}. ${field[0][1].value} (${field[2][1].get_selected( return_value=True )})</div> + </h4> + <div class="msg_body"> + %else: + <div class="msg_body2"> + %endif + <div class="repeat-group-item"> + %for field_attr in field: + <div class="form-row"> + <label>${field_attr[0]}</label> + ${field_attr[1].get_html()} + ${render_selectbox_options( index, field_attr )} + </div> + %endfor + <div class="form-row"> + <input type="submit" name="remove_button" value="Remove field ${index+1}"/> + </div> + </div> + </div> +</%def> + +<%def name="render_layout( index, widget )"> + <div class="repeat-group-item"> + <div class="form-row"> + <b> ${index+1}</b> + ${widget.get_html()} + <input type="submit" name="remove_layout_grid_button" value="Remove grid ${index+1}"/> + </div> + </div> +</%def> + +<br/><br/> +<ul class="manage-table-actions"> + <li><a class="action-button" href="${h.url_for( controller='forms', action='manage', operation='View', id=trans.security.encode_id( form_definition.current.id ) )}">View</a></li> +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">Edit form definition "${form_definition.name}"</div> + <form id="edit_form_definition" name="edit_form_definition" action="${h.url_for( controller='forms', action='edit', id=trans.security.encode_id( form_definition.current.id ) )}" method="post" > + %if response_redirect: + <input type="hidden" name="response_redirect" value="${response_redirect}" size="40" /> + %endif + %for label, input in form_details: + <div class="form-row"> + %if label != 'Type': + <label>${label}</label> + %endif + <div style="float: left; width: 250px; margin-right: 10px;"> + ${input.get_html()} + </div> + <div style="clear: both"></div> + </div> + %endfor + %if current_form_type == trans.app.model.FormDefinition.types.SAMPLE: + <div class="toolFormTitle">Form Layout</div> + <div class="form-row"> + <label>Layout grid names</label> + </div> + %for index, lg in enumerate( layout_grids ): + ${render_layout( index, lg )} + %endfor + <div class="form-row"> + <input type="submit" name="add_layout_grid" value="Add layout grid"/> + </div> + %endif + <div class="toolFormTitle">Form fields</div> + %for ctr, field in enumerate(field_details): + %if ctr < len( form_definition.fields ): + ${render_field( ctr, field, True )} + %else: + ${render_field( ctr, field, False )} + %endif + %endfor + <div class="form-row"> + <input type="submit" name="add_field_button" value="Add field"/> + </div> + <div class="form-row"> + ## TODO: Eliminate the need for this hidden refresh param + <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_changes_button" value="Save"/> + </div> + </form> +</div> --- a/templates/webapps/galaxy/admin/center.mako +++ b/templates/webapps/galaxy/admin/center.mako @@ -51,9 +51,9 @@ be granted to users (a library item is one of: a data library, a library folder, a library dataset). <p/><ul> - <li><strong>add library item</strong> - Role members can add library items to this data library or folder</li> - <li><strong>modify library item</strong> - Role members can modify this library item</li> - <li><strong>manage library permissions</strong> - Role members can manage permissions applied to this library item</li> + <li><strong>add library item</strong> - Users that have the role can add library items to this data library or folder</li> + <li><strong>modify library item</strong> - Users that have the role can modify this library item</li> + <li><strong>manage library permissions</strong> - Users that have the role can manage permissions applied to this library item</li></ul><p/> The default behavior is for no permissions to be applied to a data library item, but applied permissions are inherited downward (with the exception --- a/templates/admin/requests/request_type_permissions.mako +++ b/templates/admin/requests/request_type_permissions.mako @@ -1,11 +1,6 @@ <%inherit file="/base.mako"/><%namespace file="/message.mako" import="render_msg" /> - -%if message: - ${render_msg( message, status )} -%endif - <script type="text/javascript"> $( document ).ready( function () { $( '.role_add_button' ).click( function() { @@ -28,19 +23,23 @@ }); </script> +<br/><br/> +<ul class="manage-table-actions"> + <li><a class="action-button" href="${h.url_for( controller='requests_admin', action='view_request_type', id=trans.security.encode_id( request_type.id ) )}"><span>Browse this configuration</span></a></li> +</ul> + +%if message: + ${render_msg( message, status )} +%endif <div class="toolForm"> - <div class="toolFormTitle">Manage permissions on "${request_type.name}"</div> + <div class="toolFormTitle">Manage access permissions on sequencer interface "${request_type.name}"</div><div class="toolFormBody"><form name="request_type_permissions" id="request_type_permissions" action="${h.url_for( controller='requests_admin', action='request_type_permissions', id=trans.security.encode_id( request_type.id ) )}" method="post"><div class="form-row"><% - obj_name = request_type.name current_actions = request_type.actions - permitted_actions = trans.app.model.RequestType.permitted_actions.items() - action = trans.app.model.RequestType.permitted_actions.REQUEST_TYPE_ACCESS - obj_str = 'request_type %s' % obj_name - obj_type = 'request_type' + action = trans.app.security_agent.permitted_actions.REQUEST_TYPE_ACCESS all_roles = roles action_key = 'REQUEST_TYPE_ACCESS' @@ -51,9 +50,7 @@ in_roles.add( a.role ) out_roles = filter( lambda x: x not in in_roles, all_roles ) %> - <p> - <b>access sequencer configuration:</b> Restrict access to this sequencer configuration to only role members - </p> + ${action.description}<br/><br/><div style="width: 100%; white-space: nowrap;"><div style="float: left; width: 50%;"> Roles associated:<br/> @@ -74,7 +71,6 @@ <input type="submit" id="${action_key}_add_button" class="role_add_button" value="<<"/></div></div> -## </%def></div><div class="form-row"><input type="submit" name="update_roles_button" value="Save"/> --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -42,6 +42,8 @@ class Configuration( object ): self.cookie_path = kwargs.get( "cookie_path", "/" ) # web API self.enable_api = string_as_bool( kwargs.get( 'enable_api', False ) ) + # Communication with a sequencer + self.enable_sequencer_communication = string_as_bool( kwargs.get( 'enable_sequencer_communication', False ) ) # dataset Track files self.track_store_path = kwargs.get( "track_store_path", "${extra_files_path}/tracks") self.tool_path = resolve_path( kwargs.get( "tool_path", "tools" ), self.root ) --- /dev/null +++ b/templates/admin/forms/view_form_definition.mako @@ -0,0 +1,85 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +%if message: + ${render_msg( message, status )} +%endif + +<%def name="render_grid( grid_index, grid_name, fields_dict )"> + %if grid_name: + <div class="form-row"> + <label>${grid_name}</label> + </div> + %endif + <div style="clear: both"></div> + <table class="grid"> + <thead> + <tr> + %for index, field in fields_dict.items(): + <th>${field[ 'label' ]}</th> + %endfor + </tr> + <thead> + <tbody> + <tr> + %for index, field in fields_dict.items(): + <td> + ${field[ 'type' ]}: ${form_definition.field_as_html( field )}<br/> + <div class="toolParamHelp" style="clear: both;"> + <i>${field[ 'helptext' ]}</i> - (${field[ 'required' ]}) + </div> + %if field[ 'type' ] == 'SelectField': + <div class="toolParamHelp" style="clear: both;"> + <label>Options:</label> + %for option in field[ 'selectlist' ]: + ${option} + %endfor + </div> + %endif + </td> + %endfor + </tr> + <tbody> + </table> +</%def> + +<br/><br/> +<ul class="manage-table-actions"> + <li><a class="action-button" href="${h.url_for( controller='forms', action='manage', operation='Edit', id=trans.security.encode_id( form_definition.current.id ) )}">Edit</a></li> +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">Form definition "${form_definition.name}"</div> + %if form_definition.type == trans.app.model.FormDefinition.types.SAMPLE: + %if form_definition.layout: + %for grid_index, grid_name in enumerate( form_definition.layout ): + ${render_grid( grid_index, grid_name, form_definition.grid_fields( grid_index ) )} + %endfor + %else: + ${render_grid( 0, '', form_definition.grid_fields( None ) )} + %endif + %else: + %for index, field in enumerate( form_definition.fields ): + <div class="form-row"> + <label>${field[ 'label' ]}</label> + ${field[ 'type' ]}: ${form_definition.field_as_html( field )} + <div class="toolParamHelp" style="clear: both;"> + <i>${field[ 'helptext' ]}</i> - (${field[ 'required' ]}) + </div> + %if field[ 'type' ] == 'SelectField': + <div class="toolParamHelp" style="clear: both;"> + <label>Options:</label> + %for option in field[ 'selectlist' ]: + ${option} + %endfor + </div> + %endif + </div> + <div style="clear: both"></div> + %endfor + %endif +</div> --- a/templates/requests/common/common.mako +++ b/templates/requests/common/common.mako @@ -430,7 +430,7 @@ <input type="text" name="sample_${index}_field_${field_index}" value="${sample_values[field_index]}" size="7"/> %elif field_type == 'SelectField': <select name="sample_${index}_field_${field_index}" last_selected_value="2"> - %for option_index, option in enumerate(field['selectlist']): + %for option_index, option in enumerate(field[ 'selectlist' ]): %if option == sample_values[field_index]: <option value="${option}" selected>${option}</option> %else: