Merge pull request #4047 from bgruening/workflowexport_mako

New Workflow Management Screen UI using JavaScript
This commit is contained in:
Dannon Baker
2017-05-11 12:24:22 -04:00
committed by GitHub
21 changed files with 302 additions and 283 deletions
+9 -3
View File
@@ -8,9 +8,10 @@ var jQuery = require( 'jquery' ),
HistoryPanel = require( './history-panel' ),
PAGE = require( 'layout/page' ),
ToolForm = require( 'mvc/tool/tool-form' ),
UserPreferences = require( 'mvc/user/user-preferences' );
CustomBuilds = require( 'mvc/user/user-custom-builds' );
Tours = require( 'mvc/tours' );
UserPreferences = require( 'mvc/user/user-preferences' ),
CustomBuilds = require( 'mvc/user/user-custom-builds' ),
Tours = require( 'mvc/tours' ),
Workflows = require( 'mvc/workflow/workflow' );
/** define the 'Analyze Data'/analysis/main/home page for Galaxy
* * has a masthead
@@ -121,6 +122,7 @@ window.app = function app( options, bootstrapped ){
'(/)tours(/)(:tour_id)' : 'show_tours',
'(/)user(/)' : 'show_user',
'(/)user(/)(:form_id)' : 'show_user_form',
'(/)workflow(/)' : 'show_workflows',
'(/)custom_builds' : 'show_custom_builds'
},
@@ -153,6 +155,10 @@ window.app = function app( options, bootstrapped ){
centerPanel.display( new UserPreferences.Forms( { form_id: form_id, user_id: Galaxy.params.id } ) );
},
show_workflows : function(){
centerPanel.display( new Workflows.View() );
},
show_custom_builds : function() {
var self = this;
if ( !Galaxy.currHistoryPanel || !Galaxy.currHistoryPanel.model || !Galaxy.currHistoryPanel.model.id ) {
+12 -2
View File
@@ -63,9 +63,9 @@ var ToolPanel = LeftPanel.extend({
_renderWorkflowMenu : function(){
var self = this;
// add internal workflow list
self.$( '#internal-workflows' ).append( self._templateTool({
self.$( '#internal-workflows' ).append( self._templateAllWorkflow({
title : _l( 'All workflows' ),
href : 'workflow/list_for_run'
href : 'workflow'
}));
_.each( self.stored_workflow_menu_entries, function( menu_entry ){
self.$( '#internal-workflows' ).append( self._templateTool({
@@ -85,6 +85,16 @@ var ToolPanel = LeftPanel.extend({
].join('');
},
/** build a link to 'All Workflows' */
_templateAllWorkflow: function( tool ) {
return [
'<div class="toolTitle">',
// global
'<a href="', Galaxy.root, tool.href, '">', tool.title, '</a>',
'</div>'
].join('');
},
/** override to include inital menu dom and workflow section */
_templateBody : function(){
return [
+6 -2
View File
@@ -33,9 +33,13 @@ var Collection = Backbone.Collection.extend({
this.add({
id : 'workflow',
title : _l('Workflow'),
url : 'workflow',
tooltip : _l('Chain tools into workflows'),
disabled : !Galaxy.user.id
disabled : !Galaxy.user.id,
url : 'workflow',
target : 'galaxy_main',
onclick : function() {
window.location = Galaxy.root + 'workflow';
}
});
//
@@ -0,0 +1,198 @@
/** Workflow view */
define( [], function() {
/** View of the main workflow list page */
var View = Backbone.View.extend({
initialize: function() {
this.setElement( '<div/>' );
this.render();
},
render: function() {
var self = this,
min_query_length = 3;
$.getJSON( Galaxy.root + 'api/workflows/', function( workflows ) {
var $el_workflow = null;
// Add workflow header
self.$el.empty().append( self._templateHeader() );
// Add user actions message if any
self.build_messages( self );
$el_workflow = self.$el.find( '.user-workflows' );
// Add the actions buttons
$el_workflow.append( self._templateActionButtons() );
if( workflows.length > 0) {
$el_workflow.append( self._templateWorkflowTable( self, workflows) );
self.adjust_actiondropdown( $el_workflow );
// Register delete and run workflow events
_.each( workflows, function( wf ) {
self.confirm_delete( self, wf );
});
// Register search workflow event
self.search_workflow( self, self.$el.find( '.search-wf' ), self.$el.find( '.workflow-search tr' ), min_query_length );
}
else {
$el_workflow.append( self._templateNoWorkflow() );
}
});
},
/** Build messages after user action */
build_messages: function( self ) {
var $el_message = self.$el.find( '.response-message' ),
status = self.get_querystring( 'status' ),
message = self.get_querystring( 'message' );
if( message && message !== null && message !== "" ) {
$el_message.addClass( status + 'message' );
$el_message.html( '<p>' + message + '</p>' );
}
else {
$el_message.html("");
}
},
/** Add confirm box before removing/unsharing workflow */
confirm_delete: function( self, workflow ) {
var $el_wf_link = self.$el.find( '.link-confirm-' + workflow.id ),
$el_shared_wf_link = self.$el.find( '.link-confirm-shared-' + workflow.id );
$el_wf_link.click( function() {
return confirm( "Are you sure you want to delete workflow '" + workflow.name + "'?" );
});
$el_shared_wf_link.click( function() {
return confirm( "Are you sure you want to remove the shared workflow '" + workflow.name + "'?" );
});
},
/** Implement client side workflow search/filtering */
search_workflow: function( self, $el_searchinput, $el_tabletr, min_querylen ) {
$el_searchinput.on( 'keyup', function () {
var query = $( this ).val();
// Filter when query is at least 3 characters
// otherwise show all rows
if( query.length >= min_querylen ) {
// Ignore the query's case using 'i'
var regular_expression = new RegExp( query, 'i' );
$el_tabletr.hide();
$el_tabletr.filter(function () {
// Apply regular expression on each row's text
// and show when there is a match
return regular_expression.test( $( this ).text() );
}).show();
}
else {
$el_tabletr.show();
}
});
},
/** Get querystrings from url */
get_querystring: function( key ) {
return decodeURIComponent( window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURIComponent( key ).replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1") );
},
/** Ajust the position of dropdown with respect to table */
adjust_actiondropdown: function( $el ) {
$el.on( 'show.bs.dropdown', function () {
$el.css( "overflow", "inherit" );
});
$el.on( 'hide.bs.dropdown', function () {
$el.css( "overflow", "auto" );
});
},
/** Template for no workflow */
_templateNoWorkflow: function() {
return '<div class="wf-nodata"> You have no workflows. </div>';
},
/** Template for actions buttons */
_templateActionButtons: function() {
return '<ul class="manage-table-actions">' +
'<li>' +
'<input class="search-wf form-control" type="text" autocomplete="off" placeholder="search for workflow...">' +
'</li>' +
'<li>' +
'<a class="action-button fa fa-plus wf-action" id="new-workflow" title="Create new workflow" href="'+ Galaxy.root +'workflow/create">' +
'</a>' +
'</li>' +
'<li>' +
'<a class="action-button fa fa-upload wf-action" id="import-workflow" title="Upload or import workflow" href="'+ Galaxy.root +'workflow/import_workflow">' +
'</a>' +
'</li>' +
'</ul>';
},
/** Template for workflow table */
_templateWorkflowTable: function( self, workflows ) {
var tableHtml = "", trHtml = "";
tableHtml = tableHtml + '<table class="table colored"><thead>' +
'<tr class="header">' +
'<th class="wf-td">Name</th>' +
'<th class="wf-td">Owner</th>' +
'<th class="wf-td"># of Steps</th>' +
'<th class="wf-td">Published</th>' +
'</tr></thead>';
_.each( workflows, function( wf ) {
trHtml = trHtml + '<tr>' +
'<td class="wf-td wf-dpd">' +
'<div class="dropdown">' +
'<button class="menubutton" type="button" data-toggle="dropdown">' +
_.escape( wf.name ) + '<span class="caret"></span>' +
'</button>' +
self._templateActions( wf ) +
'</div>' +
'</td>' +
'<td>' + ( wf.owner === Galaxy.user.attributes.username ? "You" : wf.owner ) +'</td>' +
'<td class="wf-td">' + wf.number_of_steps + '</td>' +
'<td class="wf-td">' + ( wf.published ? "Yes" : "No" ) + '</td>' +
'</tr>';
});
return tableHtml + '<tbody class="workflow-search">' + trHtml + '</tbody></table>';
},
/** Template for user actions for workflows */
_templateActions: function( workflow ) {
if( workflow.owner === Galaxy.user.attributes.username ) {
return '<ul class="dropdown-menu action-dpd">' +
'<li><a href="'+ Galaxy.root +'workflow/editor?id='+ workflow.id +'">Edit</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/run?id='+ workflow.id +'" target="galaxy_main">Run</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/sharing?id='+ workflow.id +'">Share or Download</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/copy?id='+ workflow.id +'">Copy</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/rename?id='+ workflow.id +'">Rename</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/display_by_id?id='+ workflow.id +'">View</a></li>' +
'<li><a class="link-confirm-'+ workflow.id +'" href="'+ Galaxy.root +'workflow/delete?id='+ workflow.id +'">Delete</a></li>' +
'</ul>';
}
else {
return '<ul class="dropdown-menu action-dpd">' +
'<li><a href="'+ Galaxy.root +'workflow/display_by_username_and_slug?username='+ workflow.owner +'&slug='+ workflow.slug +'">View</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/run?id='+ workflow.id +'" target="galaxy_main">Run</a></li>' +
'<li><a href="'+ Galaxy.root +'workflow/copy?id='+ workflow.id +'">Copy</a></li>' +
'<li><a class="link-confirm-shared-'+ workflow.id +'" href="'+ Galaxy.root +'workflow/sharing?unshare_me=True&id='+ workflow.id +'">Remove</a></li>' +
'</ul>';
}
},
/** Main template */
_templateHeader: function() {
return '<div class="page-container">' +
'<div class="user-workflows wf">' +
'<div class="response-message"></div>' +
'<h2>Your workflows</h2>' +
'</div>'+
'<div class="other-options wf">' +
'<h2>Other options</h2>' +
'<a class="action-button fa fa-cog wf-action" href="'+ Galaxy.root +'workflow/configure_menu" title="Configure your workflow menu">' +
'<span>Configure your workflow menu</span>' +
'</a>' +
'</div>' +
'</div>';
}
});
return {
View : View
};
});
+24 -1
View File
@@ -1766,4 +1766,27 @@ div.toolTitleNoSection
color:black;
text-align:left;
}
}
}
// workflow
.wf {
overflow: auto;
}
.wf-action span {
padding-left: 3px;
font-family: "Lucida Grande", verdana, arial, helvetica, sans-serif;
}
.wf-td {
width: 25%;
}
.wf-nodata {
padding-left: 1%;
}
.other-options {
margin-bottom: 2%;
}
@@ -65,6 +65,7 @@ class WorkflowsAPIController(BaseAPIController, UsesStoredWorkflowMixin, UsesAnn
encoded_id = trans.security.encode_id(wf.id)
item['url'] = url_for('workflow', id=encoded_id)
item['owner'] = wf.user.username
item['number_of_steps'] = len( wf.latest_workflow.steps )
rval.append(item)
for wf_sa in trans.sa_session.query( trans.app.model.StoredWorkflowUserShareAssociation ).filter_by(
user=trans.user ).join( 'stored_workflow' ).filter(
@@ -74,6 +75,8 @@ class WorkflowsAPIController(BaseAPIController, UsesStoredWorkflowMixin, UsesAnn
encoded_id = trans.security.encode_id(wf_sa.stored_workflow.id)
item['url'] = url_for( 'workflow', id=encoded_id )
item['owner'] = wf_sa.stored_workflow.user.username
item['number_of_steps'] = len( wf_sa.stored_workflow.latest_workflow.steps )
item['slug'] = wf_sa.stored_workflow.slug
rval.append(item)
return rval
+1
View File
@@ -107,6 +107,7 @@ def paste_app_factory( global_conf, **kwargs ):
webapp.add_client_route( '/tours/{tour_id}' )
webapp.add_client_route( '/user' )
webapp.add_client_route( '/user/{form_id}' )
webapp.add_client_route( '/workflow' )
webapp.add_client_route( '/custom_builds' )
# ==== Done
@@ -155,10 +155,6 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix
__myexp_url = "www.myexperiment.org:80"
@web.expose
def index( self, trans ):
return self.list( trans )
@web.expose
@web.require_login( "use Galaxy workflows" )
def list_grid( self, trans, **kwargs ):
@@ -179,52 +175,9 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix
"""
Render workflow main page (management of existing workflows)
"""
user = trans.get_user()
workflows = trans.sa_session.query( model.StoredWorkflow ) \
.filter_by( user=user, deleted=False ) \
.order_by( desc( model.StoredWorkflow.table.c.update_time ) ) \
.all()
shared_by_others = trans.sa_session \
.query( model.StoredWorkflowUserShareAssociation ) \
.filter_by( user=user ) \
.join( 'stored_workflow' ) \
.filter( model.StoredWorkflow.deleted == expression.false() ) \
.order_by( desc( model.StoredWorkflow.update_time ) ) \
.all()
# Legacy issue: all shared workflows must have slugs.
slug_set = False
for workflow_assoc in shared_by_others:
if self.create_item_slug( trans.sa_session, workflow_assoc.stored_workflow ):
slug_set = True
if slug_set:
trans.sa_session.flush()
return trans.fill_template( "workflow/list.mako",
workflows=workflows,
shared_by_others=shared_by_others )
@web.expose
@web.require_login( "use Galaxy workflows" )
def list_for_run( self, trans ):
"""
Render workflow list for analysis view (just allows running workflow
or switching to management view)
"""
user = trans.get_user()
workflows = trans.sa_session.query( model.StoredWorkflow ) \
.filter_by( user=user, deleted=False ) \
.order_by( desc( model.StoredWorkflow.table.c.update_time ) ) \
.all()
shared_by_others = trans.sa_session \
.query( model.StoredWorkflowUserShareAssociation ) \
.filter_by( user=user ) \
.filter( model.StoredWorkflow.deleted == expression.false() ) \
.order_by( desc( model.StoredWorkflow.table.c.update_time ) ) \
.all()
return trans.fill_template( "workflow/list_for_run.mako",
workflows=workflows,
shared_by_others=shared_by_others )
# Take care of proxy prefix in url as well
redirect_url = url_for( '/' ) + 'workflow'
return trans.response.send_redirect( redirect_url )
@web.expose
def list_published( self, trans, **kwargs ):
@@ -425,8 +378,11 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix
stored.name = san_new_name
stored.latest_workflow.name = san_new_name
trans.sa_session.flush()
trans.set_message( "Workflow renamed to '%s'." % san_new_name )
return self.list( trans )
message = 'Workflow renamed to: %s' % escape( san_new_name )
trans.set_message( message )
# Take care of proxy prefix in url as well
redirect_url = url_for( '/' ) + 'workflow?status=done&message=%s' % escape( message )
return trans.response.send_redirect( redirect_url )
else:
return form( url_for(controller='workflow', action='rename', id=trans.security.encode_id(stored.id) ),
"Rename workflow",
@@ -543,7 +499,7 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix
if (save_as_name):
new_stored.name = '%s' % save_as_name
else:
new_stored.name = "Copy of '%s'" % stored.name
new_stored.name = "Copy of %s" % stored.name
new_stored.latest_workflow = stored.latest_workflow
# Copy annotation.
annotation_obj = self.get_item_annotation_obj( trans.sa_session, stored.user, stored )
@@ -551,15 +507,17 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix
self.add_item_annotation( trans.sa_session, trans.get_user(), new_stored, annotation_obj.annotation )
new_stored.copy_tags_from(trans.user, stored)
if not owner:
new_stored.name += " shared by '%s'" % stored.user.email
new_stored.name += " shared by %s" % stored.user.email
new_stored.user = user
# Persist
session = trans.sa_session
session.add( new_stored )
session.flush()
# Display the management page
trans.set_message( 'Created new workflow with name "%s"' % escape( new_stored.name ) )
return self.list( trans )
message = 'Created new workflow with name: %s' % escape( new_stored.name )
trans.set_message( message )
return_url = url_for( '/' ) + 'workflow?status=done&message=%s' % escape( message )
trans.response.send_redirect( return_url )
@web.expose
@web.require_login( "create workflows" )
@@ -652,8 +610,9 @@ class WorkflowController( BaseUIController, SharableMixin, UsesStoredWorkflowMix
trans.sa_session.add( stored )
trans.sa_session.flush()
# Display the management page
trans.set_message( "Workflow '%s' deleted" % escape( stored.name ) )
return self.list( trans )
message = "Workflow deleted: %s" % escape( stored.name )
trans.set_message( message )
return trans.response.send_redirect( url_for( '/' ) + 'workflow?status=done&message=%s' % escape( message ) )
@web.expose
@web.require_login( "edit workflows" )
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"workflow.js","sources":["../../../src/mvc/workflow/workflow.js"],"names":["define","View","Backbone","extend","initialize","this","setElement","render","self","min_query_length","$","getJSON","Galaxy","root","workflows","$el_workflow","$el","empty","append","_templateHeader","build_messages","find","_templateActionButtons","length","_templateWorkflowTable","adjust_actiondropdown","_","each","wf","confirm_delete","search_workflow","_templateNoWorkflow","$el_message","status","get_querystring","message","addClass","html","workflow","$el_wf_link","id","$el_shared_wf_link","click","confirm","name","$el_searchinput","$el_tabletr","min_querylen","on","query","val","regular_expression","RegExp","hide","filter","test","text","show","key","decodeURIComponent","window","location","search","replace","encodeURIComponent","css","tableHtml","trHtml","escape","_templateActions","owner","user","attributes","username","number_of_steps","published","slug"],"mappings":"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"}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
define([],function(){var a=Backbone.View.extend({initialize:function(){this.setElement("<div/>"),this.render()},render:function(){var a=this,b=3;$.getJSON(Galaxy.root+"api/workflows/",function(c){var d=null;a.$el.empty().append(a._templateHeader()),a.build_messages(a),d=a.$el.find(".user-workflows"),d.append(a._templateActionButtons()),c.length>0?(d.append(a._templateWorkflowTable(a,c)),a.adjust_actiondropdown(d),_.each(c,function(b){a.confirm_delete(a,b)}),a.search_workflow(a,a.$el.find(".search-wf"),a.$el.find(".workflow-search tr"),b)):d.append(a._templateNoWorkflow())})},build_messages:function(a){var b=a.$el.find(".response-message"),c=a.get_querystring("status"),d=a.get_querystring("message");d&&null!==d&&""!==d?(b.addClass(c+"message"),b.html("<p>"+d+"</p>")):b.html("")},confirm_delete:function(a,b){var c=a.$el.find(".link-confirm-"+b.id),d=a.$el.find(".link-confirm-shared-"+b.id);c.click(function(){return confirm("Are you sure you want to delete workflow '"+b.name+"'?")}),d.click(function(){return confirm("Are you sure you want to remove the shared workflow '"+b.name+"'?")})},search_workflow:function(a,b,c,d){b.on("keyup",function(){var a=$(this).val();if(a.length>=d){var b=new RegExp(a,"i");c.hide(),c.filter(function(){return b.test($(this).text())}).show()}else c.show()})},get_querystring:function(a){return decodeURIComponent(window.location.search.replace(new RegExp("^(?:.*[&\\?]"+encodeURIComponent(a).replace(/[\.\+\*]/g,"\\$&")+"(?:\\=([^&]*))?)?.*$","i"),"$1"))},adjust_actiondropdown:function(a){a.on("show.bs.dropdown",function(){a.css("overflow","inherit")}),a.on("hide.bs.dropdown",function(){a.css("overflow","auto")})},_templateNoWorkflow:function(){return'<div class="wf-nodata"> You have no workflows. </div>'},_templateActionButtons:function(){return'<ul class="manage-table-actions"><li><input class="search-wf form-control" type="text" autocomplete="off" placeholder="search for workflow..."></li><li><a class="action-button fa fa-plus wf-action" id="new-workflow" title="Create new workflow" href="'+Galaxy.root+'workflow/create"></a></li><li><a class="action-button fa fa-upload wf-action" id="import-workflow" title="Upload or import workflow" href="'+Galaxy.root+'workflow/import_workflow"></a></li></ul>'},_templateWorkflowTable:function(a,b){var c="",d="";return c+='<table class="table colored"><thead><tr class="header"><th class="wf-td">Name</th><th class="wf-td">Owner</th><th class="wf-td"># of Steps</th><th class="wf-td">Published</th></tr></thead>',_.each(b,function(b){d=d+'<tr><td class="wf-td wf-dpd"><div class="dropdown"><button class="menubutton" type="button" data-toggle="dropdown">'+_.escape(b.name)+'<span class="caret"></span></button>'+a._templateActions(b)+"</div></td><td>"+(b.owner===Galaxy.user.attributes.username?"You":b.owner)+'</td><td class="wf-td">'+b.number_of_steps+'</td><td class="wf-td">'+(b.published?"Yes":"No")+"</td></tr>"}),c+'<tbody class="workflow-search">'+d+"</tbody></table>"},_templateActions:function(a){return a.owner===Galaxy.user.attributes.username?'<ul class="dropdown-menu action-dpd"><li><a href="'+Galaxy.root+"workflow/editor?id="+a.id+'">Edit</a></li><li><a href="'+Galaxy.root+"workflow/run?id="+a.id+'" target="galaxy_main">Run</a></li><li><a href="'+Galaxy.root+"workflow/sharing?id="+a.id+'">Share or Download</a></li><li><a href="'+Galaxy.root+"workflow/copy?id="+a.id+'">Copy</a></li><li><a href="'+Galaxy.root+"workflow/rename?id="+a.id+'">Rename</a></li><li><a href="'+Galaxy.root+"workflow/display_by_id?id="+a.id+'">View</a></li><li><a class="link-confirm-'+a.id+'" href="'+Galaxy.root+"workflow/delete?id="+a.id+'">Delete</a></li></ul>':'<ul class="dropdown-menu action-dpd"><li><a href="'+Galaxy.root+"workflow/display_by_username_and_slug?username="+a.owner+"&slug="+a.slug+'">View</a></li><li><a href="'+Galaxy.root+"workflow/run?id="+a.id+'" target="galaxy_main">Run</a></li><li><a href="'+Galaxy.root+"workflow/copy?id="+a.id+'">Copy</a></li><li><a class="link-confirm-shared-'+a.id+'" href="'+Galaxy.root+"workflow/sharing?unshare_me=True&id="+a.id+'">Remove</a></li></ul>'},_templateHeader:function(){return'<div class="page-container"><div class="user-workflows wf"><div class="response-message"></div><h2>Your workflows</h2></div><div class="other-options wf"><h2>Other options</h2><a class="action-button fa fa-cog wf-action" href="'+Galaxy.root+'workflow/configure_menu" title="Configure your workflow menu"><span>Configure your workflow menu</span></a></div></div>'}});return{View:a}});
//# sourceMappingURL=../../../maps/mvc/workflow/workflow.js.map
File diff suppressed because one or more lines are too long
-122
View File
@@ -1,122 +0,0 @@
<%inherit file="/webapps/galaxy/base_panels.mako"/>
<%def name="init()">
<%
self.has_left_panel=False
self.has_right_panel=False
self.active_view="workflow"
self.message_box_visible=False
%>
</%def>
<%def name="title()">Workflow home</%def>
<%def name="center_panel()">
<div style="overflow: auto; height: 100%;">
<div class="page-container" style="padding: 10px;">
%if message:
<%
try:
status
except:
status = "done"
%>
<p />
<div class="${status}message">
${h.to_unicode( message )}
</div>
%endif
<h2>Your workflows</h2>
<ul class="manage-table-actions">
<li>
<a class="action-button" id="new-workflow" href="${h.url_for( controller='workflow', action='create' )}">
<img src="${h.url_for('/static/images/silk/add.png')}" />
<span>Create new workflow</span>
</a>
</li>
<li>
<a class="action-button" id="import-workflow" href="${h.url_for( controller='workflow', action='import_workflow' )}">
<img src="${h.url_for('/static/images/fugue/arrow-090.png')}" />
<span>Upload or import workflow</span>
</a>
</li>
</ul>
%if workflows:
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" style="width:100%;">
<tr class="header">
<th>Name</th>
<th># of Steps</th>
## <th>Last Updated</th>
<th></th>
</tr>
%for i, workflow in enumerate( workflows ):
<tr>
<td>
<div class="menubutton" style="float: left;" id="wf-${i}-popup">
${h.to_unicode( workflow.name ) | h}
</div>
</td>
<td>${len(workflow.latest_workflow.steps)}</td>
## <td>${str(workflow.update_time)[:19]}</td>
<td>
<div popupmenu="wf-${i}-popup">
<a class="action-button" href="${h.url_for( controller='workflow', action='editor', id=trans.security.encode_id( workflow.id ) )}" target="_parent">Edit</a>
<a class="action-button" href="${h.url_for( controller='root', action='index', workflow_id=trans.security.encode_id( workflow.id ) )}" target="_parent">Run</a>
<a class="action-button" href="${h.url_for( controller='workflow', action='sharing', id=trans.security.encode_id( workflow.id ) )}">Share or Download</a>
<a class="action-button" href="${h.url_for( controller='workflow', action='copy', id=trans.security.encode_id( workflow.id ) )}">Copy</a>
<a class="action-button" href="${h.url_for( controller='workflow', action='rename', id=trans.security.encode_id( workflow.id ) )}">Rename</a>
<a class="action-button" href="${h.url_for( controller='workflow', action='display_by_id', id=trans.security.encode_id( workflow.id ) )}" target="_top">View</a>
<a class="action-button" confirm="Are you sure you want to delete workflow '${h.to_unicode( workflow.name ) | h}'?" href="${h.url_for( controller='workflow', action='delete', id=trans.security.encode_id( workflow.id ) )}">Delete</a>
</div>
</td>
</tr>
%endfor
</table>
%else:
You have no workflows.
%endif
<h2>Workflows shared with you by others</h2>
%if shared_by_others:
<table class="colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr class="header">
<th>Name</th>
<th>Owner</th>
<th># of Steps</th>
<th></th>
</tr>
%for i, association in enumerate( shared_by_others ):
<% workflow = association.stored_workflow %>
<tr>
<td>
<a class="menubutton" id="shared-${i}-popup" href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name ) | h}</a>
</td>
<td>${workflow.user.email}</td>
<td>${len(workflow.latest_workflow.steps)}</td>
<td>
<div popupmenu="shared-${i}-popup">
<a class="action-button" href="${h.url_for( controller='workflow', action='display_by_username_and_slug', username=workflow.user.username, slug=workflow.slug )}" target="_top">View</a>
<a class="action-button" href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id( workflow.id ) )}">Run</a>
<a class="action-button" href="${h.url_for( controller='workflow', action='copy', id=trans.security.encode_id( workflow.id ) )}">Copy</a>
<a class="action-button" confirm="Are you sure you want to remove the shared workflow '${h.to_unicode( workflow.name ) | h}'?" href="${h.url_for( controller='workflow', action='sharing', unshare_me=True, id=trans.security.encode_id( workflow.id ))}">Remove</a>
</div>
</td>
</tr>
%endfor
</table>
%else:
No workflows have been shared with you.
%endif
<h2>Other options</h2>
<a class="action-button" href="${h.url_for( controller='workflow', action='configure_menu' )}">
<span>Configure your workflow menu</span>
</a>
</div>
</div>
</%def>
@@ -1,66 +0,0 @@
<%inherit file="/base.mako"/>
<%def name="title()">Workflow home</%def>
<h2>Your workflows</h2>
<ul class="manage-table-actions">
<li>
<a class="action-button" href="${h.url_for( controller='workflow', action='index' )}" target="_parent">
<span>Switch to workflow management view</span>
</a>
</li>
</ul>
%if workflows:
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr class="header">
<th>Name</th>
<th># of Steps</th>
## <th>Last Updated</th>
<th></th>
</tr>
%for i, workflow in enumerate( workflows ):
<tr>
<td>
<a href="${h.url_for(controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${h.to_unicode( workflow.name ) | h}</a>
<a id="wf-${i}-popup" class="popup-arrow" style="display: none;">&#9660;</a>
</td>
<td>${len(workflow.latest_workflow.steps)}</td>
## <td>${str(workflow.update_time)[:19]}</td>
</tr>
%endfor
</table>
%else:
You have no workflows.
%endif
<h2>Workflows shared with you by others</h2>
%if shared_by_others:
<table class="colored" border="0" cellspacing="0" cellpadding="0" width="100%">
<tr class="header">
<th>Name</th>
<th>Owner</th>
<th># of Steps</th>
<th></th>
</tr>
%for i, association in enumerate( shared_by_others ):
<% workflow = association.stored_workflow %>
<tr>
<td>
<a href="${h.url_for( controller='workflow', action='run', id=trans.security.encode_id(workflow.id) )}">${workflow.name | h}</a>
<a id="shared-${i}-popup" class="popup-arrow" style="display: none;">&#9660;</a>
</td>
<td>${workflow.user.email | h}</td>
<td>${len(workflow.latest_workflow.steps)}</td>
</tr>
%endfor
</table>
%else:
No workflows have been shared with you.
%endif
+4 -5
View File
@@ -394,17 +394,16 @@ class NavigatesGalaxy(HasDriver):
self.click_masthead_workflow()
def workflow_index_table_elements(self):
self.wait_for_selector_visible(".manage-table tbody")
table_elements = self.driver.find_elements_by_css_selector(".manage-table tbody > tr")
# drop header
return table_elements[1:]
self.wait_for_selector_visible("tbody.workflow-search")
table_elements = self.driver.find_elements_by_css_selector("tbody.workflow-search > tr")
return table_elements
def workflow_index_click_option(self, option_title, workflow_index=0):
table_elements = self.workflow_index_table_elements()
workflow_row = table_elements[workflow_index]
workflow_button = workflow_row.find_element_by_css_selector(".menubutton")
workflow_button.click()
menu_element = self.wait_for_selector_visible(".popmenu-wrapper .dropdown-menu")
menu_element = self.wait_for_selector_visible("ul.action-dpd")
menu_options = menu_element.find_elements_by_css_selector("li a")
found_option = False
for menu_option in menu_options:
@@ -45,7 +45,8 @@ class WorkflowManagementTestCase(SeleniumTestCase):
assert 'CoolNewName' in renamed_workflow_button.text, renamed_workflow_button.text
def _workflow_import_from_url(self):
self.click_selector(self.test_data["selectors"]["workflows"]["import_button"])
element = self.wait_for_selector_clickable(self.test_data["selectors"]["workflows"]["import_button"])
element.click()
url = "https://raw.githubusercontent.com/galaxyproject/galaxy/dev/test/base/data/test_workflow_1.ga"
form_element = self.driver.find_element_by_css_selector("#center form")
url_element = form_element.find_element_by_css_selector("input[type='text']")