diff --git a/lib/galaxy/model/__init__.py b/lib/galaxy/model/__init__.py
index c11d473a8c8..dd8f1ffc421 100644
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -1292,7 +1292,7 @@ class UserAddress( object ):
if self.phone:
html = html + '
' + 'Phone: ' + self.phone
return html
-
+
class Page( object ):
def __init__( self ):
self.id = None
@@ -1307,6 +1307,22 @@ class PageRevision( object ):
self.user = None
self.title = None
self.content = None
+
+class Visualization( object ):
+ def __init__( self ):
+ self.id = None
+ self.user = None
+ self.type = None
+ self.title = None
+ self.latest_revision = None
+ self.revisions = []
+
+class VisualizationRevision( object ):
+ def __init__( self ):
+ self.id = None
+ self.visualization = None
+ self.title = None
+ self.config = None
class Tag ( object ):
def __init__( self, id=None, type=None, parent_id=None, name=None ):
diff --git a/lib/galaxy/model/mapping.py b/lib/galaxy/model/mapping.py
index 0d12a816d50..0022a8e1188 100644
--- a/lib/galaxy/model/mapping.py
+++ b/lib/galaxy/model/mapping.py
@@ -556,6 +556,26 @@ PageRevision.table = Table( "page_revision", metadata,
Column( "content", TEXT )
)
+Visualization.table = Table( "visualization", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "user_id", Integer, ForeignKey( "galaxy_user.id" ), index=True, nullable=False ),
+ Column( "latest_revision_id", Integer,
+ ForeignKey( "visualization_revision.id", use_alter=True, name='visualization_latest_revision_id_fk' ), index=True ),
+ Column( "title", TEXT ),
+ Column( "type", TEXT )
+ )
+
+VisualizationRevision.table = Table( "visualization_revision", metadata,
+ Column( "id", Integer, primary_key=True ),
+ Column( "create_time", DateTime, default=now ),
+ Column( "update_time", DateTime, default=now, onupdate=now ),
+ Column( "visualization_id", Integer, ForeignKey( "visualization.id" ), index=True, nullable=False ),
+ Column( "title", TEXT ),
+ Column( "config", JSONType )
+ )
+
Tag.table = Table( "tag", metadata,
Column( "id", Integer, primary_key=True ),
Column( "type", Integer ),
@@ -1012,6 +1032,18 @@ assign_mapper( context, Page, Page.table,
tags=relation(PageTagAssociation, order_by=PageTagAssociation.table.c.id, backref="pages")
) )
+assign_mapper( context, VisualizationRevision, VisualizationRevision.table )
+
+assign_mapper( context, Visualization, Visualization.table,
+ properties=dict( user=relation( User ),
+ revisions=relation( VisualizationRevision, backref='visualization',
+ cascade="all, delete-orphan",
+ primaryjoin=( Visualization.table.c.id == VisualizationRevision.table.c.visualization_id ) ),
+ latest_revision=relation( VisualizationRevision, post_update=True,
+ primaryjoin=( Visualization.table.c.latest_revision_id == VisualizationRevision.table.c.id ),
+ lazy=False )
+ ) )
+
assign_mapper( context, Tag, Tag.table,
properties=dict( children=relation(Tag, backref=backref( 'parent', remote_side=[Tag.table.c.id] ) )
) )
diff --git a/lib/galaxy/web/controllers/tracks.py b/lib/galaxy/web/controllers/tracks.py
index 5bbb08ea5c3..9b56e33ec56 100644
--- a/lib/galaxy/web/controllers/tracks.py
+++ b/lib/galaxy/web/controllers/tracks.py
@@ -63,18 +63,35 @@ class TracksController( BaseController ):
return trans.fill_template( "tracks/index.mako" )
@web.expose
- def new_browser( self, trans, dbkey=None, dataset_ids=None, browse=None ):
+ def new_browser( self, trans, dbkey=None, dataset_ids=None, browse=None, title=None ):
"""
Build a new browser from datasets in the current history. Redirects
- to 'index' once datasets to browse have been selected.
+ to 'browser' once datasets to browse have been selected.
"""
session = trans.sa_session
# If the user clicked the submit button explicitly, try to build the browser
- if browse and dataset_ids:
+ if title and browse and dataset_ids:
if not isinstance( dataset_ids, list ):
dataset_ids = [ dataset_ids ]
- dataset_ids = ",".join( map( str, dataset_ids ) )
- trans.response.send_redirect( web.url_for( controller='tracks', action='browser', chrom="", dataset_ids=dataset_ids ) )
+ # Build config
+ tracks = []
+ for dataset_id in dataset_ids:
+ tracks.append( { "dataset_id": str( dataset_id ) } )
+ config = { "tracks": tracks }
+ # Build visualization object
+ vis = model.Visualization()
+ vis.user = trans.user
+ vis.title = title
+ vis.type = "trackster"
+ vis_rev = model.VisualizationRevision()
+ vis_rev.visualization = vis
+ vis_rev.title = title
+ vis_rev.config = config
+ vis.latest_revision = vis_rev
+ session.add( vis )
+ session.add( vis_rev )
+ session.flush()
+ trans.response.send_redirect( web.url_for( controller='tracks', action='browser', id=trans.security.encode_id( vis.id ) ) )
else:
# Determine the set of all dbkeys that are used in the current history
dbkeys = [ d.metadata.dbkey for d in trans.get_history().datasets if not d.deleted ]
@@ -96,14 +113,18 @@ class TracksController( BaseController ):
return trans.fill_template( "tracks/new_browser.mako", converters=browsable_types, dbkey=dbkey, dbkey_set=dbkey_set, datasets=datasets )
@web.expose
- def browser(self, trans, dataset_ids, chrom=""):
+ def browser(self, trans, id, chrom=""):
"""
Display browser for the datasets listed in `dataset_ids`.
"""
+ decoded_id = trans.security.decode_id( id )
+ session = trans.sa_session
+ vis = session.query( model.Visualization ).get( decoded_id )
tracks = []
dbkey = ""
- for dataset_id in dataset_ids.split( "," ):
- dataset = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( dataset_id )
+ for t in vis.latest_revision.config['tracks']:
+ dataset_id = t['dataset_id']
+ dataset = trans.app.model.HistoryDatasetAssociation.get( dataset_id )
tracks.append( {
"type": dataset.datatype.get_track_type(),
"name": dataset.name,
@@ -114,7 +135,8 @@ class TracksController( BaseController ):
if chrom_lengths is None:
error( "No chromosome lengths file found for '%s'" % dataset.name )
return trans.fill_template( 'tracks/browser.mako',
- dataset_ids=dataset_ids,
+ #dataset_ids=dataset_ids,
+ id=id,
tracks=tracks,
chrom=chrom,
dbkey=dbkey,
diff --git a/lib/galaxy/web/controllers/visualization.py b/lib/galaxy/web/controllers/visualization.py
new file mode 100644
index 00000000000..f862b803630
--- /dev/null
+++ b/lib/galaxy/web/controllers/visualization.py
@@ -0,0 +1,47 @@
+from galaxy.web.base.controller import *
+from galaxy.web.framework.helpers import time_ago, grids
+from galaxy.util.sanitize_html import sanitize_html
+
+
+class VisualizationListGrid( grids.Grid ):
+ # Grid definition
+ use_panels = True
+ title = "Visualizations"
+ model_class = model.Visualization
+ default_sort_key = "-create_time"
+ columns = [
+ grids.GridColumn( "Title", key="title", attach_popup=True,
+ link=( lambda item: dict( controller="tracks", action="browser", id=item.id ) ) ),
+ grids.GridColumn( "Type", key="type" ),
+ grids.GridColumn( "Created", key="create_time", format=time_ago ),
+ grids.GridColumn( "Last Updated", key="update_time", format=time_ago ),
+ ]
+ ## global_actions = [
+ ## grids.GridAction( "Add new page", dict( action='create' ) )
+ ## ]
+ operations = [
+ grids.GridOperation( "View", allow_multiple=False, url_args=dict( controller="tracks", action='browser' ) ),
+ ]
+ def apply_default_filter( self, trans, query, **kwargs ):
+ return query.filter_by( user=trans.user )
+
+class VisualizationController( BaseController ):
+
+ @web.expose
+ def index( self, trans ):
+ return trans.fill_template( "panels.mako", active_view='visualization', main_url=url_for( action='list' ) )
+
+ list_grid = VisualizationListGrid()
+ @web.expose
+ def list( self, trans, *args, **kwargs ):
+ return self.list_grid( trans, *args, **kwargs )
+
+ #@web.expose
+ #@web.require_admin
+ #def index( self, trans, *args, **kwargs ):
+ # # Build grid
+ # grid = self.list( trans, *args, **kwargs )
+ # # Render grid wrapped in panels
+ # return trans.fill_template( "page/index.mako", grid=grid )
+
+
\ No newline at end of file
diff --git a/templates/base_panels.mako b/templates/base_panels.mako
index d0b5b1faf1f..a43254d22c8 100644
--- a/templates/base_panels.mako
+++ b/templates/base_panels.mako
@@ -173,11 +173,18 @@
%endif
%if app.config.get_bool( 'enable_tracks', False ):
-