Add the ability to move data library items within a data library or between data libraries.

This commit is contained in:
Greg Von Kuster
2011-03-08 15:50:19 -05:00
parent a97da4abcf
commit b94de80659
7 changed files with 477 additions and 128 deletions
+22
View File
@@ -941,6 +941,28 @@ class Library( object, APIItem ):
self.description = description
self.synopsis = synopsis
self.root_folder = root_folder
def get_active_folders( self, folder, folders=None ):
# TODO: should we make sure the library is not deleted?
def sort_by_attr( seq, attr ):
"""
Sort the sequence of objects by object's attribute
Arguments:
seq - the list or any sequence (including immutable one) of objects to sort.
attr - the name of attribute to sort by
"""
# Use the "Schwartzian transform"
# Create the auxiliary list of tuples where every i-th tuple has form
# (seq[i].attr, i, seq[i]) and sort it. The second item of tuple is needed not
# only to provide stable sorting, but mainly to eliminate comparison of objects
# (which can be expensive or prohibited) in case of equal attribute values.
intermed = map( None, map( getattr, seq, ( attr, ) * len( seq ) ), xrange( len( seq ) ), seq )
intermed.sort()
return map( operator.getitem, intermed, ( -1, ) * len( intermed ) )
if folders is None:
active_folders = [ folder ]
for active_folder in folder.active_folders:
active_folders.extend( self.get_active_folders( active_folder, folders ) )
return sort_by_attr( active_folders, 'id' )
def get_info_association( self, restrict=False, inherited=False ):
if self.info_association:
if not inherited or self.info_association[0].inheritable:
+254 -23
View File
@@ -1539,16 +1539,6 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
action = params.get( 'do_action', None )
if action == 'import_to_histories':
return trans.response.send_redirect( web.url_for( controller='library_common',
action='import_datasets_to_histories',
cntrller=cntrller,
library_id=library_id,
ldda_ids=ldda_ids,
use_panels=use_panels,
show_deleted=show_deleted,
message=message,
status=status ) )
lddas = []
error = False
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
@@ -1560,6 +1550,31 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
error = True
message = 'You must select an action to perform on the selected datasets.'
else:
if action == 'import_to_histories':
return trans.response.send_redirect( web.url_for( controller='library_common',
action='import_datasets_to_histories',
cntrller=cntrller,
library_id=library_id,
ldda_ids=ldda_ids,
use_panels=use_panels,
show_deleted=show_deleted,
message=message,
status=status ) )
if action == 'move':
if library_id in [ 'none', 'None', None ]:
source_library_id = ''
else:
source_library_id = library_id
return trans.response.send_redirect( web.url_for( controller='library_common',
action='move_library_item',
cntrller=cntrller,
source_library_id=source_library_id,
item_type='ldda',
item_id=ldda_ids,
use_panels=use_panels,
show_deleted=show_deleted,
message=message,
status=status ) )
ldda_ids = util.listify( ldda_ids )
for ldda_id in ldda_ids:
try:
@@ -1779,9 +1794,11 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
@web.expose
def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_ids='', new_history_name='', **kwd ):
# This method is called from one of the following places:
# - a menu option for a library dataset ( ldda_ids will be a singel dataset id )
# - a menu option for a library folder ( folder_id will have a value )
# - a menu option for a library dataset search result set ( ldda_ids will be a comma separated string of dataset ids )
# - a menu option for a library dataset ( ldda_ids is a single ldda id )
# - a menu option for a library folder ( folder_id has a value )
# - a select list option for acting on multiple selected datasets within a library
# ( ldda_ids is a comma separated string of ldda ids )
# - a menu option for a library dataset search result set ( ldda_ids is a comma separated string of ldda ids )
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
@@ -1799,13 +1816,7 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
folder = None
ldda_ids = util.listify( ldda_ids )
if ldda_ids:
# Check boxes cause 2 copies of each id to be included in the request
ldda_ids = map( trans.security.decode_id, ldda_ids )
unique_ldda_ids = []
for ldda_id in ldda_ids:
if ldda_id not in unique_ldda_ids:
unique_ldda_ids.append( ldda_id )
ldda_ids = unique_ldda_ids
target_history_ids = util.listify( target_history_ids )
if target_history_ids:
target_history_ids = [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ]
@@ -1831,15 +1842,15 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
status = 'error'
for ldda in map( trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get, ldda_ids ):
if ldda is None:
message += "You tried to import a library dataset that does not exist. "
message += "You tried to import a dataset that does not exist. "
status = 'error'
invalid_datasets += 1
elif ldda.dataset.state not in [ trans.model.Dataset.states.OK, trans.model.Dataset.states.ERROR ]:
message += "Cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
message += "You cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
status = 'error'
invalid_datasets += 1
elif not ldda.has_data():
message += "Cannot import empty dataset '%s'. " % ldda.name
message += "You cannot import empty dataset '%s'. " % ldda.name
status = 'error'
invalid_datasets += 1
else:
@@ -1931,6 +1942,226 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
message=util.sanitize_text( message ),
status='done' ) )
@web.expose
def move_library_item( self, trans, cntrller, item_type, item_id, source_library_id='', make_target_current=True, **kwd ):
# This method is called from one of the following places:
# - a menu option for a library dataset ( item_type is 'ldda' and item_id is a single ldda id )
# - a menu option for a library folder ( item_type is 'folder' and item_id is a single folder id )
# - a select list option for acting on multiple selected datasets within a library ( item_type is
# 'ldda' and item_id is a comma separated string of ldda ids )
# - a menu option for a library dataset search result set ( item_type is 'ldda' and item_id is a
# comma separated string of ldda ids )
params = util.Params( kwd )
message = util.restore_text( params.get( 'message', '' ) )
status = params.get( 'status', 'done' )
show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
make_target_current = util.string_as_bool( make_target_current )
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
user = trans.get_user()
current_user_roles = trans.get_current_user_roles()
move_ldda_ids = []
move_lddas = []
move_folder_id = []
move_folder = None
if source_library_id:
source_library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( source_library_id ) )
else:
# Request sent from the library_dataset_search_results page.
source_library = None
target_library_id = params.get( 'target_library_id', '' )
if target_library_id not in [ '', 'none', None ]:
target_library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( target_library_id ) )
elif make_target_current:
target_library = source_library
else:
target_library = None
target_folder_id = params.get( 'target_folder_id', '' )
if target_folder_id not in [ '', 'none', None ]:
target_folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( target_folder_id ) )
if target_library is None:
target_library = target_folder.parent_library
else:
target_folder = None
if item_type == 'ldda':
# We've been called from a menu option for a library dataset search result set
move_ldda_ids = util.listify( item_id )
if move_ldda_ids:
# Checkboxes cause 2 copies of each id to be included in the request
move_ldda_ids = map( trans.security.decode_id, move_ldda_ids )
unique_ldda_ids = []
for ldda_id in move_ldda_ids:
if ldda_id not in unique_ldda_ids:
unique_ldda_ids.append( ldda_id )
move_ldda_ids = unique_ldda_ids
elif item_type == 'folder':
move_folder_id = item_id
move_folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( move_folder_id ) )
if params.get( 'move_library_item_button', False ):
if not ( move_ldda_ids or move_folder_id ) or target_folder_id in [ '', 'none', None ]:
message = "You must select a source folder or one or more source datasets, and a target folder."
status = 'error'
else:
valid_lddas = []
invalid_lddas = []
invalid_items = 0
flush_required = False
if item_type == 'ldda':
for ldda in map( trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get, move_ldda_ids ):
if ldda is None:
message += "You tried to move a dataset that does not exist. "
status = 'error'
invalid_items += 1
elif ldda.dataset.state not in [ trans.model.Dataset.states.OK, trans.model.Dataset.states.ERROR ]:
message += "You cannot move dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
status = 'error'
invalid_items += 1
elif not ldda.has_data():
message += "You cannot move empty dataset '%s'. " % ldda.name
status = 'error'
invalid_items += 1
else:
if is_admin:
library_dataset = ldda.library_dataset
library_dataset.folder = target_folder
trans.sa_session.add( library_dataset )
flush_required = True
else:
if trans.app.security_agent.can_modify_library_item( current_user_roles, ldda ):
valid_lddas.append( ldda )
library_dataset = ldda.library_dataset
library_dataset.folder = target_folder
trans.sa_session.add( library_dataset )
flush_required = True
else:
invalid_items += 1
invalid_lddas.append( ldda )
if not valid_lddas:
message = "You are not authorized to move any of the selected datasets."
elif invalid_lddas:
message += "You are not authorized to move %s: " % inflector.cond_plural( len( invalid_lddas ), "dataset" )
for ldda in invalid_lddas:
message += '(%s)' % ldda.name
message += '. '
num_source = len( move_ldda_ids ) - invalid_items
message = "%i %s moved to folder (%s) within data library (%s)" % ( num_source,
inflector.cond_plural( num_source, "dataset" ),
target_folder.name,
target_library.name )
elif item_type == 'folder':
move_folder = trans.sa_session.query( trans.app.model.LibraryFolder ) \
.get( trans.security.decode_id( move_folder_id ) )
if move_folder is None:
message += "You tried to move a folder that does not exist. "
status = 'error'
invalid_items += 1
else:
move_folder.parent = target_folder
trans.sa_session.add( move_folder )
flush_required = True
message = "Moved folder (%s) to folder (%s) within data library (%s) " % ( move_folder.name,
target_folder.name,
target_library.name )
if flush_required:
trans.sa_session.flush()
if target_library:
if is_admin:
target_library_folders = target_library.get_active_folders( target_library.root_folder )
else:
folders_with_permission_to_add = []
for folder in target_library.get_active_folders( target_library.root_folder ):
if trans.app.security_agent.can_add_library_item( current_user_roles, folder ):
folders_with_permission_to_add.append( folder )
target_library_folders = folders_with_permission_to_add
else:
target_library_folders = []
if item_type == 'ldda':
for ldda_id in move_ldda_ids:
# TODO: It is difficult to filter out undesired folders (e.g. the ldda's current
# folder) if we have a list of lddas, but we may want to filter folders that
# are easily handled.
ldda = trans.sa_session.query( trans.model.LibraryDatasetDatasetAssociation ).get( ldda_id )
move_lddas.append( ldda )
elif item_type == 'folder':
def __is_contained_in( folder1, folder2 ):
# Return True if folder1 is contained in folder2
if folder1.parent:
if folder1.parent == folder2:
return True
return __is_contained_in( folder1.parent, folder2 )
return False
filtered_folders = []
for folder in target_library_folders:
include = True
if move_folder:
if __is_contained_in( folder, move_folder ):
# Don't allow moving a folder to one of it's sub-folders (circular issues in db)
include = False
if move_folder.id == folder.id:
# Don't allow moving a folder to itself
include = False
if move_folder.parent and move_folder.parent.id == folder.id:
# Don't allow moving a folder to it's current parent folder
include = False
if include:
filtered_folders.append( folder )
target_library_folders = filtered_folders
def __build_target_library_id_select_field( trans, selected_value='none' ):
# Get all the libraries for which the current user can add items.
target_libraries = []
if is_admin:
for library in trans.sa_session.query( trans.model.Library ) \
.filter( trans.model.Library.deleted == False ) \
.order_by( trans.model.Library.table.c.name ):
if source_library is None or library.id != source_library.id:
target_libraries.append( library )
else:
for library in trans.app.security_agent.get_accessible_libraries( trans, user ):
if source_library is None:
if trans.app.security_agent.can_add_library_item( current_user_roles, library ):
target_libraries.append( library )
elif library.id != source_library.id:
if trans.app.security_agent.can_add_library_item( current_user_roles, library ):
target_libraries.append( library )
# A refresh_on_change is required to display the selected library's folders
return build_select_field( trans,
objs=target_libraries,
label_attr='name',
select_field_name='target_library_id',
selected_value=selected_value,
refresh_on_change=True )
def __build_target_folder_id_select_field( trans, folders, selected_value='none' ):
for folder in folders:
if not folder.parent:
folder.name = 'Data library root folder'
return build_select_field( trans,
objs=folders,
label_attr='name',
select_field_name='target_folder_id',
selected_value=selected_value,
refresh_on_change=False )
if target_library:
selected_value = target_library.id
else:
selected_value = 'none'
target_library_id_select_field = __build_target_library_id_select_field( trans, selected_value=selected_value )
target_folder_id_select_field = __build_target_folder_id_select_field( trans, target_library_folders )
return trans.fill_template( "/library/common/move_library_item.mako",
cntrller=cntrller,
make_target_current=make_target_current,
source_library=source_library,
item_type=item_type,
item_id=item_id,
move_ldda_ids=move_ldda_ids,
move_lddas=move_lddas,
move_folder=move_folder,
target_library=target_library,
target_library_id_select_field=target_library_id_select_field,
target_folder_id_select_field=target_folder_id_select_field,
show_deleted=show_deleted,
use_panels=use_panels,
message=message,
status=status )
@web.expose
def delete_library_item( self, trans, cntrller, library_id, item_id, item_type, **kwd ):
# This action will handle deleting all types of library items. State is saved for libraries and
# folders ( i.e., if undeleted, the state of contents of the library or folder will remain, so previously
@@ -2257,7 +2488,7 @@ def whoosh_search( trans, cntrller, search_term, **kwd ):
# Perform search
parser = MultifieldParser( [ 'name', 'info', 'dbkey', 'message' ], schema=schema )
# Search term with wildcards may be slow...
results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=0.5 )
results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=0.01 )
ldda_ids = [ result[ 'id' ] for result in results ]
lddas = []
for ldda_id in ldda_ids:
+20 -17
View File
@@ -247,19 +247,20 @@
checked="checked"
%endif
/>
%if ldda.library_dataset.deleted:
<span class="libraryItem-error">
%endif
<div style="float: left; margin-left: 1px;" class="menubutton split popup" id="dataset-${ldda.id}-popup">
<a class="view-info" href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">${ldda.name}</a>
<a class="view-info" href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">
%if ldda.library_dataset.deleted:
<div class="libraryItem-error">${ldda.name}</div>
%else:
${ldda.name}
%endif
</a>
</div>
%if ldda.library_dataset.deleted:
</span>
%endif
%if not library.deleted:
<div popupmenu="dataset-${ldda.id}-popup">
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_edit_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
<a class="action-button" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type='ldda', item_id=trans.security.encode_id( ldda.id ), source_library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Move this dataset</a>
%else:
<a class="action-button" href="${h.url_for( controller='library_common', action='ldda_info', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), id=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">View information</a>
%endif
@@ -348,7 +349,7 @@
info_association, inherited = folder.get_info_association( restrict=True )
%>
%if not root_folder and ( not folder.deleted or show_deleted ):
<% encoded_id = trans.security.encode_id(folder.id) %>
<% encoded_id = trans.security.encode_id( folder.id ) %>
<tr id="folder-${encoded_id}" class="folderRow libraryOrFolderRow"
%if parent is not None:
parent="${parent}"
@@ -358,15 +359,16 @@
<td style="padding-left: ${folder_pad}px;">
<input type="checkbox" class="folderCheckbox"/>
<span class="expandLink folder-${encoded_id}-click">
<div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id}-popup">
<a class="folder-${encoded_id}-click" href="javascript:void(0);">
%if folder.deleted:
<span class="libraryItem-error">${folder.name}</span>
%else:
${folder.name}
%endif
</a>
</div>
<div style="float: left; margin-left: 2px;" class="menubutton split popup" id="folder_img-${folder.id}-popup">
<a class="folder-${encoded_id}-click" href="javascript:void(0);">
%if folder.deleted:
<div class="libraryItem-error">${folder.name}</div>
%else:
${folder.name}
%endif
</a>
</div>
</span>
%if not library.deleted:
<div popupmenu="folder_img-${folder.id}-popup">
%if not branch_deleted( folder ) and can_add:
@@ -379,6 +381,7 @@
%endif
%if can_modify:
<a class="action-button" href="${h.url_for( controller='library_common', action='folder_info', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
<a class="action-button" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type='folder', item_id=trans.security.encode_id( folder.id ), source_library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Move this folder</a>
%else:
<a class="action-button" class="view-info" href="${h.url_for( controller='library_common', action='folder_info', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">View information</a>
%endif
+11 -7
View File
@@ -399,17 +399,18 @@
can_download = 'download' not in actions_to_exclude
can_import_to_histories = 'import_to_histories' not in actions_to_exclude
can_manage_permissions = 'manage_permissions' not in actions_to_exclude
can_move = 'move' not in actions_to_exclude
%>
<tfoot>
<tr>
<td colspan="5" style="padding-left: 42px;">
For selected items:
For selected datasets:
<select name="do_action" id="action_on_selected_items">
%if can_import_to_histories:
%if not is_admin and default_action == 'import_to_histories':
<option value="import_to_histories" selected>Import selected datasets to histories</option>
<option value="import_to_histories" selected>Import to histories</option>
%else:
<option value="import_to_histories">Import selected datasets to histories</option>
<option value="import_to_histories">Import to histories</option>
%endif
%endif
%if can_manage_permissions:
@@ -419,13 +420,19 @@
<option value="manage_permissions">Edit permissions</option>
%endif
%endif
%if can_move:
<option value="move">Move</option>
%endif
%if can_delete:
<option value="delete">Delete</option>
%endif
%if can_download:
%if 'gz' in comptypes:
<option value="tgz"
%if default_action == 'download':
selected
%endif>
>Download as a .tar.gz file</option>
>Download as a .tar.gz file</option>
%endif
%if 'bz2' in comptypes:
<option value="tbz">Download as a .tar.bz2 file</option>
@@ -442,9 +449,6 @@
>Download as a .zip file</option>
%endif
%endif
%if can_delete:
<option value="delete">Delete</option>
%endif
</select>
<input type="submit" class="primary-button" name="action_on_datasets_button" id="action_on_datasets_button" value="Go"/>
</td>
@@ -4,74 +4,53 @@
<%def name="title()">Import library datasets to histories</%def>
<%def name="javascripts()">
${parent.javascripts()}
${h.js( "jquery", "galaxy.base" )}
<script type="text/javascript">
$(function() {
$("#select-multiple").click(function() {
$("#single-dest-select").val("");
$("#single-destination").hide();
$("#multiple-destination").show();
${parent.javascripts()}
${h.js( "jquery", "galaxy.base" )}
<script type="text/javascript">
$(function() {
$("#select-multiple").click(function() {
$("#single-dest-select").val("");
$("#single-destination").hide();
$("#multiple-destination").show();
});
});
});
</script>
</script>
</%def>
%if message:
${render_msg( message, status )}
%endif
<p>
<div class="infomessage">Import library datasets into histories.</div>
<div style="clear: both"></div>
</p>
<p>
<form method="post">
<div class="toolForm" style="float: left; width: 45%; padding: 0px;">
<div class="toolFormBody">
<input type="hidden" name="cntrller" value="${cntrller}"/>
%if source_lddas:
%for source_ldda in source_lddas:
<%
checked = ""
encoded_id = trans.security.encode_id( source_ldda.id )
if source_ldda.id in ldda_ids:
checked = " checked='checked'"
%>
<div class="form-row">
<input type="checkbox" name="ldda_ids" id="dataset_${encoded_id}" value="${encoded_id}" ${checked}/>
<label for="dataset_${encoded_id}" style="display: inline;font-weight:normal;">${source_ldda.name}</label>
</div>
%endfor
%else:
<div class="form-row">This folder has no accessible library datasets.</div>
%endif
</div>
<b>Import library datasets into histories</b>
<br/><br/>
<form action="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, use_panels=use_panels, show_deleted=show_deleted )}" method="post">
<div class="toolForm" style="float: left; width: 45%; padding: 0px;">
<div class="toolFormBody">
%if source_lddas:
%for source_ldda in source_lddas:
<%
checked = ""
encoded_id = trans.security.encode_id( source_ldda.id )
if source_ldda.id in ldda_ids:
checked = " checked='checked'"
%>
<div class="form-row">
<input type="checkbox" name="ldda_ids" id="dataset_${encoded_id}" value="${encoded_id}" ${checked}/>
<label for="dataset_${encoded_id}" style="display: inline;font-weight:normal;">${source_ldda.name}</label>
</div>
%endfor
%else:
<div class="form-row">This folder has no accessible library datasets.</div>
%endif
</div>
<div style="float: left; padding-left: 10px; font-size: 36px;">&rarr;</div>
<div class="toolForm" style="float: right; width: 45%; padding: 0px;">
<div class="toolFormTitle">Destination Histories:</div>
<div class="toolFormBody">
<div class="form-row" id="single-destination">
<select id="single-dest-select" name="target_history_ids">
<option value=""></option>
%for i, target_history in enumerate( target_histories ):
<%
encoded_id = trans.security.encode_id( target_history.id )
if target_history == current_history:
current_history_text = " (current history)"
else:
current_history_text = ""
%>
<option value="${encoded_id}">${i + 1}: ${h.truncate( target_history.name, 30 )}${current_history_text}</option>
%endfor
</select>
<br/><br/>
<a style="margin-left: 10px;" href="javascript:void(0);" id="select-multiple">Choose multiple histories</a>
</div>
<div id="multiple-destination" style="display: none;">
</div>
<div style="float: left; padding-left: 10px; font-size: 36px;">&rarr;</div>
<div class="toolForm" style="float: right; width: 45%; padding: 0px;">
<div class="toolFormTitle">Destination Histories:</div>
<div class="toolFormBody">
<div class="form-row" id="single-destination">
<select id="single-dest-select" name="target_history_ids">
<option value=""></option>
%for i, target_history in enumerate( target_histories ):
<%
encoded_id = trans.security.encode_id( target_history.id )
@@ -80,31 +59,45 @@ ${h.js( "jquery", "galaxy.base" )}
else:
current_history_text = ""
%>
<div class="form-row">
<input type="checkbox" name="target_history_ids" id="target_history_${encoded_id}" value="${encoded_id}"/>
<label for="target_history_${encoded_id}" style="display: inline; font-weight:normal;">${i + 1}: ${target_history.name}${current_history_text}</label>
</div>
<option value="${encoded_id}">${i + 1}: ${h.truncate( target_history.name, 30 )}${current_history_text}</option>
%endfor
</div>
%if trans.get_user():
</select>
<br/><br/>
<a style="margin-left: 10px;" href="javascript:void(0);" id="select-multiple">Choose multiple histories</a>
</div>
<div id="multiple-destination" style="display: none;">
%for i, target_history in enumerate( target_histories ):
<%
checked = ""
if "create_new_history" in target_history_ids:
checked = " checked='checked'"
encoded_id = trans.security.encode_id( target_history.id )
if target_history == current_history:
current_history_text = " (current history)"
else:
current_history_text = ""
%>
<hr />
<div style="text-align: center; color: #888;">&mdash; OR &mdash;</div>
<div class="form-row">
<label for="new_history_name" style="display: inline; font-weight:normal;">New history named:</label>
<input type="textbox" name="new_history_name" />
<input type="checkbox" name="target_history_ids" id="target_history_${encoded_id}" value="${encoded_id}"/>
<label for="target_history_${encoded_id}" style="display: inline; font-weight:normal;">${i + 1}: ${target_history.name}${current_history_text}</label>
</div>
%endif
%endfor
</div>
%if trans.get_user():
<%
checked = ""
if "create_new_history" in target_history_ids:
checked = " checked='checked'"
%>
<hr />
<div style="text-align: center; color: #888;">&mdash; OR &mdash;</div>
<div class="form-row">
<label for="new_history_name" style="display: inline; font-weight:normal;">New history named:</label>
<input type="textbox" name="new_history_name" />
</div>
%endif
</div>
<div style="clear: both"></div>
<div class="form-row" align="center">
<input type="submit" class="primary-button" name="import_datasets_to_histories_button" value="Import library datasets"/>
</div>
</form>
</div>
</p>
<div style="clear: both"></div>
<div class="form-row" align="center">
<input type="submit" class="primary-button" name="import_datasets_to_histories_button" value="Import library datasets"/>
</div>
</form>
</div>
@@ -95,7 +95,7 @@
<p>The string "${search_term}" was found in at least one of the following information components of the displayed library datasets.</p>
${render_searched_components()}
<form name="act_on_multiple_datasets" action="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, use_panels=use_panels, show_deleted=show_deleted )}" onSubmit="javascript:return checkForm();" method="post">
<input type="hidden" name=search_term value="${search_term}"/>
<input type="hidden" name="search_term" value="${search_term}"/>
<table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
<thead>
<tr class="libraryTitle">
@@ -0,0 +1,96 @@
<%namespace file="/message.mako" import="render_msg" />
<%inherit file="/base.mako"/>
<%
if source_library:
source_library_id = trans.security.encode_id( source_library.id )
else:
source_library_id = ''
if target_library:
target_library_id = trans.security.encode_id( target_library.id )
else:
target_library_id = ''
%>
%if message:
${render_msg( message, status )}
%endif
<b>Move data library items</b>
<br/><br/>
<form name="move_library_item" action="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type=item_type, make_target_current=make_target_current, use_panels=use_panels, show_deleted=show_deleted )}" method="post">
<div class="toolForm" style="float: left; width: 45%; padding: 0px;">
<div class="toolFormBody">
<input type="hidden" name="source_library_id" value="${source_library_id}"/>
%if target_library:
<input type="hidden" name="target_library_id" value="${target_library_id}"/>
%endif
%if item_type == 'ldda':
%for move_ldda in move_lddas:
<%
checked = ""
encoded_id = trans.security.encode_id( move_ldda.id )
if move_ldda.id in move_ldda_ids:
checked = " checked='checked'"
%>
<div class="form-row">
<input type="checkbox" name="item_id" id="dataset_${encoded_id}" value="${encoded_id}" ${checked}/>
<label for="dataset_${encoded_id}" style="display: inline;font-weight:normal;">${move_ldda.name}</label>
</div>
%endfor
%elif item_type == 'folder':
<div class="form-row">
<% encoded_id = trans.security.encode_id( move_folder.id ) %>
<input type="checkbox" name="item_id" id="folder_${encoded_id}" value="${encoded_id}" checked='checked'/>
<label for="folder_${encoded_id}" style="display: inline;font-weight:normal;">${move_folder.name}</label>
</div>
%endif
</div>
</div>
<div style="float: left; padding-left: 10px; font-size: 36px;">&rarr;</div>
<div class="toolForm" style="float: right; width: 45%; padding: 0px;">
%if target_library:
<div class="toolFormTitle">Select folder within data library: ${h.truncate( target_library.name, 30 )}</div>
%else:
<div class="toolFormTitle">Select a data library</div>
%endif
<div class="toolFormBody">
%if target_library:
<div class="form-row">
%if len( target_folder_id_select_field.options ) > 1:
${target_folder_id_select_field.get_html()}
%else:
%if source_library and source_library.id == target_library.id:
You are not authorized to move items within the source data library
%else:
You are not authorized to move items into the selected data library
%endif
%endif
%if source_library:
<br/><br/>
%if target_library.id == source_library.id:
<a style="margin-left: 10px;" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type=item_type, item_id=item_id, source_library_id=source_library_id, make_target_current=False, use_panels=use_panels, show_deleted=show_deleted )}">Choose another data library</a>
%else:
<a style="margin-left: 10px;" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type=item_type, item_id=item_id, source_library_id=source_library_id, make_target_current=True, use_panels=use_panels, show_deleted=show_deleted )}">Choose source data library</a>
%endif
%elif not target_library_folders:
<br/><br/>
<a style="margin-left: 10px;" href="${h.url_for( controller='library_common', action='move_library_item', cntrller=cntrller, item_type=item_type, item_id=item_id, source_library_id=source_library_id, make_target_current=False, use_panels=use_panels, show_deleted=show_deleted )}">Choose another data library</a>
%endif
</div>
%else:
<div class="form-row">
%if len( target_library_id_select_field.options ) > 1:
${target_library_id_select_field.get_html()}
%else:
You are not authorized to move items to any data libraries
%endif
</div>
%endif
</div>
</div>
<div style="clear: both"></div>
<div class="form-row" align="center">
<input type="submit" class="primary-button" name="move_library_item_button" value="Move"/>
</div>
</form>