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 ): - + <% + cls = "tab" + if self.active_view == 'visualization': + cls += " active" + %> + Visualization diff --git a/templates/panels.mako b/templates/panels.mako new file mode 100644 index 00000000000..2ad39149cce --- /dev/null +++ b/templates/panels.mako @@ -0,0 +1,16 @@ +<%inherit file="/base_panels.mako"/> + +<%def name="init()"> +<% + self.has_left_panel=False + self.has_right_panel=False + self.active_view=active_view + self.message_box_visible=False +%> + + +<%def name="center_panel()"> + + + + diff --git a/templates/tracks/browser.mako b/templates/tracks/browser.mako index 113c342c80d..728c644ddd1 100644 --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -124,7 +124,8 @@ ${h.js( "jquery", "jquery.event.drag", "jquery.mousewheel", "lrucache", "trackst - + ## + + - diff --git a/templates/tracks/new_browser.mako b/templates/tracks/new_browser.mako index e3e425cdb9b..9c55b75728f 100644 --- a/templates/tracks/new_browser.mako +++ b/templates/tracks/new_browser.mako @@ -19,10 +19,17 @@ $( function() { % else:
-
Select datasets to include in browser
+
Create new track browser
+
+ +
+ +
+
+