details: http://www.bx.psu.edu/hg/galaxy/rev/90723c58b1a6 changeset: 3100:90723c58b1a6 user: jeremy goecks <jeremy.goecks@emory.edu> date: Tue Nov 17 19:06:42 2009 -0500 description: 'Insert history link' functionality added to pages. A user can select 1 or more histories and create links that point to a view of each history. diffstat: lib/galaxy/web/controllers/history.py | 23 +++++ lib/galaxy/web/controllers/page.py | 4 +- static/scripts/jquery.wymeditor.js | 91 ---------------------- static/wymeditor/lang/en.js | 4 +- templates/grid_base_async.mako | 10 ++- templates/page/editor.mako | 117 +++++++++++++++++++--------- templates/page/select_histories_grid.mako | 6 + templates/root/history.mako | 13 +++ 8 files changed, 133 insertions(+), 135 deletions(-) diffs (421 lines): diff -r 4c3cddd02b09 -r 90723c58b1a6 lib/galaxy/web/controllers/history.py --- a/lib/galaxy/web/controllers/history.py Mon Nov 16 18:38:32 2009 -0500 +++ b/lib/galaxy/web/controllers/history.py Tue Nov 17 19:06:42 2009 -0500 @@ -369,7 +369,30 @@ history.name = new_name trans.sa_session.add( history ) trans.sa_session.flush() + + @web.expose + @web.require_login( "get history name" ) + def get_name_async( self, trans, id=None ): + """ Returns the name for a given history. """ + history = get_history( trans, id, False ) + # To get name: user must own history, history must be importable. + if history.user == trans.get_user() or history.importable or trans.get_user() in history.users_shared_with: + return history.name + return + + @web.expose + @web.require_login( "set history's importable flag" ) + def set_importable_async( self, trans, id=None, importable=False ): + """ Set history's importable attribute. """ + history = get_history( trans, id, True ) + + if history: + history.importable = importable + trans.sa_session.flush() + + return + @web.expose def name_autocomplete_data( self, trans, q=None, limit=None, timestamp=None ): """Return autocomplete data for history names""" diff -r 4c3cddd02b09 -r 90723c58b1a6 lib/galaxy/web/controllers/page.py --- a/lib/galaxy/web/controllers/page.py Mon Nov 16 18:38:32 2009 -0500 +++ b/lib/galaxy/web/controllers/page.py Tue Nov 17 19:06:42 2009 -0500 @@ -116,13 +116,13 @@ # Grid definition. title = "Saved Histories" - template = "grid_base_async.mako" + template = "/page/select_histories_grid.mako" async_template = "grid_body_async.mako" model_class = model.History default_filter = { "deleted" : "False" , "shared" : "All" } default_sort_key = "-update_time" use_paging = True - num_rows_per_page = 5 + num_rows_per_page = 10 columns = [ NameColumn( "Name", key="name", model_class=model.History, filterable="advanced" ), grids.TagsColumn( "Tags", "tags", model.History, model.HistoryTagAssociation, filterable="advanced"), diff -r 4c3cddd02b09 -r 90723c58b1a6 static/scripts/jquery.wymeditor.js --- a/static/scripts/jquery.wymeditor.js Mon Nov 16 18:38:32 2009 -0500 +++ b/static/scripts/jquery.wymeditor.js Tue Nov 17 19:06:42 2009 -0500 @@ -295,67 +295,6 @@ }); -/* - Galaxy code that integrates into the WYM Editor. - */ -var Galaxy = -{ - /* - Galaxy constants for WYM Editor: - TOOLS - A string replaced by the galaxy toolbar's HTML. - TOOLS_ITEMS - A string replaced by the galaxy toolbar items. - INSERT_HISTORY - Command: open the insert history dialog. - INSERT_DATASET - Command: open the insert dataset dialog. - DIALOG_HISTORY - A dialog to insert a history. - DIALOG_DATASET - A dialog to insert a dataset. - */ - TOOLS : "{Galaxy_Tools}", - TOOLS_ITEMS : "{Galaxy_Tools_Items}", - INSERT_HISTORY : "InsertHistory", - INSERT_DATASET : "InsertDataset", - DIALOG_HISTORY : "DialogHistory", - DIALOG_DATASET : "DialogDataset", - - // Tool items overview. - toolsItems: [ - {'name': "InsertHistory", 'title': 'History', 'css': 'galaxy_tools_insert_history_link'}, - {'name': "InsertDataset", 'title': 'Dataset', 'css': 'galaxy_dataset'} - ], - - // Tools HTML. - toolsHtml: "<div class='wym_tools wym_section'>" - + "<h2>" + this.TOOLS + "</h2>" - + "<ul>" - + this.TOOLS_ITEMS - + "</ul>" - + "</div>", - - // Insert history dialog. - dialogHistoryHtml: "<body class='wym_dialog wym_dialog_history'" - + " onload='WYMeditor.INIT_DIALOG(" + WYMeditor.INDEX + ")'" - + ">" - + "<form>" - + "<fieldset>" - + "<input type='hidden' class='wym_dialog_type' value='" - + this.DIALOG_HISTORY - + "' />" - + "<legend>{Link}</legend>" - + "<div class='row'>" - + "<label>{Title}</label>" - + "<input type='text' class='wym_title' value='' size='40' />" - + "</div>" - + "<div class='row row-indent'>" - + "<input class='wym_submit' type='button'" - + " value='{Add}' />" - + "<input class='wym_cancel' type='button'" - + "value='{Cancel}' />" - + "</div>" - + "</fieldset>" - + "</form>" - + "</body>", -}; - - /********** JQUERY **********/ /** @@ -414,7 +353,6 @@ + "<div class='wym_area_right'>" + WYMeditor.CONTAINERS + WYMeditor.CLASSES - + Galaxy.TOOLS + "</div>" + "<div class='wym_area_main'>" + WYMeditor.HTML @@ -445,8 +383,6 @@ + "<h2>{Tools}</h2>" + "<ul>" + WYMeditor.TOOLS_ITEMS - // Add Galaxy Tools. - //+ Galaxy.TOOLS_ITEMS + "</ul>" + "</div>", @@ -821,7 +757,6 @@ boxHtml = h.replaceAll(boxHtml, WYMeditor.LOGO, this._options.logoHtml); boxHtml = h.replaceAll(boxHtml, WYMeditor.TOOLS, this._options.toolsHtml); - boxHtml = h.replaceAll(boxHtml, Galaxy.TOOLS, Galaxy.toolsHtml); boxHtml = h.replaceAll(boxHtml, WYMeditor.CONTAINERS,this._options.containersHtml); boxHtml = h.replaceAll(boxHtml, WYMeditor.CLASSES, this._options.classesHtml); boxHtml = h.replaceAll(boxHtml, WYMeditor.HTML, this._options.htmlHtml); @@ -846,24 +781,6 @@ boxHtml = h.replaceAll(boxHtml, WYMeditor.TOOLS_ITEMS, sTools); - // Construct Galaxy tools list. - var galaxyTools = eval(Galaxy.toolsItems); - sTools = ""; - for(var i = 0; i < galaxyTools.length; i++) { - var galaxyTool = galaxyTools[i]; - if(galaxyTool.name && galaxyTool.title) { - var sTool = this._options.toolsItemHtml; - var sTool = h.replaceAll(sTool, WYMeditor.TOOL_NAME, galaxyTool.name); - sTool = h.replaceAll(sTool, WYMeditor.TOOL_TITLE, this._options.stringDelimiterLeft - + galaxyTool.title - + this._options.stringDelimiterRight); - sTool = h.replaceAll(sTool, WYMeditor.TOOL_CLASS, galaxyTool.css); - sTools += sTool; - } - } - - //boxHtml = h.replaceAll(boxHtml, Galaxy.TOOLS_ITEMS, sTools); - //construct classes list var aClasses = eval(this._options.classesItems); var sClasses = ""; @@ -1029,10 +946,6 @@ this.dialog(WYMeditor.PREVIEW, this._options.dialogFeaturesPreview); break; - case Galaxy.INSERT_HISTORY: - this.dialog(Galaxy.DIALOG_HISTORY); - break; - default: this._exec(cmd); break; @@ -1263,10 +1176,6 @@ case(WYMeditor.PREVIEW): sBodyHtml = this._options.dialogPreviewHtml; break; - case(Galaxy.DIALOG_HISTORY): - sBodyHtml = Galaxy.dialogHistoryHtml; - break; - default: sBodyHtml = bodyHtml; } diff -r 4c3cddd02b09 -r 90723c58b1a6 static/wymeditor/lang/en.js --- a/static/wymeditor/lang/en.js Mon Nov 16 18:38:32 2009 -0500 +++ b/static/wymeditor/lang/en.js Tue Nov 17 19:06:42 2009 -0500 @@ -43,7 +43,7 @@ Source_Code: 'Source code', // Galaxy replacements. - History: 'History', - Dataset: 'Dataset', + Galaxy_History_Link: 'Insert Link to History', + Galaxy_Dataset_Link: 'Insert Link to Dataset', }; diff -r 4c3cddd02b09 -r 90723c58b1a6 templates/grid_base_async.mako --- a/templates/grid_base_async.mako Mon Nov 16 18:38:32 2009 -0500 +++ b/templates/grid_base_async.mako Tue Nov 17 19:06:42 2009 -0500 @@ -407,7 +407,11 @@ // Update grid. function update_grid(maintain_page_links) { + // If there's an operation in the args, do POST; otherwise, do GET. + var operation = url_args['operation']; + var method = (operation != null && operation != undefined ? "POST" : "GET" ); $.ajax({ + type: method, url: "${h.url_for()}", data: url_args, error: function() { alert( "Grid refresh failed" ) }, @@ -504,9 +508,11 @@ <%namespace file="./grid_common_async.mako" import="*" /> ## Print grid header. -<%def name="render_grid_header()"> +<%def name="render_grid_header(include_title)"> <div class="grid-header"> - <h2>${grid.title}</h2> + %if include_title: + <h2>${grid.title}</h2> + %endif %if grid.global_actions: <ul class="manage-table-actions"> diff -r 4c3cddd02b09 -r 90723c58b1a6 templates/page/editor.mako --- a/templates/page/editor.mako Mon Nov 16 18:38:32 2009 -0500 +++ b/templates/page/editor.mako Tue Nov 17 19:06:42 2009 -0500 @@ -39,6 +39,13 @@ <script type='text/javascript' src="${h.url_for('/static/scripts/jquery.autocomplete.js')}"> </script> <script type="text/javascript"> + + // Useful Galaxy stuff. + var Galaxy = + { + DIALOG_HISTORY_LINK : "history_link", + }; + ## Completely replace WYM's dialog handling WYMeditor.editor.prototype.dialog = function( dialogType, dialogFeatures, bodyHtml ) { @@ -187,45 +194,73 @@ } // HISTORY DIALOG - if ( dialogType == Galaxy.DIALOG_HISTORY ) { - show_modal( - "Insert History", - "<div class='row'>" - + "<label>History Name</label><br>" - + "<input id='history_name_input' type='text' class='wym_galaxy_history_name' value='' size='40' />" - + "</div>" - + "<div class='row'>" - + "<label>Select History</label><br>" - + "<input type='text' class='wym_galaxy_history_selected' value='' size='40' />" - + "</div>" - , - { - "Insert": function() { - var sUrl = jQuery(wym._options.hrefSelector).val(); - if(sUrl.length > 0) { - - wym._exec(WYMeditor.CREATE_LINK, sStamp); - - jQuery("a[href=" + sStamp + "]", wym._doc.body) - .attr(WYMeditor.HREF, sUrl) - .attr(WYMeditor.TITLE, jQuery(wym._options.titleSelector).val()); - hide_modal(); - - // TODO: remove autocomplete. - }, - "Cancel": function() { - hide_modal(); - - // TODO: remove autocomplete. - } + if ( dialogType == Galaxy.DIALOG_HISTORY_LINK ) { + $.ajax( + { + url: "${h.url_for( action='list_histories_for_selection' )}", + data: {}, + error: function() { alert( "Grid refresh failed" ) }, + success: function(table_html) + { + show_modal( + "Insert Link to History", + table_html + + "<div><input id='make-importable' type='checkbox' checked/>" + + "Publish the selected histories so that they can viewed by everyone.</div>" + , + { + "Insert": function() + { + // Make histories public/importable? + var make_importable = false; + if ( $('#make-importable:checked').val() !== null ) + make_importable = true; + + // Insert links to history for each checked item. + var item_ids = new Array(); + $('input[name=id]:checked').each(function() { + var item_id = $(this).val(); + + // Make history importable? + if (make_importable) + $.ajax({ + type: "POST", + url: '${h.url_for( controller='history', action='set_importable_async' )}', + data: { id: item_id, importable: 'True' }, + error: function() { alert('Make history importable failed; id=' + item_id) } + }); + + // Insert link. + wym._exec(WYMeditor.CREATE_LINK, sStamp); + if ( $("a[href=" + sStamp + "]", wym._doc.body).length != 0) + { + // Link created from selected text; add href and title. + $("a[href=" + sStamp + "]", wym._doc.body) + .attr(WYMeditor.HREF, '${h.url_for( controller='history', action='view' )}' + '?id=' + item_id) + .attr(WYMeditor.TITLE, "History" + item_id); + } + else + { + // User selected no text; create link from scratch and use default text. + + // Get history name. + $.get( '${h.url_for( controller='history', action='get_name_async' )}?id=' + item_id, function( history_name ) { + var href = '${h.url_for( controller='history', action='view' )}?id=' + item_id; + wym.insert("<a href='" + href + "'>History '" + history_name + "'</a>"); + }); + } + }); + + hide_modal(); + }, + "Cancel": function() + { + hide_modal(); + } + } + ); } - ); - - // Set up autocomplete for name input. - var t = $("#history_name_input"); - var autocomplete_options = - { selectFirst: false, autoFill: false, highlight: false, mustMatch: false }; - t.autocomplete("${h.url_for( controller='history', action='name_autocomplete_data' )}", autocomplete_options); + }); } }; </script> @@ -272,6 +307,7 @@ {'name': 'Unlink', 'title': 'Unlink', 'css': 'wym_tools_unlink'}, {'name': 'InsertImage', 'title': 'Image', 'css': 'wym_tools_image'}, {'name': 'InsertTable', 'title': 'Table', 'css': 'wym_tools_table'}, + {'name': 'Insert Galaxy History Link', 'title' : 'Galaxy_History_Link', 'css' : 'galaxy_tools_insert_history_link'} ] }); ## Get the editor object @@ -320,6 +356,11 @@ window.document.location = "${next_url}"; } }); + + // Initialize 'Insert history link' button. + $('.galaxy_tools_insert_history_link').children().click( function() { + editor.dialog(Galaxy.DIALOG_HISTORY_LINK); + }); }); </script> </%def> diff -r 4c3cddd02b09 -r 90723c58b1a6 templates/page/select_histories_grid.mako --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/templates/page/select_histories_grid.mako Tue Nov 17 19:06:42 2009 -0500 @@ -0,0 +1,6 @@ +## Template generates a grid that enables user to select histories. +<%namespace file="../grid_base_async.mako" import="*" /> + +${javascripts()} +${render_grid_header(False)} +${render_grid_table()} \ No newline at end of file diff -r 4c3cddd02b09 -r 90723c58b1a6 templates/root/history.mako --- a/templates/root/history.mako Mon Nov 16 18:38:32 2009 -0500 +++ b/templates/root/history.mako Tue Nov 17 19:06:42 2009 -0500 @@ -246,6 +246,19 @@ } }); }; + + //TODO: this function is a duplicate of array_length defined in galaxy.base.js ; not sure why it needs to be redefined here (due to streaming?). + // Returns the number of keys (elements) in an array/dictionary. + var array_length = function(an_array) + { + if (an_array.length) + return an_array.length; + + var count = 0; + for (element in an_array) + count++; + return count; + }; // // Function provides text for tagging toggle link.