[hg] galaxy 2852: Enables viewing of an importable/sharable hist...
details: http://www.bx.psu.edu/hg/galaxy/rev/8f630db17cf1 changeset: 2852:8f630db17cf1 user: jeremy goecks <jeremy.goecks@emory.edu> date: Thu Oct 08 13:38:32 2009 -0400 description: Enables viewing of an importable/sharable history. Using the syntax /history/view?id=<encoded_history_id> produces a page that renders a history for viewing. A user need not be logged in to view the history. 11 file(s) affected in this change: lib/galaxy/web/controllers/history.py static/june_2007_style/blue/history.css static/june_2007_style/history.css.tmpl static/scripts/autocomplete_tagging.js templates/base_panels.mako templates/history/sharing.mako templates/history/view.mako templates/root/history.mako templates/root/history_common.mako templates/tagging_common.mako test/functional/test_history_functions.py diffs (819 lines): diff -r d146ca99434f -r 8f630db17cf1 lib/galaxy/web/controllers/history.py --- a/lib/galaxy/web/controllers/history.py Thu Oct 08 11:33:43 2009 -0400 +++ b/lib/galaxy/web/controllers/history.py Thu Oct 08 13:38:32 2009 -0400 @@ -371,6 +371,7 @@ # Rename history.name = new_name trans.sa_session.flush() + @web.expose def imp( self, trans, id=None, confirm=False, **kwd ): """Import another user's history via a shared URL""" @@ -423,6 +424,38 @@ Warning! If you import this history, you will lose your current history. Click <a href="%s">here</a> to confirm. """ % web.url_for( id=id, confirm=True ) ) + + @web.expose + def view( self, trans, id=None ): + """View a history. If a history is importable, then it is viewable by any user.""" + + # Get history to view. + if not id: + return trans.show_error_message( "You must specify a history you want to view." ) + history_to_view = get_history( trans, id, False) + + # Integrity checks. + if not history_to_view: + return trans.show_error_message( "The specified history does not exist.") + # TODO: Use a new flag to determine if history is viewable? + if not history_to_view.importable: + error( "The owner of this history has not published this history." ) + + # View history. + query = trans.sa_session.query( model.HistoryDatasetAssociation ) \ + .filter( model.HistoryDatasetAssociation.history == history_to_view ) \ + .options( eagerload( "children" ) ) \ + .join( "dataset" ).filter( model.Dataset.purged == False ) \ + .options( eagerload_all( "dataset.actions" ) ) + # Do not show deleted datasets. + query = query.filter( model.HistoryDatasetAssociation.deleted == False ) + user_owns_history = ( trans.get_user() == history_to_view.user ) + return trans.stream_template_mako( "history/view.mako", + history = history_to_view, + datasets = query.all(), + user_owns_history = user_owns_history, + show_deleted = False ) + @web.expose @web.require_login( "share histories with other users" ) def share( self, trans, id=None, email="", **kwd ): @@ -699,6 +732,7 @@ @web.expose @web.require_login( "share histories with other users" ) def sharing( self, trans, histories=[], id=None, **kwd ): + """Performs sharing of histories among users.""" # histories looks like: [ historyX, historyY ] params = util.Params( kwd ) msg = util.restore_text ( params.get( 'msg', '' ) ) diff -r d146ca99434f -r 8f630db17cf1 static/june_2007_style/blue/history.css --- a/static/june_2007_style/blue/history.css Thu Oct 08 11:33:43 2009 -0400 +++ b/static/june_2007_style/blue/history.css Thu Oct 08 13:38:32 2009 -0400 @@ -1,7 +1,7 @@ body{background:#C1C9E5;color:#303030;background-image:url(menu_bg.png);background-repeat:repeat-x;background-position:top;margin:5px;border:0;padding:0;} a{color:#303030;} div.historyLinks{padding:5px;margin:5px 0 5px 0;} -div.historyItem{margin:5px -5px 5px 0px;padding:5px 11px 5px 5px;border:solid #888888 1px;border-left:solid #888888 5px;border-right:none;background:#EEEEEE;} +div.historyItem{margin:5px -5px 5px 0px;padding:5px 11px 5px 5px;border:solid #888888 1px;border-left:solid #888888 5px;border-right:solid #888888 1px;background:#EEEEEE;} div.historyItem .state-icon{display:inline-block;vertical-align:middle;width:16px;height:16px;background-position:0 1px;background-repeat:no-repeat;} div.historyItem .historyItemTitle{line-height:16px;} div.historyItem div.historyItem{margin-right:-11px;} diff -r d146ca99434f -r 8f630db17cf1 static/june_2007_style/history.css.tmpl --- a/static/june_2007_style/history.css.tmpl Thu Oct 08 11:33:43 2009 -0400 +++ b/static/june_2007_style/history.css.tmpl Thu Oct 08 13:38:32 2009 -0400 @@ -25,7 +25,7 @@ padding: 5px 11px 5px 5px; border: solid $history_queued_border 1px; border-left: solid $history_queued_border 5px; - border-right: none; + border-right: solid $history_queued_border 1px; background: $history_queued_bg; .state-icon { display: inline-block; diff -r d146ca99434f -r 8f630db17cf1 static/scripts/autocomplete_tagging.js --- a/static/scripts/autocomplete_tagging.js Thu Oct 08 11:33:43 2009 -0400 +++ b/static/scripts/autocomplete_tagging.js Thu Oct 08 13:38:32 2009 -0400 @@ -12,30 +12,31 @@ // var defaults = { - get_toggle_link_text_fn: function(tags) - { - var text = ""; - var num_tags = array_length(tags); - if (num_tags != 0) - text = num_tags + (num_tags != 0 ? " Tags" : " Tag"); - else - // No tags. - text = "Add tags"; - return text; - }, - tag_click_fn : function (name, value) { }, - input_size: 20, - in_form: false, - tags : {}, - use_toggle_link: true, - item_id: "", - add_tag_img: "", - add_tag_img_rollover: "", - delete_tag_img: "", - ajax_autocomplete_tag_url: "", - ajax_retag_url: "", - ajax_delete_tag_url: "", - ajax_add_tag_url: "" + get_toggle_link_text_fn: function(tags) + { + var text = ""; + var num_tags = array_length(tags); + if (num_tags != 0) + text = num_tags + (num_tags != 0 ? " Tags" : " Tag"); + else + // No tags. + text = "Add tags"; + return text; + }, + tag_click_fn : function (name, value) { }, + editable: true, + input_size: 20, + in_form: false, + tags : {}, + use_toggle_link: true, + item_id: "", + add_tag_img: "", + add_tag_img_rollover: "", + delete_tag_img: "", + ajax_autocomplete_tag_url: "", + ajax_retag_url: "", + ajax_delete_tag_url: "", + ajax_add_tag_url: "" }; // @@ -206,32 +207,32 @@ // Delete tag. $.ajax({ - url: settings.ajax_delete_tag_url, - data: { tag_name: tag_name }, - error: function() - { - // Failed. Roll back changes and show alert. - settings.tags[tag_name] = tag_value; - if (prev_button.hasClass("tag-button")) - prev_button.after(tag_button); - else - tag_area.prepend(tag_button); - var new_text = settings.get_toggle_link_text_fn(settings.tags); - alert( "Remove tag failed" ); + url: settings.ajax_delete_tag_url, + data: { tag_name: tag_name }, + error: function() + { + // Failed. Roll back changes and show alert. + settings.tags[tag_name] = tag_value; + if (prev_button.hasClass("tag-button")) + prev_button.after(tag_button); + else + tag_area.prepend(tag_button); + var new_text = settings.get_toggle_link_text_fn(settings.tags); + alert( "Remove tag failed" ); - toggle_link.text(new_text); + toggle_link.text(new_text); - // TODO: no idea why it's necessary to set this up again. - delete_img.mouseenter( function () - { - $(this).attr("src", settings.delete_tag_img_rollover); - }); - delete_img.mouseleave( function () - { - $(this).attr("src", settings.delete_tag_img); - }); - }, - success: function() {} + // TODO: no idea why it's necessary to set this up again. + delete_img.mouseenter( function () + { + $(this).attr("src", settings.delete_tag_img_rollover); + }); + delete_img.mouseleave( function () + { + $(this).attr("src", settings.delete_tag_img); + }); + }, + success: function() {} }); return true; @@ -248,7 +249,9 @@ var tag_button = $("<span></span>").addClass("tag-button"); tag_button.append(tag_name_elt); - tag_button.append(delete_img); + // Allow delete only if element is editable. + if (settings.editable) + tag_button.append(delete_img); return tag_button; }; @@ -411,55 +414,58 @@ } }); - tag_area.append(add_tag_button); - tag_area.append(tag_input_field); - tag_input_field.hide(); + if (settings.editable) + { + tag_area.append(add_tag_button); + tag_area.append(tag_input_field); + tag_input_field.hide(); - // On click, enable user to add tags. - tag_area.click( function(e) - { - var is_active = $(this).hasClass("active-tag-area"); + // On click, enable user to add tags. + tag_area.click( function(e) + { + var is_active = $(this).hasClass("active-tag-area"); - // If a "delete image" object was pressed and area is inactive, do nothing. - if ($(e.target).hasClass("delete-tag-img") && !is_active) - return false; + // If a "delete image" object was pressed and area is inactive, do nothing. + if ($(e.target).hasClass("delete-tag-img") && !is_active) + return false; - // If a "tag name" object was pressed and area is inactive, do nothing. - if ($(e.target).hasClass("tag-name") && !is_active) - return false; + // If a "tag name" object was pressed and area is inactive, do nothing. + if ($(e.target).hasClass("tag-name") && !is_active) + return false; - // Hide add tag button, show tag_input field. Change background to show - // area is active. - $(this).addClass("active-tag-area"); - add_tag_button.hide(); - tag_input_field.show(); - tag_input_field.focus(); + // Hide add tag button, show tag_input field. Change background to show + // area is active. + $(this).addClass("active-tag-area"); + add_tag_button.hide(); + tag_input_field.show(); + tag_input_field.focus(); - // Add handler to document that will call blur when the tag area is blurred; - // a tag area is blurred when a user clicks on an element outside the area. - var handle_document_click = function(e) - { - var tag_area_id = tag_area.attr("id"); - // Blur the tag area if the element clicked on is not in the tag area. - if ( - ($(e.target).attr("id") != tag_area_id) && - ($(e.target).parents().filter(tag_area_id).length == 0) - ) - { - tag_area.blur(); - $(document).unbind("click", handle_document_click); - } - }; - // TODO: we should attach the click handler to all frames in order to capture - // clicks outside the frame that this element is in. - //window.parent.document.onclick = handle_document_click; - //var temp = $(window.parent.document.body).contents().find("iframe").html(); - //alert(temp); - //$(document).parent().click(handle_document_click); - $(window).click(handle_document_click); + // Add handler to document that will call blur when the tag area is blurred; + // a tag area is blurred when a user clicks on an element outside the area. + var handle_document_click = function(e) + { + var tag_area_id = tag_area.attr("id"); + // Blur the tag area if the element clicked on is not in the tag area. + if ( + ($(e.target).attr("id") != tag_area_id) && + ($(e.target).parents().filter(tag_area_id).length == 0) + ) + { + tag_area.blur(); + $(document).unbind("click", handle_document_click); + } + }; + // TODO: we should attach the click handler to all frames in order to capture + // clicks outside the frame that this element is in. + //window.parent.document.onclick = handle_document_click; + //var temp = $(window.parent.document.body).contents().find("iframe").html(); + //alert(temp); + //$(document).parent().click(handle_document_click); + $(window).click(handle_document_click); - return false; - }); + return false; + }); + } // If using toggle link, hide the tag area. Otherwise, if there are no tags, // hide the "add tags" button and show the input field. diff -r d146ca99434f -r 8f630db17cf1 templates/base_panels.mako --- a/templates/base_panels.mako Thu Oct 08 11:33:43 2009 -0400 +++ b/templates/base_panels.mako Thu Oct 08 13:38:32 2009 -0400 @@ -44,13 +44,14 @@ <!--[if lt IE 7]> ${h.js( 'IE7', 'ie7-recalc' )} <![endif]--> + ${h.js( 'jquery' )} </%def> ## Default late-load javascripts <%def name="late_javascripts()"> ## Scripts can be loaded later since they progressively add features to ## the panels, but do not change layout - ${h.js( 'jquery', 'jquery.event.drag', 'jquery.event.hover', 'jquery.form', 'galaxy.base', 'galaxy.panels' )} + ${h.js( 'jquery.event.drag', 'jquery.event.hover', 'jquery.form', 'galaxy.base', 'galaxy.panels' )} <script type="text/javascript"> ensure_dd_helper(); diff -r d146ca99434f -r 8f630db17cf1 templates/history/sharing.mako --- a/templates/history/sharing.mako Thu Oct 08 11:33:43 2009 -0400 +++ b/templates/history/sharing.mako Thu Oct 08 13:38:32 2009 -0400 @@ -34,10 +34,17 @@ %endif %if history.importable: <div class="form-row"> + <% url = h.url_for( controller='history', action='view', id=trans.security.encode_id(history.id), qualified=True ) %> + <a href="${url}" target="_blank">${url}</a> + <div class="toolParamHelp" style="clear: both;"> + Send the above link to users as an easy way for them to view the history. + </div> + </div> + <div class="form-row"> <% url = h.url_for( controller='history', action='imp', id=trans.security.encode_id(history.id), qualified=True ) %> <a href="${url}">${url}</a> <div class="toolParamHelp" style="clear: both;"> - Send the above URL to users as an easy way for them to import the history, making a copy of their own + Send the above link to users as an easy way for them to import the history, making a copy of their own. </div> </div> <div class="form-row"> diff -r d146ca99434f -r 8f630db17cf1 templates/history/view.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/history/view.mako Thu Oct 08 13:38:32 2009 -0400 @@ -0,0 +1,349 @@ +<%inherit file="/base_panels.mako"/> + +<%def name="javascripts()"> + ${parent.javascripts()} + ${h.js( "jquery", "json2", "jquery.jstore-all", "jquery.autocomplete", "autocomplete_tagging" )} +</%def> + +<%def name="stylesheets()"> + ${parent.stylesheets()} + ${h.css( "history", "autocomplete_tagging" )} +</%def> + +<%namespace file="/root/history_common.mako" import="render_dataset" /> + +<%def name="init()"> +<% + self.has_left_panel=False + self.has_right_panel=False + self.message_box_visible=False +%> +</%def> + +<%def name="center_panel()"> + ## For now, turn off inline editing so that view is external only. + <% + user_owns_history = False + %> + + <div style="overflow: auto; height: 100%;"> + <div style="padding: 10px;"> + ## Render view of history. + <script type="text/javascript"> + $(function() { + // Load jStore for local storage + $.extend(jQuery.jStore.defaults, { project: 'galaxy', flash: '/static/jStore.Flash.html' }) + $.jStore.load(); // Auto-select best storage + + $.jStore.ready(function(engine) { + engine.ready(function() { + // Init stuff that requires the local storage to be running + initShowHide(); + setupHistoryItem( $("div.historyItemWrapper") ); + }); + }); + + // Generate 'collapse all' link + $("#top-links").append( "| " ).append( $("<a href='#'>${_('collapse all')}</a>").click( function() { + $( "div.historyItemBody:visible" ).each( function() { + if ( $.browser.mozilla ) { + $(this).find( "pre.peek" ).css( "overflow", "hidden" ); + } + $(this).slideUp( "fast" ); + }); + $.jStore.remove("history_expand_state"); + })); + + $("#history-rename").click( function() { + var old_name = $("#history-name").text() + var t = $("<input type='text' value='" + old_name + "'></input>" ); + t.blur( function() { + $(this).remove(); + $("#history-name").show(); + }); + t.keyup( function( e ) { + if ( e.keyCode == 27 ) { + // Escape key + $(this).trigger( "blur" ); + } else if ( e.keyCode == 13 ) { + // Enter key + new_value = this.value; + $(this).trigger( "blur" ); + $.ajax({ + url: "${h.url_for( controller='history', action='rename_async', id=history.id )}", + data: { "_": true, new_name: new_value }, + error: function() { alert( "Rename failed" ) }, + success: function() { + $("#history-name").text( new_value ); + } + }); + } + }); + $("#history-name").hide(); + $("#history-name-area").append( t ); + t.focus(); + return false; + }); + // Updater + updater({ + <% updateable = [data for data in reversed( datasets ) if data.visible and data.state not in [ "deleted", "empty", "error", "ok" ]] %> + ${ ",".join( map(lambda data: "\"%s\" : \"%s\"" % (data.id, data.state), updateable) ) } + }); + }); + // Functionized so AJAX'd datasets can call them + function initShowHide() { + + // Load saved state and show as necessary + try { + var stored = $.jStore.store("history_expand_state"); + if (stored) { + var st = JSON.parse(stored); + for (var id in st) { + $("#" + id + " div.historyItemBody" ).show(); + } + } + } catch(err) { + // Something was wrong with values in storage, so clear storage + $.jStore.remove("history_expand_state"); + } + + // If Mozilla, hide scrollbars in hidden items since they cause animation bugs + if ( $.browser.mozilla ) { + $( "div.historyItemBody" ).each( function() { + if ( ! $(this).is( ":visible" ) ) $(this).find( "pre.peek" ).css( "overflow", "hidden" ); + }) + } + } + // Add show/hide link and delete link to a history item + function setupHistoryItem( query ) { + query.each( function() { + var id = this.id; + var body = $(this).children( "div.historyItemBody" ); + var peek = body.find( "pre.peek" ) + $(this).children( ".historyItemTitleBar" ).find( ".historyItemTitle" ).wrap( "<a href='#'></a>" ).click( function() { + if ( body.is(":visible") ) { + // Hiding stuff here + if ( $.browser.mozilla ) { peek.css( "overflow", "hidden" ) } + body.slideUp( "fast" ); + + // Save setting + var stored = $.jStore.store("history_expand_state") + var prefs = stored ? JSON.parse(stored) : null + if (prefs) { + delete prefs[id]; + $.jStore.store("history_expand_state", JSON.stringify(prefs)); + } + } else { + // Showing stuff here + body.slideDown( "fast", function() { + if ( $.browser.mozilla ) { peek.css( "overflow", "auto" ); } + }); + + // Save setting + var stored = $.jStore.store("history_expand_state") + var prefs = stored ? JSON.parse(stored) : new Object; + prefs[id] = true; + $.jStore.store("history_expand_state", JSON.stringify(prefs)); + } + return false; + }); + // Delete link + $(this).find( "div.historyItemButtons > .delete" ).each( function() { + var data_id = this.id.split( "-" )[1]; + $(this).click( function() { + $( '#historyItem-' + data_id + "> div.historyItemTitleBar" ).addClass( "spinner" ); + $.ajax({ + url: "${h.url_for( action='delete_async', id='XXX' )}".replace( 'XXX', data_id ), + error: function() { alert( "Delete failed" ) }, + success: function() { + %if show_deleted: + var to_update = {}; + to_update[data_id] = "none"; + updater( to_update ); + %else: + $( "#historyItem-" + data_id ).fadeOut( "fast", function() { + $( "#historyItemContainer-" + data_id ).remove(); + if ( $( "div.historyItemContainer" ).length < 1 ) { + $( "#emptyHistoryMessage" ).show(); + } + }); + %endif + } + }); + return false; + }); + }); + // Undelete link + $(this).find( "a.historyItemUndelete" ).each( function() { + var data_id = this.id.split( "-" )[1]; + $(this).click( function() { + $( '#historyItem-' + data_id + " > div.historyItemTitleBar" ).addClass( "spinner" ); + $.ajax({ + url: "${h.url_for( controller='dataset', action='undelete_async', id='XXX' )}".replace( 'XXX', data_id ), + error: function() { alert( "Undelete failed" ) }, + success: function() { + var to_update = {}; + to_update[data_id] = "none"; + updater( to_update ); + } + }); + return false; + }); + }); + }); + }; + // Looks for changes in dataset state using an async request. Keeps + // calling itself (via setTimeout) until all datasets are in a terminal + // state. + var updater = function ( tracked_datasets ) { + // Check if there are any items left to track + var empty = true; + for ( i in tracked_datasets ) { + empty = false; + break; + } + if ( ! empty ) { + // console.log( "Updater running in 3 seconds" ); + setTimeout( function() { updater_callback( tracked_datasets ) }, 3000 ); + } else { + // console.log( "Updater finished" ); + } + }; + var updater_callback = function ( tracked_datasets ) { + // Build request data + var ids = [] + var states = [] + var force_history_refresh = false + $.each( tracked_datasets, function ( id, state ) { + ids.push( id ); + states.push( state ); + }); + // Make ajax call + $.ajax( { + type: "POST", + url: "${h.url_for( controller='root', action='history_item_updates' )}", + dataType: "json", + data: { ids: ids.join( "," ), states: states.join( "," ) }, + success : function ( data ) { + $.each( data, function( id, val ) { + // Replace HTML + var container = $("#historyItemContainer-" + id); + container.html( val.html ); + setupHistoryItem( container.children( ".historyItemWrapper" ) ); + initShowHide(); + // If new state was terminal, stop tracking + if (( val.state == "ok") || ( val.state == "error") || ( val.state == "empty") || ( val.state == "deleted" ) || ( val.state == "discarded" )) { + if ( val.force_history_refresh ){ + force_history_refresh = true; + } + delete tracked_datasets[ parseInt(id) ]; + } else { + tracked_datasets[ parseInt(id) ] = val.state; + } + }); + if ( force_history_refresh ) { + parent.frames.galaxy_history.location.reload(); + } else { + // Keep going (if there are still any items to track) + updater( tracked_datasets ); + } + }, + error: function() { + // Just retry, like the old method, should try to be smarter + updater( tracked_datasets ); + } + }); + }; + + // + // Function provides text for tagging toggle link. + // + var get_toggle_link_text = function(tags) + { + var text = ""; + var num_tags = array_length(tags); + if (num_tags != 0) + { + text = num_tags + (num_tags != 1 ? " Tags" : " Tag"); + } + else + { + // No tags. + text = "Add tags to history"; + } + return text; + }; + </script> + + <style> + .historyItemBody { + display: none; + } + </style> + + <noscript> + <style> + .historyItemBody { + display: block; + } + </style> + </noscript> + + <div id="top-links" class="historyLinks" style="padding: 0px 0px 5px 0px"> + %if not user_owns_history: + <a href="${h.url_for( controller='history', action='imp', id=trans.security.encode_id(history.id) )}">${_('import')}</a> | + %endif + <a href="${h.url_for( controller='history', action='view', id=trans.security.encode_id(history.id) )}">${_('refresh')}</a> + %if show_deleted: + | <a href="${h.url_for('history', show_deleted=False)}">${_('hide deleted')}</a> + %endif + </div> + + <div id="history-name-area" class="historyLinks" style="color: gray; font-weight: bold; padding: 0px 0px 5px 0px"> + %if user_owns_history: + <div style="float: right"><a id="history-rename" title="Rename" class="icon-button edit" target="galaxy_main" href="${h.url_for( controller='history', action='rename' )}"></a></div> + %endif + <div id="history-name">${history.get_display_name()}</div> + </div> + + %if history.deleted: + <div class="warningmessagesmall"> + ${_('You are currently viewing a deleted history!')} + </div> + <p></p> + %endif + + <div id="history-tag-area" style="margin-bottom: 1em"> + </div> + + <%namespace file="../tagging_common.mako" import="render_tagging_element" /> + + %if trans.get_user() is not None: + <div id='history-tag-area' class="tag-element"></div> + ${render_tagging_element(history, "history-tag-area", get_toggle_link_text_fn='get_toggle_link_text', editable=user_owns_history)} + %endif + + %if not datasets: + + <div class="infomessagesmall" id="emptyHistoryMessage"> + + %else: + + ## Render requested datasets, ordered from newest to oldest + %for data in reversed( datasets ): + %if data.visible: + <div class="historyItemContainer" id="historyItemContainer-${data.id}"> + ${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted, user_owns_dataset=user_owns_history )} + </div> + %endif + %endfor + + <div class="infomessagesmall" id="emptyHistoryMessage" style="display:none;"> + %endif + ${_("Your history is empty. Click 'Get Data' on the left pane to start")} + </div> + </div> + </div> + + +</%def> diff -r d146ca99434f -r 8f630db17cf1 templates/root/history.mako --- a/templates/root/history.mako Thu Oct 08 11:33:43 2009 -0400 +++ b/templates/root/history.mako Thu Oct 08 13:38:32 2009 -0400 @@ -321,7 +321,7 @@ %for data in reversed( datasets ): %if data.visible: <div class="historyItemContainer" id="historyItemContainer-${data.id}"> - ${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted )} + ${render_dataset( data, data.hid, show_deleted_on_refresh = show_deleted, user_owns_dataset = True )} </div> %endif %endfor diff -r d146ca99434f -r 8f630db17cf1 templates/root/history_common.mako --- a/templates/root/history_common.mako Thu Oct 08 11:33:43 2009 -0400 +++ b/templates/root/history_common.mako Thu Oct 08 13:38:32 2009 -0400 @@ -1,6 +1,6 @@ <% _=n_ %> ## Render the dataset `data` as history item, using `hid` as the displayed id -<%def name="render_dataset( data, hid, show_deleted_on_refresh = False )"> +<%def name="render_dataset( data, hid, show_deleted_on_refresh = False, user_owns_dataset = True )"> <% if data.state in ['no state','',None]: data_state = "queued" @@ -19,21 +19,27 @@ <strong>This dataset has been deleted. Click <a href="${h.url_for( controller='dataset', action='undelete', id=data.id )}" class="historyItemUndelete" id="historyItemUndeleter-${data.id}" target="galaxy_history">here</a> to undelete.</strong> </div> %endif - + ## Header row for history items (name, state, action buttons) <div style="overflow: hidden;" class="historyItemTitleBar"> <div class="historyItemButtons"> %if data_state == "upload": - ## TODO: Make these CSS, just adding a "disabled" class to the normal - ## links should be enough. However the number of datasets being uploaded - ## at a time is usually small so the impact of these images is also small. - <img src="${h.url_for('/static/images/eye_icon_grey.png')}" width='16' height='16' alt='display data' title='display data' class='button display' border='0'> - <img src="${h.url_for('/static/images/pencil_icon_grey.png')}" width='16' height='16' alt='edit attributes' title='edit attributes' class='button edit' border='0'> + ## TODO: Make these CSS, just adding a "disabled" class to the normal + ## links should be enough. However the number of datasets being uploaded + ## at a time is usually small so the impact of these images is also small. + <img src="${h.url_for('/static/images/eye_icon_grey.png')}" width='16' height='16' alt='display data' title='display data' class='button display' border='0'> + %if user_owns_dataset: + <img src="${h.url_for('/static/images/pencil_icon_grey.png')}" width='16' height='16' alt='edit attributes' title='edit attributes' class='button edit' border='0'> + %endif %else: - <a class="icon-button display" title="display data" href="${h.url_for( controller='dataset', dataset_id=data.id, action='display', filename='index')}" target="galaxy_main"></a> - <a class="icon-button edit" title="edit attributes" href="${h.url_for( controller='root', action='edit', id=data.id )}" target="galaxy_main"></a> + <a class="icon-button display" title="display data" href="${h.url_for( controller='dataset', dataset_id=data.id, action='display', filename='index')}" target="galaxy_main"></a> + %if user_owns_dataset: + <a class="icon-button edit" title="edit attributes" href="${h.url_for( controller='root', action='edit', id=data.id )}" target="galaxy_main"></a> + %endif %endif - <a class="icon-button delete" title="delete" href="${h.url_for( action='delete', id=data.id, show_deleted_on_refresh=show_deleted_on_refresh )}" id="historyItemDeleter-${data.id}"></a> + %if user_owns_dataset: + <a class="icon-button delete" title="delete" href="${h.url_for( action='delete', id=data.id, show_deleted_on_refresh=show_deleted_on_refresh )}" id="historyItemDeleter-${data.id}"></a> + %endif </div> <span class="state-icon"></span> <span class="historyItemTitle"><b>${hid}: ${data.display_name().decode('utf-8')}</b></span> @@ -80,8 +86,10 @@ <div class="info">${_('Info: ')}${data.display_info()}</div> <div> %if data.has_data: - <a href="${h.url_for( action='display', id=data.id, tofile='yes', toext=data.ext )}" target="_blank">save</a> - | <a href="${h.url_for( controller='tool_runner', action='rerun', id=data.id )}" target="galaxy_main">rerun</a> + <a href="${h.url_for( controller='root', action='display', id=data.id, tofile='yes', toext=data.ext )}" target="_blank">save</a> + %if user_owns_dataset: + | <a href="${h.url_for( controller='tool_runner', action='rerun', id=data.id )}" target="galaxy_main">rerun</a> + %endif %for display_app in data.datatype.get_display_types(): <% target_frame, display_links = data.datatype.get_display_links( data, display_app, app, request.base ) %> %if len( display_links ) > 0: diff -r d146ca99434f -r 8f630db17cf1 templates/tagging_common.mako --- a/templates/tagging_common.mako Thu Oct 08 11:33:43 2009 -0400 +++ b/templates/tagging_common.mako Thu Oct 08 13:38:32 2009 -0400 @@ -4,7 +4,7 @@ %endif ## Render the tags 'tags' as an autocomplete element. -<%def name="render_tagging_element(tagged_item, elt_id, use_toggle_link='true', in_form='false', input_size='15', tag_click_fn='default_tag_click_fn', get_toggle_link_text_fn='default_get_toggle_link_text_fn')"> +<%def name="render_tagging_element(tagged_item, elt_id, use_toggle_link='true', in_form='false', input_size='15', tag_click_fn='default_tag_click_fn', get_toggle_link_text_fn='default_get_toggle_link_text_fn', editable='true')"> <script type="text/javascript"> // // Set up autocomplete tagger. @@ -83,6 +83,7 @@ var options = { tags : ${h.to_json_string(tag_names_and_values)}, + editable : ${str(editable).lower()}, get_toggle_link_text_fn: ${get_toggle_link_text_fn}, tag_click_fn: ${tag_click_fn}, <% tagged_item_id = trans.security.encode_id(tagged_item.id) %> diff -r d146ca99434f -r 8f630db17cf1 test/functional/test_history_functions.py --- a/test/functional/test_history_functions.py Thu Oct 08 11:33:43 2009 -0400 +++ b/test/functional/test_history_functions.py Thu Oct 08 13:38:32 2009 -0400 @@ -164,7 +164,7 @@ # Enable importing history3 via a URL self.enable_import_via_link( self.security.encode_id( history3.id ), check_str='Unshare', - check_str_after_submit='Send the above URL to users' ) + check_str_after_submit='Send the above link to users' ) # Make sure history3 is now import-able history3.refresh() if not history3.importable: @@ -175,7 +175,7 @@ check_str_after_submit='You cannot import your own history.' ) # Disable the import link for history3 self.disable_import_via_link( self.security.encode_id( history3.id ), - check_str='Send the above URL to users', + check_str='Send the above link to users', check_str_after_submit='Enable import via link' ) # Try importing history3 after disabling the URL self.import_history_via_url( self.security.encode_id( history3.id ),
participants (1)
-
Greg Von Kuster