mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge branch 'remove_gridhelper' into remove_gridhelper_001
This commit is contained in:
@@ -39,8 +39,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}admin/users_list`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -49,8 +48,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}admin/roles_list`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -59,8 +57,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}admin/groups_list`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -69,8 +66,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}admin_toolshed/browse_repositories`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -79,8 +75,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}admin/tool_versions_list`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -89,8 +84,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}admin/quotas_list`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -105,8 +99,7 @@ window.app = function app(options, bootstrapped) {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}forms/forms_list`,
|
||||
url_data: Galaxy.params,
|
||||
dict_format: true
|
||||
url_data: Galaxy.params
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@@ -47,6 +47,7 @@ window.app = function app(options, bootstrapped) {
|
||||
"(/)tours(/)(:tour_id)": "show_tours",
|
||||
"(/)user(/)": "show_user",
|
||||
"(/)user(/)(:form_id)": "show_user_form",
|
||||
"(/)openids(/)list": "show_openids",
|
||||
"(/)pages(/)create(/)": "show_pages_create",
|
||||
"(/)pages(/)edit(/)": "show_pages_edit",
|
||||
"(/)pages(/)(:action_id)": "show_pages",
|
||||
@@ -115,8 +116,7 @@ window.app = function app(options, bootstrapped) {
|
||||
show_workflows_published: function() {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}workflow/list_published`,
|
||||
dict_format: true
|
||||
url_base: `${Galaxy.root}workflow/list_published`
|
||||
})
|
||||
);
|
||||
},
|
||||
@@ -157,11 +157,18 @@ window.app = function app(options, bootstrapped) {
|
||||
);
|
||||
},
|
||||
|
||||
show_openids: function() {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}user/openids_list`
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
show_datasets: function() {
|
||||
this.page.display(
|
||||
new GridView({
|
||||
url_base: `${Galaxy.root}dataset/list`,
|
||||
dict_format: true
|
||||
url_base: `${Galaxy.root}dataset/list`
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@@ -332,7 +332,6 @@ WYMeditor.editor.prototype.dialog = function(dialogType, dialogFeatures, bodyHtm
|
||||
|
||||
var grid = new GridView({
|
||||
url_base: item_info.list_ajax_url,
|
||||
dict_format: true,
|
||||
embedded: true
|
||||
});
|
||||
Galaxy.modal.show({
|
||||
@@ -426,7 +425,6 @@ WYMeditor.editor.prototype.dialog = function(dialogType, dialogFeatures, bodyHtm
|
||||
|
||||
var grid = new GridView({
|
||||
url_base: item_info.list_ajax_url,
|
||||
dict_format: true,
|
||||
embedded: true
|
||||
});
|
||||
Galaxy.modal.show({
|
||||
|
||||
@@ -60,7 +60,6 @@ var View = Backbone.View.extend({
|
||||
Utils.get({
|
||||
url: `${Galaxy.root}history/${options.action_id}?${$.param(Galaxy.params)}`,
|
||||
success: function(response) {
|
||||
response.dict_format = true;
|
||||
self.model.set(response);
|
||||
self.render();
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ var Model = Backbone.Model.extend({
|
||||
description: _l("Associate OpenIDs with your account."),
|
||||
icon: "fa-openid",
|
||||
onclick: function() {
|
||||
window.location.href = `${Galaxy.root}user/openid_manage?cntrller=user&use_panels=True`;
|
||||
window.location.href = `${Galaxy.root}openids/list`;
|
||||
}
|
||||
},
|
||||
custom_builds: {
|
||||
|
||||
@@ -10,7 +10,6 @@ var View = Backbone.View.extend({
|
||||
$.ajax({
|
||||
url: `${Galaxy.root + this.item}/${this.model.get("action_id")}?${$.param(Galaxy.params)}`,
|
||||
success: function(response) {
|
||||
response["dict_format"] = true;
|
||||
self.model.set(response);
|
||||
self.render();
|
||||
}
|
||||
|
||||
@@ -459,7 +459,6 @@ var TracksterView = Backbone.View.extend({
|
||||
view_in_saved: function(dataset_params) {
|
||||
var tracks_grid = new GridView({
|
||||
url_base: `${Galaxy.root}visualization/list_tracks`,
|
||||
dict_format: true,
|
||||
embedded: true
|
||||
});
|
||||
Galaxy.modal.show({
|
||||
|
||||
@@ -46,14 +46,12 @@ var select_datasets = (filters, success_fn) => {
|
||||
var history_grid = new GridView({
|
||||
url_base: `${Galaxy.root}visualization/list_history_datasets`,
|
||||
filters: filters,
|
||||
dict_format: true,
|
||||
embedded: true
|
||||
});
|
||||
|
||||
// library dataset selection tab
|
||||
var library_grid = new GridView({
|
||||
url_base: `${Galaxy.root}visualization/list_library_datasets`,
|
||||
dict_format: true,
|
||||
embedded: true
|
||||
});
|
||||
|
||||
|
||||
@@ -1289,21 +1289,6 @@ class UsesFormDefinitionsMixin:
|
||||
else:
|
||||
return [fdc.latest_form for fdc in fdc_list if fdc.latest_form.type == form_type]
|
||||
|
||||
def field_param_values_ok(self, widget_name, widget_type, **kwd):
|
||||
# Make sure required fields have contents, etc
|
||||
params = util.Params(kwd)
|
||||
if widget_type == 'AddressField':
|
||||
if not util.restore_text(params.get('%s_short_desc' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_name' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_institution' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_address' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_city' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_state' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_postal_code' % widget_name, '')) \
|
||||
or not util.restore_text(params.get('%s_country' % widget_name, '')):
|
||||
return False
|
||||
return True
|
||||
|
||||
def save_widget_field(self, trans, field_obj, widget_name, **kwd):
|
||||
# Save a form_builder field object
|
||||
params = util.Params(kwd)
|
||||
|
||||
@@ -10,7 +10,6 @@ from galaxy.model.item_attrs import RuntimeException, UsesAnnotations, UsesItemR
|
||||
from galaxy.util import restore_text, sanitize_text, unicodify
|
||||
from galaxy.util.odict import odict
|
||||
from galaxy.web.framework import decorators, url_for
|
||||
from galaxy.web.framework.helpers import iff
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -21,12 +20,8 @@ class Grid(object):
|
||||
Specifies the content and format of a grid (data table).
|
||||
"""
|
||||
title = ""
|
||||
exposed = True
|
||||
model_class = None
|
||||
show_item_checkboxes = False
|
||||
template = "grid_base.mako"
|
||||
async_template = "grid_base_async.mako"
|
||||
use_async = False
|
||||
use_hide_message = True
|
||||
global_actions = []
|
||||
columns = []
|
||||
@@ -35,14 +30,12 @@ class Grid(object):
|
||||
# Any columns that are filterable (either standard or advanced) should have a default value set in the default filter.
|
||||
default_filter = {}
|
||||
default_sort_key = None
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
num_rows_per_page = 25
|
||||
num_page_links = 10
|
||||
# Set preference names.
|
||||
cur_filter_pref_name = ".filter"
|
||||
cur_sort_key_pref_name = ".sort_key"
|
||||
pass_through_operations = {}
|
||||
legend = None
|
||||
info_text = None
|
||||
|
||||
@@ -65,7 +58,6 @@ class Grid(object):
|
||||
# FIXME: pretty sure this is only here to pass along, can likely be eliminated
|
||||
status = kwargs.get('status', None)
|
||||
message = kwargs.get('message', None)
|
||||
dict_format = kwargs.get('dict_format', False)
|
||||
# Build a base filter and sort key that is the combination of the saved state and defaults.
|
||||
# Saved state takes preference over defaults.
|
||||
base_filter = {}
|
||||
@@ -73,14 +65,6 @@ class Grid(object):
|
||||
# default_filter is a dictionary that provides a default set of filters based on the grid's columns.
|
||||
base_filter = self.default_filter.copy()
|
||||
base_sort_key = self.default_sort_key
|
||||
if self.preserve_state:
|
||||
pref_name = text_type(self.__class__.__name__ + self.cur_filter_pref_name)
|
||||
if pref_name in trans.get_user().preferences:
|
||||
saved_filter = loads(trans.get_user().preferences[pref_name])
|
||||
base_filter.update(saved_filter)
|
||||
pref_name = text_type(self.__class__.__name__ + self.cur_sort_key_pref_name)
|
||||
if pref_name in trans.get_user().preferences:
|
||||
base_sort_key = loads(trans.get_user().preferences[pref_name])
|
||||
# Build initial query
|
||||
query = self.build_initial_query(trans, **kwargs)
|
||||
query = self.apply_query_filter(trans, query, **kwargs)
|
||||
@@ -228,26 +212,11 @@ class Grid(object):
|
||||
# There are some places in grid templates where it's useful for a grid
|
||||
# to have its current filter.
|
||||
self.cur_filter_dict = cur_filter_dict
|
||||
# Preserve grid state: save current filter and sort key.
|
||||
if self.preserve_state:
|
||||
pref_name = text_type(self.__class__.__name__ + self.cur_filter_pref_name)
|
||||
trans.get_user().preferences[pref_name] = text_type(dumps(cur_filter_dict))
|
||||
if sort_key:
|
||||
pref_name = text_type(self.__class__.__name__ + self.cur_sort_key_pref_name)
|
||||
trans.get_user().preferences[pref_name] = text_type(dumps(sort_key))
|
||||
trans.sa_session.flush()
|
||||
|
||||
# Log grid view.
|
||||
context = text_type(self.__class__.__name__)
|
||||
params = cur_filter_dict.copy()
|
||||
params['sort'] = sort_key
|
||||
params['async'] = ('async' in kwargs)
|
||||
|
||||
# TODO:??
|
||||
# commenting this out; when this fn calls session.add( action ) and session.flush the query from this fn
|
||||
# is effectively 'wiped' out. Nate believes it has something to do with our use of session( autocommit=True )
|
||||
# in mapping.py. If you change that to False, the log_action doesn't affect the query
|
||||
# Below, I'm rendering the template first (that uses query), then calling log_action, then returning the page
|
||||
# trans.log_action( trans.get_user(), text_type( "grid.view" ), context, params )
|
||||
|
||||
# Render grid.
|
||||
def url(*args, **kwargs):
|
||||
@@ -280,43 +249,14 @@ class Grid(object):
|
||||
|
||||
self.use_panels = (kwargs.get('use_panels', False) in [True, 'True', 'true'])
|
||||
self.advanced_search = (kwargs.get('advanced_search', False) in [True, 'True', 'true'])
|
||||
async_request = ((self.use_async) and (kwargs.get('async', False) in [True, 'True', 'true']))
|
||||
# Currently, filling the template returns a str object; this requires decoding the string into a
|
||||
# unicode object within mako templates. What probably should be done is to return the template as
|
||||
# utf-8 unicode; however, this would require encoding the object as utf-8 before returning the grid
|
||||
# results via a controller method, which is require substantial changes. Hence, for now, return grid
|
||||
# as str.
|
||||
if not dict_format:
|
||||
page = trans.fill_template(iff(async_request, self.async_template, self.template),
|
||||
grid=self,
|
||||
query=query,
|
||||
cur_page_num=page_num,
|
||||
num_pages=num_pages,
|
||||
num_page_links=self.num_page_links,
|
||||
default_filter_dict=self.default_filter,
|
||||
cur_filter_dict=cur_filter_dict,
|
||||
sort_key=sort_key,
|
||||
current_item=current_item,
|
||||
ids=kwargs.get('id', []),
|
||||
url=url,
|
||||
status=status,
|
||||
message=message,
|
||||
info_text=self.info_text,
|
||||
use_panels=self.use_panels,
|
||||
use_hide_message=self.use_hide_message,
|
||||
advanced_search=self.advanced_search,
|
||||
show_item_checkboxes=(self.show_item_checkboxes or
|
||||
kwargs.get('show_item_checkboxes', '') in ['True', 'true']),
|
||||
# Pass back kwargs so that grid template can set and use args without
|
||||
# grid explicitly having to pass them.
|
||||
kwargs=kwargs)
|
||||
trans.log_action(trans.get_user(), text_type("grid.view"), context, params)
|
||||
return page
|
||||
|
||||
grid_config = {
|
||||
'title' : self.title,
|
||||
'url_base' : trans.request.path_url,
|
||||
'async' : self.use_async,
|
||||
'async_ops' : [],
|
||||
'categorical_filters' : {},
|
||||
'filters' : cur_filter_dict,
|
||||
|
||||
@@ -106,6 +106,7 @@ def app_factory(global_conf, load_app_kwds={}, **kwargs):
|
||||
webapp.add_client_route('/tours/{tour_id}')
|
||||
webapp.add_client_route('/user')
|
||||
webapp.add_client_route('/user/{form_id}')
|
||||
webapp.add_client_route('/openids/list')
|
||||
webapp.add_client_route('/visualizations/list_published')
|
||||
webapp.add_client_route('/visualizations/list')
|
||||
webapp.add_client_route('/visualizations/edit')
|
||||
|
||||
@@ -154,7 +154,6 @@ class UserListGrid(grids.Grid):
|
||||
grids.GridColumnFilter("All", args=dict(deleted='All'))
|
||||
]
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
def get_current_item(self, trans, **kwargs):
|
||||
@@ -255,7 +254,6 @@ class RoleListGrid(grids.Grid):
|
||||
grids.GridColumnFilter("All", args=dict(deleted='All'))
|
||||
]
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
def apply_query_filter(self, trans, query, **kwargs):
|
||||
@@ -335,7 +333,6 @@ class GroupListGrid(grids.Grid):
|
||||
grids.GridColumnFilter("All", args=dict(deleted='All'))
|
||||
]
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
|
||||
@@ -447,7 +444,6 @@ class QuotaListGrid(grids.Grid):
|
||||
grids.GridColumnFilter("All", args=dict(deleted='All'))
|
||||
]
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
|
||||
@@ -499,7 +495,6 @@ class ToolVersionListGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = {}
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
@@ -559,7 +554,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
if message and status:
|
||||
kwd['message'] = util.sanitize_text(message)
|
||||
kwd['status'] = status
|
||||
kwd['dict_format'] = True
|
||||
return self.user_list_grid(trans, **kwd)
|
||||
|
||||
@web.expose_api
|
||||
@@ -592,7 +586,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
if message:
|
||||
kwargs['message'] = util.sanitize_text(message)
|
||||
kwargs['status'] = status or 'done'
|
||||
kwargs['dict_format'] = True
|
||||
return self.quota_list_grid(trans, **kwargs)
|
||||
|
||||
@web.expose_api
|
||||
@@ -902,7 +895,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
@web.expose_api
|
||||
@web.require_admin
|
||||
def tool_versions_list(self, trans, **kwd):
|
||||
kwd['dict_format'] = True
|
||||
return self.tool_version_list_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
@@ -923,7 +915,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
message, status = self._undelete_role(trans, ids)
|
||||
elif operation == 'purge':
|
||||
message, status = self._purge_role(trans, ids)
|
||||
kwargs['dict_format'] = True
|
||||
if message and status:
|
||||
kwargs['message'] = util.sanitize_text(message)
|
||||
kwargs['status'] = status
|
||||
@@ -1168,7 +1159,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
message, status = self._undelete_group(trans, ids)
|
||||
elif operation == 'purge':
|
||||
message, status = self._purge_group(trans, ids)
|
||||
kwargs['dict_format'] = True
|
||||
if message and status:
|
||||
kwargs['message'] = util.sanitize_text(message)
|
||||
kwargs['status'] = status
|
||||
|
||||
@@ -88,7 +88,6 @@ class AdminToolshed(AdminGalaxy):
|
||||
if message and status:
|
||||
kwd['message'] = util.sanitize_text(message)
|
||||
kwd['status'] = 'success' if status in ['ok', 'done', 'success'] else 'error'
|
||||
kwd['dict_format'] = True
|
||||
return self.installed_repository_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
|
||||
@@ -84,8 +84,6 @@ class HistoryDatasetAssociationListGrid(grids.Grid):
|
||||
]
|
||||
standard_filters = []
|
||||
default_filter = dict(name="All", deleted="False", tags="All")
|
||||
preserve_state = False
|
||||
use_async = True
|
||||
use_paging = True
|
||||
num_rows_per_page = 50
|
||||
|
||||
@@ -570,7 +568,6 @@ class DatasetInterface(BaseUIController, UsesAnnotations, UsesItemRatings, UsesE
|
||||
kwargs['refresh_frames'] = ['history']
|
||||
|
||||
# Render the list view
|
||||
kwargs['dict_format'] = True
|
||||
return self.stored_list_grid(trans, status=status, message=message, **kwargs)
|
||||
|
||||
@web.expose
|
||||
|
||||
@@ -39,7 +39,6 @@ class FormsGrid(grids.Grid):
|
||||
model_class = model.FormDefinitionCurrent
|
||||
default_sort_key = "-update_time"
|
||||
num_rows_per_page = 50
|
||||
preserve_state = True
|
||||
use_paging = True
|
||||
default_filter = dict(deleted="False")
|
||||
columns = [
|
||||
@@ -99,7 +98,6 @@ class Forms(BaseUIController):
|
||||
if message and status:
|
||||
kwd['message'] = util.sanitize_text(message)
|
||||
kwd['status'] = status
|
||||
kwd['dict_format'] = True
|
||||
return self.forms_grid(trans, **kwd)
|
||||
|
||||
@web.expose_api
|
||||
|
||||
@@ -130,8 +130,6 @@ class HistoryListGrid(grids.Grid):
|
||||
]
|
||||
default_filter = dict(name="All", deleted="False", tags="All", sharing="All")
|
||||
num_rows_per_page = 15
|
||||
preserve_state = False
|
||||
use_async = True
|
||||
use_paging = True
|
||||
info_text = "Histories that have been deleted for more than a time period specified by the Galaxy administrator(s) may be permanently deleted."
|
||||
|
||||
@@ -194,7 +192,6 @@ class HistoryAllPublishedGrid(grids.Grid):
|
||||
default_filter = dict(public_url="All", username="All", tags="All")
|
||||
use_paging = True
|
||||
num_rows_per_page = 50
|
||||
use_async = True
|
||||
columns = [
|
||||
NameURLColumn("Name", key="name", filterable="advanced"),
|
||||
grids.OwnerAnnotationColumn("Annotation", key="annotation", model_annotation_association_class=model.HistoryAnnotationAssociation, filterable="advanced"),
|
||||
@@ -246,7 +243,6 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt
|
||||
@web.expose
|
||||
@web.json
|
||||
def list_published(self, trans, **kwargs):
|
||||
kwargs['dict_format'] = True
|
||||
return self.published_list_grid(trans, **kwargs)
|
||||
|
||||
@web.expose_api
|
||||
@@ -316,7 +312,6 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt
|
||||
|
||||
trans.sa_session.flush()
|
||||
# Render the list view
|
||||
kwargs['dict_format'] = True
|
||||
if message and status:
|
||||
kwargs['message'] = sanitize_text(message)
|
||||
kwargs['status'] = status
|
||||
@@ -454,7 +449,6 @@ class HistoryController(BaseUIController, SharableMixin, UsesAnnotations, UsesIt
|
||||
message = "Unshared %d shared histories" % len(ids)
|
||||
status = 'done'
|
||||
# Render the list view
|
||||
kwargs['dict_format'] = True
|
||||
return self.shared_list_grid(trans, status=status, message=message, **kwargs)
|
||||
|
||||
@web.expose
|
||||
|
||||
@@ -62,7 +62,6 @@ class PageListGrid(grids.Grid):
|
||||
class PageAllPublishedGrid(grids.Grid):
|
||||
# Grid definition
|
||||
use_panels = True
|
||||
use_async = True
|
||||
title = "Published Pages"
|
||||
model_class = model.Page
|
||||
default_sort_key = "update_time"
|
||||
@@ -104,7 +103,6 @@ class ItemSelectionGrid(grids.Grid):
|
||||
show_item_checkboxes = True
|
||||
default_filter = {"deleted": "False", "sharing": "All"}
|
||||
default_sort_key = "-update_time"
|
||||
use_async = True
|
||||
use_paging = True
|
||||
num_rows_per_page = 10
|
||||
|
||||
@@ -322,7 +320,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
session.flush()
|
||||
|
||||
# Build grid dictionary.
|
||||
kwargs['dict_format'] = True
|
||||
grid = self._page_list(trans, *args, **kwargs)
|
||||
grid['shared_by_others'] = self._get_shared(trans)
|
||||
return grid
|
||||
@@ -330,7 +327,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
@web.expose
|
||||
@web.json
|
||||
def list_published(self, trans, *args, **kwargs):
|
||||
kwargs['dict_format'] = True
|
||||
grid = self._all_published_list(trans, *args, **kwargs)
|
||||
grid['shared_by_others'] = self._get_shared(trans)
|
||||
return grid
|
||||
@@ -700,7 +696,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
@web.require_login("select a history from saved histories")
|
||||
def list_histories_for_selection(self, trans, **kwargs):
|
||||
""" Returns HTML that enables a user to select one or more histories. """
|
||||
kwargs['dict_format'] = True
|
||||
return self._history_selection_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@@ -708,7 +703,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
@web.require_login("select a workflow from saved workflows")
|
||||
def list_workflows_for_selection(self, trans, **kwargs):
|
||||
""" Returns HTML that enables a user to select one or more workflows. """
|
||||
kwargs['dict_format'] = True
|
||||
return self._workflow_selection_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@@ -716,7 +710,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
@web.require_login("select a visualization from saved visualizations")
|
||||
def list_visualizations_for_selection(self, trans, **kwargs):
|
||||
""" Returns HTML that enables a user to select one or more visualizations. """
|
||||
kwargs['dict_format'] = True
|
||||
return self._visualization_selection_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@@ -724,7 +717,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
@web.require_login("select a page from saved pages")
|
||||
def list_pages_for_selection(self, trans, **kwargs):
|
||||
""" Returns HTML that enables a user to select one or more pages. """
|
||||
kwargs['dict_format'] = True
|
||||
return self._page_selection_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@@ -732,7 +724,6 @@ class PageController(BaseUIController, SharableMixin,
|
||||
@web.require_login("select a dataset from saved datasets")
|
||||
def list_datasets_for_selection(self, trans, **kwargs):
|
||||
""" Returns HTML that enables a user to select one or more datasets. """
|
||||
kwargs['dict_format'] = True
|
||||
return self._datasets_selection_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
|
||||
@@ -57,7 +57,7 @@ class RootController(controller.JSAppLauncher, UsesAnnotations):
|
||||
'toolbox' : app.toolbox.to_dict(trans, in_panel=False),
|
||||
'toolbox_in_panel' : app.toolbox.to_dict(trans),
|
||||
'message_box_visible' : app.config.message_box_visible,
|
||||
'show_inactivity_warning' : app.config.user_activation_on and trans.user and not trans.user.active,
|
||||
'show_inactivity_warning' : app.config.user_activation_on and trans.user and not trans.user.active
|
||||
}
|
||||
|
||||
# TODO: move to user
|
||||
|
||||
@@ -62,16 +62,17 @@ can also copy and paste it into your browser.
|
||||
|
||||
|
||||
class UserOpenIDGrid(grids.Grid):
|
||||
use_panels = False
|
||||
title = "OpenIDs linked to your account"
|
||||
model_class = model.UserOpenID
|
||||
template = '/user/openid_manage.mako'
|
||||
default_filter = {"openid": "All"}
|
||||
default_sort_key = "-create_time"
|
||||
columns = [
|
||||
grids.TextColumn("OpenID URL", key="openid", link=(lambda x: dict(action='openid_auth', login_button="Login", openid_url=x.openid if not x.provider else '', openid_provider=x.provider, auto_associate=True))),
|
||||
grids.GridColumn("Created", key="create_time", format=time_ago),
|
||||
]
|
||||
global_actions = [
|
||||
grids.GridAction("Add new account", url_args=dict(action="create_openid"), target="center")
|
||||
]
|
||||
operations = [
|
||||
grids.GridOperation("Delete", async_compatible=True),
|
||||
]
|
||||
@@ -138,8 +139,10 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
return trans.show_error_message('OpenID authentication is not enabled in this instance of Galaxy')
|
||||
auto_associate = util.string_as_bool(kwd.get('auto_associate', False))
|
||||
action = 'login'
|
||||
controller = 'user'
|
||||
if trans.user:
|
||||
action = 'openid_manage'
|
||||
action = 'openids'
|
||||
controller = 'list'
|
||||
if trans.app.config.support_url is not None:
|
||||
contact = '<a href="%s">support</a>' % trans.app.config.support_url
|
||||
else:
|
||||
@@ -153,7 +156,7 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
openid_provider = kwd.get('openid_provider', None)
|
||||
if info.status == trans.app.openid_manager.FAILURE and display_identifier:
|
||||
message = "Login via OpenID failed. The technical reason for this follows, please include this message in your email if you need to %s to resolve this problem: %s" % (contact, info.message)
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
return trans.response.send_redirect(url_for(controller=controller,
|
||||
action=action,
|
||||
use_panels=True,
|
||||
redirect=redirect,
|
||||
@@ -208,8 +211,8 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
message = '%s<br>Click <a href="%s"><strong>here</strong></a> to return to the page you were previously viewing.' % (message, escape(self.__get_redirect_url(redirect)))
|
||||
if redirect and status != "error":
|
||||
return trans.response.send_redirect(self.__get_redirect_url(redirect))
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_manage',
|
||||
return trans.response.send_redirect(url_for(controller='openids',
|
||||
action='list',
|
||||
use_panels=True,
|
||||
redirect=redirect,
|
||||
message=message,
|
||||
@@ -300,18 +303,14 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
for openid in openid_objs:
|
||||
message = '%s<li><a href="%s" target="_blank">%s</a></li>' % (message, url_for(controller='user', action='openid_auth', openid_provider=openid.id, redirect=redirect, auto_associate=True), openid.name)
|
||||
message = "%s</ul>" % (message)
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_manage',
|
||||
use_panels=use_panels,
|
||||
redirect=redirect,
|
||||
return trans.response.send_redirect(url_for(controller='openids',
|
||||
action='list',
|
||||
message=message,
|
||||
status='info'))
|
||||
if redirect:
|
||||
return trans.response.send_redirect(redirect)
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_manage',
|
||||
use_panels=use_panels,
|
||||
redirect=redirect,
|
||||
return trans.response.send_redirect(url_for(controller='openids',
|
||||
action='list',
|
||||
message=message,
|
||||
status='info'))
|
||||
if kwd.get('create_user_button', False):
|
||||
@@ -352,18 +351,14 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
for openid in openid_objs:
|
||||
message = '%s<li><a href="%s" target="_blank">%s</a></li>' % (message, url_for(controller='user', action='openid_auth', openid_provider=openid.id, redirect=redirect, auto_associate=True), openid.name)
|
||||
message = "%s</ul>" % (message)
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_manage',
|
||||
use_panels=True,
|
||||
redirect=redirect,
|
||||
return trans.response.send_redirect(url_for(controller='openids',
|
||||
action='list',
|
||||
message=message,
|
||||
status='info'))
|
||||
if redirect:
|
||||
return trans.response.send_redirect(redirect)
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_manage',
|
||||
use_panels=use_panels,
|
||||
redirect=redirect,
|
||||
return trans.response.send_redirect(url_for(controller='openids',
|
||||
action='list',
|
||||
message=message,
|
||||
status='info'))
|
||||
else:
|
||||
@@ -386,63 +381,53 @@ class User(BaseUIController, UsesFormDefinitionsMixin, CreatesUsersMixin, Create
|
||||
openids=openids)
|
||||
|
||||
@web.expose
|
||||
@web.require_login('manage OpenIDs')
|
||||
def openid_disassociate(self, trans, **kwd):
|
||||
'''Disassociates a user with an OpenID'''
|
||||
if not trans.app.config.enable_openid:
|
||||
return trans.show_error_message('OpenID authentication is not enabled in this instance of Galaxy')
|
||||
params = util.Params(kwd)
|
||||
ids = params.get('id', None)
|
||||
message = params.get('message', None)
|
||||
status = params.get('status', None)
|
||||
use_panels = params.get('use_panels', False)
|
||||
user_openids = []
|
||||
if not ids:
|
||||
message = 'You must select at least one OpenID to disassociate from your Galaxy account.'
|
||||
status = 'error'
|
||||
else:
|
||||
ids = util.listify(params.id)
|
||||
for id in ids:
|
||||
id = trans.security.decode_id(id)
|
||||
user_openid = trans.sa_session.query(trans.app.model.UserOpenID).get(int(id))
|
||||
if not user_openid or (trans.user.id != user_openid.user_id):
|
||||
message = 'The selected OpenID(s) are not associated with your Galaxy account.'
|
||||
status = 'error'
|
||||
user_openids = []
|
||||
break
|
||||
user_openids.append(user_openid)
|
||||
if user_openids:
|
||||
deleted_urls = []
|
||||
for user_openid in user_openids:
|
||||
trans.sa_session.delete(user_openid)
|
||||
deleted_urls.append(user_openid.openid)
|
||||
trans.sa_session.flush()
|
||||
for deleted_url in deleted_urls:
|
||||
trans.log_event("User disassociated OpenID: %s" % deleted_url)
|
||||
message = '%s OpenIDs were disassociated from your Galaxy account.' % len(ids)
|
||||
status = 'done'
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_manage',
|
||||
use_panels=use_panels,
|
||||
message=message,
|
||||
status=status))
|
||||
@web.require_login('create OpenIDs')
|
||||
def create_openid(self, trans, **kwd):
|
||||
return trans.fill_template('/user/openid_manage.mako',
|
||||
openid_providers=trans.app.openid_providers,
|
||||
redirect=kwd.get('redirect', url_for(controller='openids', action='list')).strip())
|
||||
|
||||
@web.expose
|
||||
@web.expose_api
|
||||
@web.require_login('manage OpenIDs')
|
||||
def openid_manage(self, trans, **kwd):
|
||||
'''Manage OpenIDs for user'''
|
||||
def openids_list(self, trans, **kwd):
|
||||
'''List of availabel OpenIDs for user'''
|
||||
message = kwd.get('message', '')
|
||||
status = kwd.get('status', '')
|
||||
if not trans.app.config.enable_openid:
|
||||
return trans.show_error_message('OpenID authentication is not enabled in this instance of Galaxy')
|
||||
use_panels = kwd.get('use_panels', False)
|
||||
message = 'OpenID authentication is not enabled in this instance of Galaxy.'
|
||||
status = 'error'
|
||||
if 'operation' in kwd:
|
||||
operation = kwd['operation'].lower()
|
||||
if operation == "delete":
|
||||
return trans.response.send_redirect(url_for(controller='user',
|
||||
action='openid_disassociate',
|
||||
use_panels=use_panels,
|
||||
id=kwd['id']))
|
||||
kwd['redirect'] = kwd.get('redirect', url_for(controller='user', action='openid_manage', use_panels=True)).strip()
|
||||
kwd['openid_providers'] = trans.app.openid_providers
|
||||
ids = util.listify(kwd.get('id'))
|
||||
if operation == 'delete':
|
||||
if not ids:
|
||||
message = 'You must select at least one OpenID to disassociate from your Galaxy account.'
|
||||
status = 'error'
|
||||
else:
|
||||
user_openids = []
|
||||
for id in ids:
|
||||
id = trans.security.decode_id(id)
|
||||
user_openid = trans.sa_session.query(trans.app.model.UserOpenID).get(int(id))
|
||||
if not user_openid or (trans.user.id != user_openid.user_id):
|
||||
message = 'The selected OpenID(s) are not associated with your Galaxy account.'
|
||||
status = 'error'
|
||||
user_openids = []
|
||||
break
|
||||
user_openids.append(user_openid)
|
||||
if user_openids:
|
||||
deleted_urls = []
|
||||
for user_openid in user_openids:
|
||||
trans.sa_session.delete(user_openid)
|
||||
deleted_urls.append(user_openid.openid)
|
||||
trans.sa_session.flush()
|
||||
for deleted_url in deleted_urls:
|
||||
trans.log_event('User disassociated OpenID: %s' % deleted_url)
|
||||
message = '%s OpenIDs were disassociated from your Galaxy account.' % len(ids)
|
||||
status = 'done'
|
||||
if message and status:
|
||||
kwd['message'] = util.sanitize_text(message)
|
||||
kwd['status'] = status
|
||||
kwd['dict_format'] = True
|
||||
return self.user_openid_grid(trans, **kwd)
|
||||
|
||||
@web.expose
|
||||
|
||||
@@ -118,7 +118,6 @@ class TracksterSelectionGrid(grids.Grid):
|
||||
title = "Insert into visualization"
|
||||
model_class = model.Visualization
|
||||
default_sort_key = "-update_time"
|
||||
use_async = True
|
||||
use_paging = False
|
||||
show_item_checkboxes = True
|
||||
columns = [
|
||||
@@ -193,7 +192,6 @@ class VisualizationListGrid(grids.Grid):
|
||||
class VisualizationAllPublishedGrid(grids.Grid):
|
||||
# Grid definition
|
||||
use_panels = True
|
||||
use_async = True
|
||||
title = "Published Visualizations"
|
||||
model_class = model.Visualization
|
||||
default_sort_key = "update_time"
|
||||
@@ -242,7 +240,6 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
|
||||
@web.require_login("see all available libraries")
|
||||
def list_libraries(self, trans, **kwargs):
|
||||
"""List all libraries that can be used for selecting datasets."""
|
||||
kwargs['dict_format'] = True
|
||||
return self._libraries_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@@ -251,7 +248,6 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
|
||||
def list_history_datasets(self, trans, **kwargs):
|
||||
"""List a history's datasets that can be added to a visualization."""
|
||||
kwargs['show_item_checkboxes'] = 'True'
|
||||
kwargs['dict_format'] = True
|
||||
return self._history_datasets_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@@ -260,19 +256,16 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
|
||||
def list_library_datasets(self, trans, **kwargs):
|
||||
"""List a library's datasets that can be added to a visualization."""
|
||||
kwargs['show_item_checkboxes'] = 'True'
|
||||
kwargs['dict_format'] = True
|
||||
return self._library_datasets_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@web.json
|
||||
def list_tracks(self, trans, **kwargs):
|
||||
kwargs['dict_format'] = True
|
||||
return self._tracks_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
@web.json
|
||||
def list_published(self, trans, *args, **kwargs):
|
||||
kwargs['dict_format'] = True
|
||||
grid = self._published_list_grid(trans, **kwargs)
|
||||
grid['shared_by_others'] = self._get_shared(trans)
|
||||
return grid
|
||||
@@ -294,7 +287,6 @@ class VisualizationController(BaseUIController, SharableMixin, UsesVisualization
|
||||
self.copy(trans, **kwargs)
|
||||
session.flush()
|
||||
kwargs['embedded'] = True
|
||||
kwargs['dict_format'] = True
|
||||
if message and status:
|
||||
kwargs['message'] = sanitize_text(message)
|
||||
kwargs['status'] = status
|
||||
|
||||
@@ -102,7 +102,6 @@ class StoredWorkflowAllPublishedGrid(grids.Grid):
|
||||
model_class = model.StoredWorkflow
|
||||
default_sort_key = "update_time"
|
||||
default_filter = dict(public_url="All", username="All", tags="All")
|
||||
use_async = True
|
||||
columns = [
|
||||
grids.PublicURLColumn("Name", key="name", filterable="advanced", attach_popup=True),
|
||||
grids.OwnerAnnotationColumn("Annotation",
|
||||
@@ -202,7 +201,6 @@ class WorkflowController(BaseUIController, SharableMixin, UsesStoredWorkflowMixi
|
||||
@web.expose
|
||||
@web.json
|
||||
def list_published(self, trans, **kwargs):
|
||||
kwargs['dict_format'] = True
|
||||
return self.published_list_grid(trans, **kwargs)
|
||||
|
||||
@web.expose
|
||||
|
||||
@@ -17,8 +17,8 @@ from sqlalchemy import and_, not_, or_
|
||||
|
||||
from galaxy import model, util
|
||||
from galaxy.web.base.controller import BaseUIController, web
|
||||
from galaxy.web.framework.helpers import grids
|
||||
from galaxy.webapps.reports.controllers.query import ReportQueryBuilder
|
||||
from galaxy.webapps.reports.framework import grids
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -179,7 +179,6 @@ class SpecifiedDateListGrid(grids.Grid):
|
||||
use_async = False
|
||||
model_class = model.Job
|
||||
title = "Jobs"
|
||||
template = '/webapps/reports/grid.mako'
|
||||
default_sort_key = "id"
|
||||
columns = [
|
||||
JobIdColumn("Id",
|
||||
@@ -223,7 +222,6 @@ class SpecifiedDateListGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = {'specified_date': 'All'}
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
|
||||
@@ -18,12 +18,12 @@ from sqlalchemy import and_
|
||||
|
||||
from galaxy import model, util
|
||||
from galaxy.web.base.controller import BaseUIController, web
|
||||
from galaxy.web.framework.helpers import grids
|
||||
from galaxy.webapps.reports.controllers.jobs import (
|
||||
get_spark_time,
|
||||
sorter
|
||||
)
|
||||
from galaxy.webapps.reports.controllers.query import ReportQueryBuilder
|
||||
from galaxy.webapps.reports.framework import grids
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@@ -81,7 +81,6 @@ class SpecifiedDateListGrid(grids.Grid):
|
||||
use_async = False
|
||||
model_class = model.StoredWorkflow
|
||||
title = "Workflows"
|
||||
template = '/webapps/reports/grid.mako'
|
||||
default_sort_key = "name"
|
||||
columns = [
|
||||
WorkflowNameColumn("Name",
|
||||
@@ -113,7 +112,6 @@ class SpecifiedDateListGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = {'specified_date': 'All'}
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = True
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
|
||||
@@ -0,0 +1,854 @@
|
||||
import logging
|
||||
import math
|
||||
from json import dumps, loads
|
||||
|
||||
from markupsafe import escape
|
||||
from six import string_types, text_type
|
||||
from sqlalchemy.sql.expression import and_, false, func, null, or_, true
|
||||
|
||||
from galaxy.model.item_attrs import RuntimeException, UsesAnnotations, UsesItemRatings
|
||||
from galaxy.util import sanitize_text, unicodify
|
||||
from galaxy.util.odict import odict
|
||||
from galaxy.web.framework import decorators, url_for
|
||||
from galaxy.web.framework.helpers import iff
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Grid(object):
|
||||
"""
|
||||
Specifies the content and format of a grid (data table).
|
||||
"""
|
||||
title = ""
|
||||
model_class = None
|
||||
show_item_checkboxes = False
|
||||
template = "webapps/reports/grid_base.mako"
|
||||
async_template = "webapps/reports/grid_base_async.mako"
|
||||
use_async = False
|
||||
use_hide_message = True
|
||||
global_actions = []
|
||||
columns = []
|
||||
operations = []
|
||||
standard_filters = []
|
||||
# Any columns that are filterable (either standard or advanced) should have a default value set in the default filter.
|
||||
default_filter = {}
|
||||
default_sort_key = None
|
||||
use_paging = False
|
||||
num_rows_per_page = 25
|
||||
num_page_links = 10
|
||||
# Set preference names.
|
||||
cur_filter_pref_name = ".filter"
|
||||
cur_sort_key_pref_name = ".sort_key"
|
||||
legend = None
|
||||
info_text = None
|
||||
|
||||
def __init__(self):
|
||||
# Determine if any multiple row operations are defined
|
||||
self.has_multiple_item_operations = False
|
||||
for operation in self.operations:
|
||||
if operation.allow_multiple:
|
||||
self.has_multiple_item_operations = True
|
||||
break
|
||||
|
||||
# If a column does not have a model class, set the column's model class
|
||||
# to be the grid's model class.
|
||||
for column in self.columns:
|
||||
if not column.model_class:
|
||||
column.model_class = self.model_class
|
||||
|
||||
def __call__(self, trans, **kwargs):
|
||||
# Get basics.
|
||||
# FIXME: pretty sure this is only here to pass along, can likely be eliminated
|
||||
status = kwargs.get('status', None)
|
||||
message = kwargs.get('message', None)
|
||||
# Build a base filter and sort key that is the combination of the saved state and defaults.
|
||||
# Saved state takes preference over defaults.
|
||||
base_filter = {}
|
||||
if self.default_filter:
|
||||
# default_filter is a dictionary that provides a default set of filters based on the grid's columns.
|
||||
base_filter = self.default_filter.copy()
|
||||
base_sort_key = self.default_sort_key
|
||||
# Build initial query
|
||||
query = self.build_initial_query(trans, **kwargs)
|
||||
query = self.apply_query_filter(trans, query, **kwargs)
|
||||
# Maintain sort state in generated urls
|
||||
extra_url_args = {}
|
||||
# Determine whether use_default_filter flag is set.
|
||||
use_default_filter_str = kwargs.get('use_default_filter')
|
||||
use_default_filter = False
|
||||
if use_default_filter_str:
|
||||
use_default_filter = (use_default_filter_str.lower() == 'true')
|
||||
# Process filtering arguments to (a) build a query that represents the filter and (b) build a
|
||||
# dictionary that denotes the current filter.
|
||||
cur_filter_dict = {}
|
||||
for column in self.columns:
|
||||
if column.key:
|
||||
# Get the filter criterion for the column. Precedence is (a) if using default filter, only look there; otherwise,
|
||||
# (b) look in kwargs; and (c) look in base filter.
|
||||
column_filter = None
|
||||
if use_default_filter:
|
||||
if self.default_filter:
|
||||
column_filter = self.default_filter.get(column.key)
|
||||
elif "f-" + column.model_class.__name__ + ".%s" % column.key in kwargs:
|
||||
# Queries that include table joins cannot guarantee unique column names. This problem is
|
||||
# handled by setting the column_filter value to <TableName>.<ColumnName>.
|
||||
column_filter = kwargs.get("f-" + column.model_class.__name__ + ".%s" % column.key)
|
||||
elif "f-" + column.key in kwargs:
|
||||
column_filter = kwargs.get("f-" + column.key)
|
||||
elif column.key in base_filter:
|
||||
column_filter = base_filter.get(column.key)
|
||||
|
||||
# Method (1) combines a mix of strings and lists of strings into a single string and (2) attempts to de-jsonify all strings.
|
||||
def loads_recurse(item):
|
||||
decoded_list = []
|
||||
if isinstance(item, string_types):
|
||||
try:
|
||||
# Not clear what we're decoding, so recurse to ensure that we catch everything.
|
||||
decoded_item = loads(item)
|
||||
if isinstance(decoded_item, list):
|
||||
decoded_list = loads_recurse(decoded_item)
|
||||
else:
|
||||
decoded_list = [text_type(decoded_item)]
|
||||
except ValueError:
|
||||
decoded_list = [text_type(item)]
|
||||
elif isinstance(item, list):
|
||||
for element in item:
|
||||
a_list = loads_recurse(element)
|
||||
decoded_list = decoded_list + a_list
|
||||
return decoded_list
|
||||
# If column filter found, apply it.
|
||||
if column_filter is not None:
|
||||
# TextColumns may have a mix of json and strings.
|
||||
if isinstance(column, TextColumn):
|
||||
column_filter = loads_recurse(column_filter)
|
||||
if len(column_filter) == 1:
|
||||
column_filter = column_filter[0]
|
||||
# Interpret ',' as a separator for multiple terms.
|
||||
if isinstance(column_filter, string_types) and column_filter.find(',') != -1:
|
||||
column_filter = column_filter.split(',')
|
||||
|
||||
# Check if filter is empty
|
||||
if isinstance(column_filter, list):
|
||||
# Remove empty strings from filter list
|
||||
column_filter = [x for x in column_filter if x != '']
|
||||
if len(column_filter) == 0:
|
||||
continue
|
||||
elif isinstance(column_filter, string_types):
|
||||
# If filter criterion is empty, do nothing.
|
||||
if column_filter == '':
|
||||
continue
|
||||
|
||||
# Update query.
|
||||
query = column.filter(trans, trans.user, query, column_filter)
|
||||
# Upate current filter dict.
|
||||
# Column filters are rendered in various places, sanitize them all here.
|
||||
cur_filter_dict[column.key] = sanitize_text(column_filter)
|
||||
# Carry filter along to newly generated urls; make sure filter is a string so
|
||||
# that we can encode to UTF-8 and thus handle user input to filters.
|
||||
if isinstance(column_filter, list):
|
||||
# Filter is a list; process each item.
|
||||
column_filter = [text_type(_).encode('utf-8') if not isinstance(_, string_types) else _ for _ in column_filter]
|
||||
extra_url_args["f-" + column.key] = dumps(column_filter)
|
||||
else:
|
||||
# Process singleton filter.
|
||||
if not isinstance(column_filter, string_types):
|
||||
column_filter = text_type(column_filter)
|
||||
extra_url_args["f-" + column.key] = column_filter.encode("utf-8")
|
||||
# Process sort arguments.
|
||||
sort_key = None
|
||||
if 'sort' in kwargs:
|
||||
sort_key = kwargs['sort']
|
||||
elif base_sort_key:
|
||||
sort_key = base_sort_key
|
||||
if sort_key:
|
||||
ascending = not(sort_key.startswith("-"))
|
||||
# Queries that include table joins cannot guarantee unique column names. This problem is
|
||||
# handled by setting the column_filter value to <TableName>.<ColumnName>.
|
||||
table_name = None
|
||||
if sort_key.find('.') > -1:
|
||||
a_list = sort_key.split('.')
|
||||
if ascending:
|
||||
table_name = a_list[0]
|
||||
else:
|
||||
table_name = a_list[0][1:]
|
||||
column_name = a_list[1]
|
||||
elif ascending:
|
||||
column_name = sort_key
|
||||
else:
|
||||
column_name = sort_key[1:]
|
||||
# Sort key is a column key.
|
||||
for column in self.columns:
|
||||
if column.key and column.key.find('.') > -1:
|
||||
column_key = column.key.split('.')[1]
|
||||
else:
|
||||
column_key = column.key
|
||||
if (table_name is None or table_name == column.model_class.__name__) and column_key == column_name:
|
||||
query = column.sort(trans, query, ascending, column_name=column_name)
|
||||
break
|
||||
extra_url_args['sort'] = sort_key
|
||||
# There might be a current row
|
||||
current_item = self.get_current_item(trans, **kwargs)
|
||||
# Process page number.
|
||||
if self.use_paging:
|
||||
if 'page' in kwargs:
|
||||
if kwargs['page'] == 'all':
|
||||
page_num = 0
|
||||
else:
|
||||
page_num = int(kwargs['page'])
|
||||
else:
|
||||
page_num = 1
|
||||
if page_num == 0:
|
||||
# Show all rows in page.
|
||||
total_num_rows = query.count()
|
||||
page_num = 1
|
||||
num_pages = 1
|
||||
else:
|
||||
# Show a limited number of rows. Before modifying query, get the total number of rows that query
|
||||
# returns so that the total number of pages can be computed.
|
||||
total_num_rows = query.count()
|
||||
query = query.limit(self.num_rows_per_page).offset((page_num - 1) * self.num_rows_per_page)
|
||||
num_pages = int(math.ceil(float(total_num_rows) / self.num_rows_per_page))
|
||||
else:
|
||||
# Defaults.
|
||||
page_num = 1
|
||||
num_pages = 1
|
||||
# There are some places in grid templates where it's useful for a grid
|
||||
# to have its current filter.
|
||||
self.cur_filter_dict = cur_filter_dict
|
||||
|
||||
# Log grid view.
|
||||
context = text_type(self.__class__.__name__)
|
||||
params = cur_filter_dict.copy()
|
||||
params['sort'] = sort_key
|
||||
params['async'] = ('async' in kwargs)
|
||||
|
||||
# TODO:??
|
||||
# commenting this out; when this fn calls session.add( action ) and session.flush the query from this fn
|
||||
# is effectively 'wiped' out. Nate believes it has something to do with our use of session( autocommit=True )
|
||||
# in mapping.py. If you change that to False, the log_action doesn't affect the query
|
||||
# Below, I'm rendering the template first (that uses query), then calling log_action, then returning the page
|
||||
# trans.log_action( trans.get_user(), text_type( "grid.view" ), context, params )
|
||||
|
||||
# Render grid.
|
||||
def url(*args, **kwargs):
|
||||
route_name = kwargs.pop('__route_name__', None)
|
||||
# Only include sort/filter arguments if not linking to another
|
||||
# page. This is a bit of a hack.
|
||||
if 'action' in kwargs:
|
||||
new_kwargs = dict()
|
||||
else:
|
||||
new_kwargs = dict(extra_url_args)
|
||||
# Extend new_kwargs with first argument if found
|
||||
if len(args) > 0:
|
||||
new_kwargs.update(args[0])
|
||||
new_kwargs.update(kwargs)
|
||||
# We need to encode item ids
|
||||
if 'id' in new_kwargs:
|
||||
id = new_kwargs['id']
|
||||
if isinstance(id, list):
|
||||
new_kwargs['id'] = [trans.security.encode_id(i) for i in id]
|
||||
else:
|
||||
new_kwargs['id'] = trans.security.encode_id(id)
|
||||
# The url_for invocation *must* include a controller and action.
|
||||
if 'controller' not in new_kwargs:
|
||||
new_kwargs['controller'] = trans.controller
|
||||
if 'action' not in new_kwargs:
|
||||
new_kwargs['action'] = trans.action
|
||||
if route_name:
|
||||
return url_for(route_name, **new_kwargs)
|
||||
return url_for(**new_kwargs)
|
||||
|
||||
self.use_panels = (kwargs.get('use_panels', False) in [True, 'True', 'true'])
|
||||
self.advanced_search = (kwargs.get('advanced_search', False) in [True, 'True', 'true'])
|
||||
async_request = ((self.use_async) and (kwargs.get('async', False) in [True, 'True', 'true']))
|
||||
# Currently, filling the template returns a str object; this requires decoding the string into a
|
||||
# unicode object within mako templates. What probably should be done is to return the template as
|
||||
# utf-8 unicode; however, this would require encoding the object as utf-8 before returning the grid
|
||||
# results via a controller method, which is require substantial changes. Hence, for now, return grid
|
||||
# as str.
|
||||
page = trans.fill_template(iff(async_request, self.async_template, self.template),
|
||||
grid=self,
|
||||
query=query,
|
||||
cur_page_num=page_num,
|
||||
num_pages=num_pages,
|
||||
num_page_links=self.num_page_links,
|
||||
default_filter_dict=self.default_filter,
|
||||
cur_filter_dict=cur_filter_dict,
|
||||
sort_key=sort_key,
|
||||
current_item=current_item,
|
||||
ids=kwargs.get('id', []),
|
||||
url=url,
|
||||
status=status,
|
||||
message=message,
|
||||
info_text=self.info_text,
|
||||
use_panels=self.use_panels,
|
||||
use_hide_message=self.use_hide_message,
|
||||
advanced_search=self.advanced_search,
|
||||
show_item_checkboxes=(self.show_item_checkboxes or
|
||||
kwargs.get('show_item_checkboxes', '') in ['True', 'true']),
|
||||
# Pass back kwargs so that grid template can set and use args without
|
||||
# grid explicitly having to pass them.
|
||||
kwargs=kwargs)
|
||||
trans.log_action(trans.get_user(), text_type("grid.view"), context, params)
|
||||
return page
|
||||
|
||||
def get_ids(self, **kwargs):
|
||||
id = []
|
||||
if 'id' in kwargs:
|
||||
id = kwargs['id']
|
||||
# Coerce ids to list
|
||||
if not isinstance(id, list):
|
||||
id = id.split(",")
|
||||
# Ensure ids are integers
|
||||
try:
|
||||
id = list(map(int, id))
|
||||
except Exception:
|
||||
decorators.error("Invalid id")
|
||||
return id
|
||||
|
||||
# ---- Override these ----------------------------------------------------
|
||||
def handle_operation(self, trans, operation, ids, **kwargs):
|
||||
pass
|
||||
|
||||
def get_current_item(self, trans, **kwargs):
|
||||
return None
|
||||
|
||||
def build_initial_query(self, trans, **kwargs):
|
||||
return trans.sa_session.query(self.model_class)
|
||||
|
||||
def apply_query_filter(self, trans, query, **kwargs):
|
||||
# Applies a database filter that holds for all items in the grid.
|
||||
# (gvk) Is this method necessary? Why not simply build the entire query,
|
||||
# including applying filters in the build_initial_query() method?
|
||||
return query
|
||||
|
||||
|
||||
class GridColumn(object):
|
||||
def __init__(self, label, key=None, model_class=None, method=None, format=None,
|
||||
link=None, attach_popup=False, visible=True, nowrap=False,
|
||||
# Valid values for filterable are ['standard', 'advanced', None]
|
||||
filterable=None, sortable=True, label_id_prefix=None, target=None):
|
||||
"""Create a grid column."""
|
||||
self.label = label
|
||||
self.key = key
|
||||
self.model_class = model_class
|
||||
self.method = method
|
||||
self.format = format
|
||||
self.link = link
|
||||
self.target = target
|
||||
self.nowrap = nowrap
|
||||
self.attach_popup = attach_popup
|
||||
self.visible = visible
|
||||
self.filterable = filterable
|
||||
# Column must have a key to be sortable.
|
||||
self.sortable = (self.key is not None and sortable)
|
||||
self.label_id_prefix = label_id_prefix or ''
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
if self.method:
|
||||
value = getattr(grid, self.method)(trans, item)
|
||||
elif self.key:
|
||||
value = getattr(item, self.key)
|
||||
else:
|
||||
value = None
|
||||
if self.format:
|
||||
value = self.format(value)
|
||||
return escape(unicodify(value))
|
||||
|
||||
def get_link(self, trans, grid, item):
|
||||
if self.link and self.link(item):
|
||||
return self.link(item)
|
||||
return None
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
""" Modify query to reflect the column filter. """
|
||||
if column_filter == "All":
|
||||
pass
|
||||
if column_filter == "True":
|
||||
query = query.filter_by(**{self.key: True})
|
||||
elif column_filter == "False":
|
||||
query = query.filter_by(**{self.key: False})
|
||||
return query
|
||||
|
||||
def get_accepted_filters(self):
|
||||
""" Returns a list of accepted filters for this column. """
|
||||
accepted_filters_vals = ["False", "True", "All"]
|
||||
accepted_filters = []
|
||||
for val in accepted_filters_vals:
|
||||
args = {self.key: val}
|
||||
accepted_filters.append(GridColumnFilter(val, args))
|
||||
return accepted_filters
|
||||
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
"""Sort query using this column."""
|
||||
if column_name is None:
|
||||
column_name = self.key
|
||||
if ascending:
|
||||
query = query.order_by(self.model_class.table.c.get(column_name).asc())
|
||||
else:
|
||||
query = query.order_by(self.model_class.table.c.get(column_name).desc())
|
||||
return query
|
||||
|
||||
|
||||
class ReverseSortColumn(GridColumn):
|
||||
""" Column that reverses sorting; this is useful when the natural sort is descending. """
|
||||
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
return GridColumn.sort(self, trans, query, (not ascending), column_name=column_name)
|
||||
|
||||
|
||||
class TextColumn(GridColumn):
|
||||
""" Generic column that employs freetext and, hence, supports freetext, case-independent filtering. """
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
""" Modify query to filter using free text, case independence. """
|
||||
if column_filter == "All":
|
||||
pass
|
||||
elif column_filter:
|
||||
query = query.filter(self.get_filter(trans, user, column_filter))
|
||||
return query
|
||||
|
||||
def get_filter(self, trans, user, column_filter):
|
||||
""" Returns a SQLAlchemy criterion derived from column_filter. """
|
||||
if isinstance(column_filter, string_types):
|
||||
return self.get_single_filter(user, column_filter)
|
||||
elif isinstance(column_filter, list):
|
||||
clause_list = []
|
||||
for filter in column_filter:
|
||||
clause_list.append(self.get_single_filter(user, filter))
|
||||
return and_(*clause_list)
|
||||
|
||||
def get_single_filter(self, user, a_filter):
|
||||
"""
|
||||
Returns a SQLAlchemy criterion derived for a single filter. Single filter
|
||||
is the most basic filter--usually a string--and cannot be a list.
|
||||
"""
|
||||
# Queries that include table joins cannot guarantee that table column names will be
|
||||
# unique, so check to see if a_filter is of type <TableName>.<ColumnName>.
|
||||
if self.key.find('.') > -1:
|
||||
a_key = self.key.split('.')[1]
|
||||
else:
|
||||
a_key = self.key
|
||||
model_class_key_field = getattr(self.model_class, a_key)
|
||||
return func.lower(model_class_key_field).like("%" + a_filter.lower() + "%")
|
||||
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
"""Sort column using case-insensitive alphabetical sorting."""
|
||||
if column_name is None:
|
||||
column_name = self.key
|
||||
if ascending:
|
||||
query = query.order_by(func.lower(self.model_class.table.c.get(column_name)).asc())
|
||||
else:
|
||||
query = query.order_by(func.lower(self.model_class.table.c.get(column_name)).desc())
|
||||
return query
|
||||
|
||||
|
||||
class DateTimeColumn(TextColumn):
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
"""Sort query using this column."""
|
||||
return GridColumn.sort(self, trans, query, ascending, column_name=column_name)
|
||||
|
||||
|
||||
class BooleanColumn(TextColumn):
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
"""Sort query using this column."""
|
||||
return GridColumn.sort(self, trans, query, ascending, column_name=column_name)
|
||||
|
||||
def get_single_filter(self, user, a_filter):
|
||||
if self.key.find('.') > -1:
|
||||
a_key = self.key.split('.')[1]
|
||||
else:
|
||||
a_key = self.key
|
||||
model_class_key_field = getattr(self.model_class, a_key)
|
||||
return model_class_key_field == a_filter
|
||||
|
||||
|
||||
class IntegerColumn(TextColumn):
|
||||
"""
|
||||
Integer column that employs freetext, but checks that the text is an integer,
|
||||
so support filtering on integer values.
|
||||
|
||||
IMPORTANT NOTE: grids that use this column type should not include the column
|
||||
in the cols_to_filter list of MulticolFilterColumn ( i.e., searching on this
|
||||
column type should not be performed in the grid's standard search - it won't
|
||||
throw exceptions, but it also will not find what you're looking for ). Grids
|
||||
that search on this column should use 'filterable="advanced"' so that searching
|
||||
is only performed in the advanced search component, restricting the search to
|
||||
the specific column.
|
||||
|
||||
This is useful for searching on object ids or other integer columns. See the
|
||||
JobIdColumn column in the SpecifiedDateListGrid class in the jobs controller of
|
||||
the reports webapp for an example.
|
||||
"""
|
||||
|
||||
def get_single_filter(self, user, a_filter):
|
||||
model_class_key_field = getattr(self.model_class, self.key)
|
||||
assert int(a_filter), "The search entry must be an integer"
|
||||
return model_class_key_field == int(a_filter)
|
||||
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
"""Sort query using this column."""
|
||||
return GridColumn.sort(self, trans, query, ascending, column_name=column_name)
|
||||
|
||||
|
||||
class CommunityRatingColumn(GridColumn, UsesItemRatings):
|
||||
""" Column that displays community ratings for an item. """
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
ave_item_rating, num_ratings = self.get_ave_item_rating_data(trans.sa_session, item, webapp_model=trans.model)
|
||||
return trans.fill_template("tool_shed_rating.mako",
|
||||
ave_item_rating=ave_item_rating,
|
||||
num_ratings=num_ratings,
|
||||
item_id=trans.security.encode_id(item.id))
|
||||
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
def get_foreign_key(source_class, target_class):
|
||||
""" Returns foreign key in source class that references target class. """
|
||||
target_fk = None
|
||||
for fk in source_class.table.foreign_keys:
|
||||
if fk.references(target_class.table):
|
||||
target_fk = fk
|
||||
break
|
||||
if not target_fk:
|
||||
raise RuntimeException("No foreign key found between objects: %s, %s" % source_class.table, target_class.table)
|
||||
return target_fk
|
||||
# Get the columns that connect item's table and item's rating association table.
|
||||
item_rating_assoc_class = getattr(trans.model, '%sRatingAssociation' % self.model_class.__name__)
|
||||
foreign_key = get_foreign_key(item_rating_assoc_class, self.model_class)
|
||||
fk_col = foreign_key.parent
|
||||
referent_col = foreign_key.get_referent(self.model_class.table)
|
||||
# Do sorting using a subquery.
|
||||
# Subquery to get average rating for each item.
|
||||
ave_rating_subquery = trans.sa_session.query(fk_col,
|
||||
func.avg(item_rating_assoc_class.table.c.rating).label('avg_rating')) \
|
||||
.group_by(fk_col).subquery()
|
||||
# Integrate subquery into main query.
|
||||
query = query.outerjoin((ave_rating_subquery, referent_col == ave_rating_subquery.columns[fk_col.name]))
|
||||
# Sort using subquery results; use coalesce to avoid null values.
|
||||
if not ascending: # TODO: for now, reverse sorting b/c first sort is ascending, and that should be the natural sort.
|
||||
query = query.order_by(func.coalesce(ave_rating_subquery.c.avg_rating, 0).asc())
|
||||
else:
|
||||
query = query.order_by(func.coalesce(ave_rating_subquery.c.avg_rating, 0).desc())
|
||||
return query
|
||||
|
||||
|
||||
class OwnerAnnotationColumn(TextColumn, UsesAnnotations):
|
||||
""" Column that displays and filters item owner's annotations. """
|
||||
|
||||
def __init__(self, col_name, key, model_class=None, model_annotation_association_class=None, filterable=None):
|
||||
GridColumn.__init__(self, col_name, key=key, model_class=model_class, filterable=filterable)
|
||||
self.sortable = False
|
||||
self.model_annotation_association_class = model_annotation_association_class
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
""" Returns first 150 characters of annotation. """
|
||||
annotation = self.get_item_annotation_str(trans.sa_session, item.user, item)
|
||||
if annotation:
|
||||
ann_snippet = annotation[:155]
|
||||
if len(annotation) > 155:
|
||||
ann_snippet = ann_snippet[:ann_snippet.rfind(' ')]
|
||||
ann_snippet += "..."
|
||||
else:
|
||||
ann_snippet = ""
|
||||
return escape(ann_snippet)
|
||||
|
||||
def get_single_filter(self, user, a_filter):
|
||||
""" Filter by annotation and annotation owner. """
|
||||
return self.model_class.annotations.any(
|
||||
and_(func.lower(self.model_annotation_association_class.annotation).like("%" + a_filter.lower() + "%"),
|
||||
# TODO: not sure why, to filter by owner's annotations, we have to do this rather than
|
||||
# 'self.model_class.user==self.model_annotation_association_class.user'
|
||||
self.model_annotation_association_class.table.c.user_id == self.model_class.table.c.user_id))
|
||||
|
||||
|
||||
class CommunityTagsColumn(TextColumn):
|
||||
""" Column that supports community tags. """
|
||||
|
||||
def __init__(self, col_name, key, model_class=None, model_tag_association_class=None, filterable=None, grid_name=None):
|
||||
GridColumn.__init__(self, col_name, key=key, model_class=model_class, nowrap=True, filterable=filterable, sortable=False)
|
||||
self.model_tag_association_class = model_tag_association_class
|
||||
# Column-specific attributes.
|
||||
self.grid_name = grid_name
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
return trans.fill_template("/tagging_common.mako", tag_type="community", trans=trans, user=trans.get_user(), tagged_item=item, elt_context=self.grid_name,
|
||||
in_form=True, input_size="20", tag_click_fn="add_tag_to_grid_filter", use_toggle_link=True)
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
""" Modify query to filter model_class by tag. Multiple filters are ANDed. """
|
||||
if column_filter == "All":
|
||||
pass
|
||||
elif column_filter:
|
||||
query = query.filter(self.get_filter(trans, user, column_filter))
|
||||
return query
|
||||
|
||||
def get_filter(self, trans, user, column_filter):
|
||||
# Parse filter to extract multiple tags.
|
||||
if isinstance(column_filter, list):
|
||||
# Collapse list of tags into a single string; this is redundant but effective. TODO: fix this by iterating over tags.
|
||||
column_filter = ",".join(column_filter)
|
||||
raw_tags = trans.app.tag_handler.parse_tags(column_filter.encode("utf-8"))
|
||||
clause_list = []
|
||||
for name, value in raw_tags:
|
||||
if name:
|
||||
# Filter by all tags.
|
||||
clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_tname).like("%" + name.lower() + "%")))
|
||||
if value:
|
||||
# Filter by all values.
|
||||
clause_list.append(self.model_class.tags.any(func.lower(self.model_tag_association_class.user_value).like("%" + value.lower() + "%")))
|
||||
return and_(*clause_list)
|
||||
|
||||
|
||||
class IndividualTagsColumn(CommunityTagsColumn):
|
||||
""" Column that supports individual tags. """
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
return trans.fill_template("/tagging_common.mako",
|
||||
tag_type="individual",
|
||||
user=trans.user,
|
||||
tagged_item=item,
|
||||
elt_context=self.grid_name,
|
||||
in_form=True,
|
||||
input_size="20",
|
||||
tag_click_fn="add_tag_to_grid_filter",
|
||||
use_toggle_link=True)
|
||||
|
||||
def get_filter(self, trans, user, column_filter):
|
||||
# Parse filter to extract multiple tags.
|
||||
if isinstance(column_filter, list):
|
||||
# Collapse list of tags into a single string; this is redundant but effective. TODO: fix this by iterating over tags.
|
||||
column_filter = ",".join(column_filter)
|
||||
raw_tags = trans.app.tag_handler.parse_tags(column_filter.encode("utf-8"))
|
||||
clause_list = []
|
||||
for name, value in raw_tags:
|
||||
if name:
|
||||
# Filter by individual's tag names.
|
||||
clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_tname).like("%" + name.lower() + "%"), self.model_tag_association_class.user == user)))
|
||||
if value:
|
||||
# Filter by individual's tag values.
|
||||
clause_list.append(self.model_class.tags.any(and_(func.lower(self.model_tag_association_class.user_value).like("%" + value.lower() + "%"), self.model_tag_association_class.user == user)))
|
||||
return and_(*clause_list)
|
||||
|
||||
|
||||
class MulticolFilterColumn(TextColumn):
|
||||
""" Column that performs multicolumn filtering. """
|
||||
|
||||
def __init__(self, col_name, cols_to_filter, key, visible, filterable="default"):
|
||||
GridColumn.__init__(self, col_name, key=key, visible=visible, filterable=filterable)
|
||||
self.cols_to_filter = cols_to_filter
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
""" Modify query to filter model_class by tag. Multiple filters are ANDed. """
|
||||
if column_filter == "All":
|
||||
return query
|
||||
if isinstance(column_filter, list):
|
||||
clause_list = []
|
||||
for filter in column_filter:
|
||||
part_clause_list = []
|
||||
for column in self.cols_to_filter:
|
||||
part_clause_list.append(column.get_filter(trans, user, filter))
|
||||
clause_list.append(or_(*part_clause_list))
|
||||
complete_filter = and_(*clause_list)
|
||||
else:
|
||||
clause_list = []
|
||||
for column in self.cols_to_filter:
|
||||
clause_list.append(column.get_filter(trans, user, column_filter))
|
||||
complete_filter = or_(*clause_list)
|
||||
return query.filter(complete_filter)
|
||||
|
||||
|
||||
class OwnerColumn(TextColumn):
|
||||
""" Column that lists item's owner. """
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
return item.user.username
|
||||
|
||||
def sort(self, trans, query, ascending, column_name=None):
|
||||
""" Sort column using case-insensitive alphabetical sorting on item's username. """
|
||||
if ascending:
|
||||
query = query.order_by(func.lower(self.model_class.username).asc())
|
||||
else:
|
||||
query = query.order_by(func.lower(self.model_class.username).desc())
|
||||
return query
|
||||
|
||||
|
||||
class PublicURLColumn(TextColumn):
|
||||
""" Column displays item's public URL based on username and slug. """
|
||||
|
||||
def get_link(self, trans, grid, item):
|
||||
if item.user.username and item.slug:
|
||||
return dict(action='display_by_username_and_slug', username=item.user.username, slug=item.slug)
|
||||
elif not item.user.username:
|
||||
# TODO: provide link to set username.
|
||||
return None
|
||||
elif not item.user.slug:
|
||||
# TODO: provide link to set slug.
|
||||
return None
|
||||
|
||||
|
||||
class DeletedColumn(GridColumn):
|
||||
""" Column that tracks and filters for items with deleted attribute. """
|
||||
|
||||
def get_accepted_filters(self):
|
||||
""" Returns a list of accepted filters for this column. """
|
||||
accepted_filter_labels_and_vals = {"active" : "False", "deleted" : "True", "all": "All"}
|
||||
accepted_filters = []
|
||||
for label, val in accepted_filter_labels_and_vals.items():
|
||||
args = {self.key: val}
|
||||
accepted_filters.append(GridColumnFilter(label, args))
|
||||
return accepted_filters
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
"""Modify query to filter self.model_class by state."""
|
||||
if column_filter == "All":
|
||||
pass
|
||||
elif column_filter in ["True", "False"]:
|
||||
query = query.filter(self.model_class.deleted == (column_filter == "True"))
|
||||
return query
|
||||
|
||||
|
||||
class StateColumn(GridColumn):
|
||||
"""
|
||||
Column that tracks and filters for items with state attribute.
|
||||
|
||||
IMPORTANT NOTE: self.model_class must have a states Bunch or dict if
|
||||
this column type is used in the grid.
|
||||
"""
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
return item.state
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
"""Modify query to filter self.model_class by state."""
|
||||
if column_filter == "All":
|
||||
pass
|
||||
elif column_filter in [v for k, v in self.model_class.states.items()]:
|
||||
query = query.filter(self.model_class.state == column_filter)
|
||||
return query
|
||||
|
||||
def get_accepted_filters(self):
|
||||
"""Returns a list of accepted filters for this column."""
|
||||
all = GridColumnFilter('all', {self.key : 'All'})
|
||||
accepted_filters = [all]
|
||||
for k, v in self.model_class.states.items():
|
||||
args = {self.key: v}
|
||||
accepted_filters.append(GridColumnFilter(v, args))
|
||||
return accepted_filters
|
||||
|
||||
|
||||
class SharingStatusColumn(GridColumn):
|
||||
""" Grid column to indicate sharing status. """
|
||||
|
||||
def get_value(self, trans, grid, item):
|
||||
# Delete items cannot be shared.
|
||||
if item.deleted:
|
||||
return ""
|
||||
# Build a list of sharing for this item.
|
||||
sharing_statuses = []
|
||||
if item.users_shared_with:
|
||||
sharing_statuses.append("Shared")
|
||||
if item.importable:
|
||||
sharing_statuses.append("Accessible")
|
||||
if item.published:
|
||||
sharing_statuses.append("Published")
|
||||
return ", ".join(sharing_statuses)
|
||||
|
||||
def get_link(self, trans, grid, item):
|
||||
if not item.deleted and (item.users_shared_with or item.importable or item.published):
|
||||
return dict(operation="share or publish", id=item.id)
|
||||
return None
|
||||
|
||||
def filter(self, trans, user, query, column_filter):
|
||||
""" Modify query to filter histories by sharing status. """
|
||||
if column_filter == "All":
|
||||
pass
|
||||
elif column_filter:
|
||||
if column_filter == "private":
|
||||
query = query.filter(self.model_class.users_shared_with == null())
|
||||
query = query.filter(self.model_class.importable == false())
|
||||
elif column_filter == "shared":
|
||||
query = query.filter(self.model_class.users_shared_with != null())
|
||||
elif column_filter == "accessible":
|
||||
query = query.filter(self.model_class.importable == true())
|
||||
elif column_filter == "published":
|
||||
query = query.filter(self.model_class.published == true())
|
||||
return query
|
||||
|
||||
def get_accepted_filters(self):
|
||||
""" Returns a list of accepted filters for this column. """
|
||||
accepted_filter_labels_and_vals = odict()
|
||||
accepted_filter_labels_and_vals["private"] = "private"
|
||||
accepted_filter_labels_and_vals["shared"] = "shared"
|
||||
accepted_filter_labels_and_vals["accessible"] = "accessible"
|
||||
accepted_filter_labels_and_vals["published"] = "published"
|
||||
accepted_filter_labels_and_vals["all"] = "All"
|
||||
accepted_filters = []
|
||||
for label, val in accepted_filter_labels_and_vals.items():
|
||||
args = {self.key: val}
|
||||
accepted_filters.append(GridColumnFilter(label, args))
|
||||
return accepted_filters
|
||||
|
||||
|
||||
class GridOperation(object):
|
||||
def __init__(self, label, key=None, condition=None, allow_multiple=True, allow_popup=True,
|
||||
target=None, url_args=None, async_compatible=False, confirm=None,
|
||||
global_operation=None):
|
||||
self.label = label
|
||||
self.key = key
|
||||
self.allow_multiple = allow_multiple
|
||||
self.allow_popup = allow_popup
|
||||
self.condition = condition
|
||||
self.target = target
|
||||
self.url_args = url_args
|
||||
self.async_compatible = async_compatible
|
||||
# if 'confirm' is set, then ask before completing the operation
|
||||
self.confirm = confirm
|
||||
# specify a general operation that acts on the full grid
|
||||
# this should be a function returning a dictionary with parameters
|
||||
# to pass to the URL, similar to GridColumn links:
|
||||
# global_operation=(lambda: dict(operation="download")
|
||||
self.global_operation = global_operation
|
||||
|
||||
def get_url_args(self, item):
|
||||
if self.url_args:
|
||||
if hasattr(self.url_args, '__call__'):
|
||||
url_args = self.url_args(item)
|
||||
else:
|
||||
url_args = dict(self.url_args)
|
||||
url_args['id'] = item.id
|
||||
return url_args
|
||||
else:
|
||||
return dict(operation=self.label, id=item.id)
|
||||
|
||||
def allowed(self, item):
|
||||
if self.condition:
|
||||
return bool(self.condition(item))
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
class DisplayByUsernameAndSlugGridOperation(GridOperation):
|
||||
""" Operation to display an item by username and slug. """
|
||||
|
||||
def get_url_args(self, item):
|
||||
return {'action' : 'display_by_username_and_slug', 'username' : item.user.username, 'slug' : item.slug}
|
||||
|
||||
|
||||
class GridAction(object):
|
||||
def __init__(self, label=None, url_args=None, target=None):
|
||||
self.label = label
|
||||
self.url_args = url_args
|
||||
self.target = target
|
||||
|
||||
|
||||
class GridColumnFilter(object):
|
||||
def __init__(self, label, args=None):
|
||||
self.label = label
|
||||
self.args = args
|
||||
|
||||
def get_url_args(self):
|
||||
rval = {}
|
||||
for k, v in self.args.items():
|
||||
rval["f-" + k] = v
|
||||
return rval
|
||||
@@ -21,7 +21,7 @@ from galaxy import (
|
||||
from galaxy.tools.repositories import ValidationContext
|
||||
from galaxy.web.base.controller import BaseUIController
|
||||
from galaxy.web.form_builder import CheckboxField, SelectField
|
||||
from galaxy.web.framework.helpers import grids
|
||||
from galaxy.webapps.reports.framework import grids
|
||||
from galaxy.webapps.tool_shed.util import ratings_util
|
||||
from tool_shed.capsule import capsule_manager
|
||||
from tool_shed.dependencies.repository import relation_builder
|
||||
|
||||
@@ -215,7 +215,6 @@ class InstalledRepositoryGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = dict(deleted="False")
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
|
||||
@@ -3,7 +3,8 @@ import logging
|
||||
from markupsafe import escape
|
||||
from sqlalchemy import and_
|
||||
|
||||
from galaxy.web.framework.helpers import grids, time_ago
|
||||
from galaxy.web.framework.helpers import time_ago
|
||||
from galaxy.webapps.reports.framework import grids
|
||||
from galaxy.webapps.tool_shed import model
|
||||
from tool_shed.grids.repository_grids import CategoryGrid, RepositoryGrid
|
||||
from tool_shed.util import hg_util
|
||||
|
||||
@@ -7,7 +7,7 @@ from sqlalchemy import and_, false, or_, true
|
||||
import tool_shed.grids.util as grids_util
|
||||
import tool_shed.repository_types.util as rt_util
|
||||
import tool_shed.util.shed_util_common as suc
|
||||
from galaxy.web.framework.helpers import grids
|
||||
from galaxy.webapps.reports.framework import grids
|
||||
from galaxy.webapps.tool_shed import model
|
||||
from tool_shed.util import hg_util, metadata_util, repository_util
|
||||
|
||||
@@ -62,7 +62,6 @@ class CategoryGrid(grids.Grid):
|
||||
operations = []
|
||||
standard_filters = []
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
|
||||
@@ -236,7 +235,6 @@ class RepositoryGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = dict(deleted="False")
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
@@ -358,7 +356,6 @@ class MatchedRepositoryGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = {}
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
@@ -457,7 +454,6 @@ class RepositoriesByUserGrid(RepositoryGrid):
|
||||
standard_filters = []
|
||||
default_filter = dict(deleted="False")
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
@@ -978,7 +974,6 @@ class RepositoryMetadataGrid(grids.Grid):
|
||||
standard_filters = []
|
||||
default_filter = dict(malicious="False")
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
@@ -1298,7 +1293,6 @@ class ValidCategoryGrid(CategoryGrid):
|
||||
operations = []
|
||||
standard_filters = []
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import logging
|
||||
from markupsafe import escape
|
||||
from sqlalchemy import and_, false, null, or_, true
|
||||
|
||||
from galaxy.web.framework.helpers import grids
|
||||
from galaxy.webapps.reports.framework import grids
|
||||
from galaxy.webapps.tool_shed import model
|
||||
from tool_shed.grids.repository_grids import RepositoryGrid
|
||||
from tool_shed.util import hg_util, metadata_util
|
||||
@@ -45,7 +45,6 @@ class ComponentGrid(grids.Grid):
|
||||
operations = []
|
||||
standard_filters = []
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
|
||||
@@ -349,7 +348,6 @@ class RepositoryReviewsByUserGrid(grids.Grid):
|
||||
]
|
||||
standard_filters = []
|
||||
num_rows_per_page = 50
|
||||
preserve_state = False
|
||||
use_paging = False
|
||||
|
||||
def build_initial_query(self, trans, **kwd):
|
||||
|
||||
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
@@ -1 +1 @@
|
||||
define("mvc/grid/grid-model",["exports"],function(t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=Backbone.Model.extend({defaults:{url_base:"",async:!1,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:!1,advanced_search:!1,cur_page:1,num_pages:1,operation:void 0,item_ids:void 0},can_async_op:function(t){return-1!==_.indexOf(this.attributes.async_ops,t)},add_filter:function(t,e,i){if(i){var s,r=this.attributes.filters[t];if(null===r||void 0===r)s=e;else if("string"==typeof r)if("All"==r||r==e)s=e;else{var a=[];a[0]=r,a[1]=e,s=a}else-1===(s=r).indexOf(e)&&s.push(e);this.attributes.filters[t]=s}else this.attributes.filters[t]=e},remove_filter:function(t,e){var i=this.attributes.filters[t];if(null===i||void 0===i)return!1;if("string"==typeof i)this.attributes.filters[t]="";else{var s=_.indexOf(i,e);-1!==s&&(i[s]="")}},get_url_data:function(){var t={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};this.attributes.operation&&(t.operation=this.attributes.operation),this.attributes.item_ids&&(t.id=this.attributes.item_ids);var e=this;return _.each(_.pairs(e.attributes.filters),function(e){t["f-"+e[0]]=e[1]}),t},get_url:function(t){return this.get("url_base")+"?"+$.param(this.get_url_data())+"&"+$.param(t)}})});
|
||||
define("mvc/grid/grid-model",["exports"],function(t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=Backbone.Model.extend({defaults:{url_base:"",async:!1,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:!1,advanced_search:!1,cur_page:1,num_pages:1,operation:void 0,item_ids:void 0},add_filter:function(t,e,i){if(i){var s,r=this.attributes.filters[t];if(null===r||void 0===r)s=e;else if("string"==typeof r)if("All"==r||r==e)s=e;else{var a=[];a[0]=r,a[1]=e,s=a}else-1===(s=r).indexOf(e)&&s.push(e);this.attributes.filters[t]=s}else this.attributes.filters[t]=e},remove_filter:function(t,e){var i=this.attributes.filters[t];if(null===i||void 0===i)return!1;if("string"==typeof i)this.attributes.filters[t]="";else{var s=_.indexOf(i,e);-1!==s&&(i[s]="")}},get_url_data:function(){var t={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};this.attributes.operation&&(t.operation=this.attributes.operation),this.attributes.item_ids&&(t.id=this.attributes.item_ids);var e=this;return _.each(_.pairs(e.attributes.filters),function(e){t["f-"+e[0]]=e[1]}),t},get_url:function(t){return this.get("url_base")+"?"+$.param(this.get_url_data())+"&"+$.param(t)}})});
|
||||
@@ -1 +1 @@
|
||||
define("mvc/grid/grid-shared",["exports","mvc/grid/grid-view"],function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=function(e){return e&&e.__esModule?e:{default:e}}(t),i=Backbone.View.extend({initialize:function(e){var t=this;this.setElement($("<div/>")),this.model=new Backbone.Model(e),this.item=this.model.get("item"),this.title=this.model.get("plural"),$.ajax({url:Galaxy.root+this.item+"/"+this.model.get("action_id")+"?"+$.param(Galaxy.params),success:function(e){e.dict_format=!0,t.model.set(e),t.render()}})},render:function(){var e=new a.default(this.model.attributes);this.$el.empty().append(e.$el),this.$el.append(this._templateShared())},_templateShared:function(){var e=this,t=$("<div><h2>"+this.model.get("plural")+" shared with you by others</h2></div>"),a=this.model.attributes;if(a.shared_by_others&&a.shared_by_others.length>0){var i=$('<table class="colored" border="0" cellspacing="0" cellpadding="0" width="100%"><tr class="header"><th>Title</th><th>Owner</th></tr></table>');_.each(a.shared_by_others,function(t,a){var r=Galaxy.root+e.item+"/display_by_username_and_slug?username="+t.username+"&slug="+t.slug;i.append('<tr><td><a href="'+r+'">'+_.escape(t.title)+"</a></td><td>"+_.escape(t.username)+"</td></tr>")}),t.append(i)}else t.append("No "+this.model.get("plural").toLowerCase()+" have been shared with you.");return t}});e.default={View:i}});
|
||||
define("mvc/grid/grid-shared",["exports","mvc/grid/grid-view"],function(e,t){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var a=function(e){return e&&e.__esModule?e:{default:e}}(t),i=Backbone.View.extend({initialize:function(e){var t=this;this.setElement($("<div/>")),this.model=new Backbone.Model(e),this.item=this.model.get("item"),this.title=this.model.get("plural"),$.ajax({url:Galaxy.root+this.item+"/"+this.model.get("action_id")+"?"+$.param(Galaxy.params),success:function(e){t.model.set(e),t.render()}})},render:function(){var e=new a.default(this.model.attributes);this.$el.empty().append(e.$el),this.$el.append(this._templateShared())},_templateShared:function(){var e=this,t=$("<div><h2>"+this.model.get("plural")+" shared with you by others</h2></div>"),a=this.model.attributes;if(a.shared_by_others&&a.shared_by_others.length>0){var i=$('<table class="colored" border="0" cellspacing="0" cellpadding="0" width="100%"><tr class="header"><th>Title</th><th>Owner</th></tr></table>');_.each(a.shared_by_others,function(t,a){var r=Galaxy.root+e.item+"/display_by_username_and_slug?username="+t.username+"&slug="+t.slug;i.append('<tr><td><a href="'+r+'">'+_.escape(t.title)+"</a></td><td>"+_.escape(t.username)+"</td></tr>")}),t.append(i)}else t.append("No "+this.model.get("plural").toLowerCase()+" have been shared with you.");return t}});e.default={View:i}});
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
define("mvc/history/history-list",["exports","utils/localization","utils/utils","mvc/grid/grid-view","mvc/history/history-model","mvc/history/copy-dialog"],function(t,e,i,o,n,a){"use strict";function l(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(t,"__esModule",{value:!0});var r=l(e),d=l(i),c=l(o),s=l(n),u=l(a),f=c.default.extend({_showCopyDialog:function(t){var e=new s.default.History({id:t});e.fetch().fail(function(){alert("History could not be fetched. Please contact an administrator")}).done(function(){(0,u.default)(e,{}).done(function(){window.parent&&window.parent.Galaxy&&window.parent.Galaxy.currHistoryPanel&&window.parent.Galaxy.currHistoryPanel.loadCurrentHistory(),window.location.reload(!0)})})},_add_operation:function(t,e,i){var o=this,n=i.operation_config[e.label];"Copy"==e.label&&(e.onclick=function(t){o._showCopyDialog(t)}),n.allowed&&e.allow_popup&&t.addItem({html:e.label,href:n.url_args,target:n.target,confirmation_text:e.confirm,func:function(t){t.preventDefault();var n=$(t.target).html();e.onclick?e.onclick(i.encode_id):o.execute(this.findItemByHtml(n))}})}}),y=Backbone.View.extend({title:(0,r.default)("Histories"),initialize:function(t){var e=this;this.setElement($("<div/>")),this.model=new Backbone.Model,d.default.get({url:Galaxy.root+"history/"+t.action_id+"?"+$.param(Galaxy.params),success:function(t){t.dict_format=!0,e.model.set(t),e.render()}})},render:function(){var t=new f(this.model.attributes);this.$el.empty().append(t.$el)}});t.default={View:y}});
|
||||
define("mvc/history/history-list",["exports","utils/localization","utils/utils","mvc/grid/grid-view","mvc/history/history-model","mvc/history/copy-dialog"],function(t,e,i,o,n,a){"use strict";function l(t){return t&&t.__esModule?t:{default:t}}Object.defineProperty(t,"__esModule",{value:!0});var r=l(e),d=l(i),c=l(o),s=l(n),u=l(a),f=c.default.extend({_showCopyDialog:function(t){var e=new s.default.History({id:t});e.fetch().fail(function(){alert("History could not be fetched. Please contact an administrator")}).done(function(){(0,u.default)(e,{}).done(function(){window.parent&&window.parent.Galaxy&&window.parent.Galaxy.currHistoryPanel&&window.parent.Galaxy.currHistoryPanel.loadCurrentHistory(),window.location.reload(!0)})})},_add_operation:function(t,e,i){var o=this,n=i.operation_config[e.label];"Copy"==e.label&&(e.onclick=function(t){o._showCopyDialog(t)}),n.allowed&&e.allow_popup&&t.addItem({html:e.label,href:n.url_args,target:n.target,confirmation_text:e.confirm,func:function(t){t.preventDefault();var n=$(t.target).html();e.onclick?e.onclick(i.encode_id):o.execute(this.findItemByHtml(n))}})}}),y=Backbone.View.extend({title:(0,r.default)("Histories"),initialize:function(t){var e=this;this.setElement($("<div/>")),this.model=new Backbone.Model,d.default.get({url:Galaxy.root+"history/"+t.action_id+"?"+$.param(Galaxy.params),success:function(t){e.model.set(t),e.render()}})},render:function(){var t=new f(this.model.attributes);this.$el.empty().append(t.$el)}});t.default={View:y}});
|
||||
@@ -1 +1 @@
|
||||
define("mvc/user/user-preferences",["exports","utils/localization","mvc/form/form-view","mvc/ui/ui-misc","utils/query-string-parsing"],function(e,t,i,s,a){"use strict";function o(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var n=o(t),r=(o(i),o(s)),u=o(a),l=Backbone.Model.extend({initialize:function(e){(e=e||{}).user_id=e.user_id||Galaxy.user.id,this.set({user_id:e.user_id,information:{title:(0,n.default)("Manage information"),description:"Edit your email, addresses and custom parameters or change your username.",url:"api/users/"+e.user_id+"/information/inputs",icon:"fa-user",redirect:"user"},password:{title:(0,n.default)("Change password"),description:(0,n.default)("Allows you to change your login credentials."),icon:"fa-unlock-alt",url:"api/users/"+e.user_id+"/password/inputs",submit_title:"Save password",redirect:"user"},communication:{title:(0,n.default)("Change communication settings"),description:(0,n.default)("Enable or disable the communication feature to chat with other users."),url:"api/users/"+e.user_id+"/communication/inputs",icon:"fa-comments-o",redirect:"user"},permissions:{title:(0,n.default)("Set dataset permissions for new histories"),description:"Grant others default access to newly created histories. Changes made here will only affect histories created after these settings have been stored.",url:"api/users/"+e.user_id+"/permissions/inputs",icon:"fa-users",submit_title:"Save permissions",redirect:"user"},api_key:{title:(0,n.default)("Manage API key"),description:(0,n.default)("Access your current API key or create a new one."),url:"api/users/"+e.user_id+"/api_key/inputs",icon:"fa-key",submit_title:"Create a new key",submit_icon:"fa-check"},toolbox_filters:{title:(0,n.default)("Manage Toolbox filters"),description:(0,n.default)("Customize your Toolbox by displaying or omitting sets of Tools."),url:"api/users/"+e.user_id+"/toolbox_filters/inputs",icon:"fa-filter",submit_title:"Save filters",redirect:"user"},openids:{title:(0,n.default)("Manage OpenIDs"),description:(0,n.default)("Associate OpenIDs with your account."),icon:"fa-openid",onclick:function(){window.location.href=Galaxy.root+"user/openid_manage?cntrller=user&use_panels=True"}},custom_builds:{title:(0,n.default)("Manage custom builds"),description:(0,n.default)("Add or remove custom builds using history datasets."),icon:"fa-cubes",onclick:function(){window.location.href=Galaxy.root+"custom_builds"}},logout:{title:(0,n.default)("Sign out"),description:(0,n.default)("Click here to sign out of all sessions."),icon:"fa-sign-out",onclick:function(){Galaxy.modal.show({title:(0,n.default)("Sign out"),body:"Do you want to continue and sign out of all active sessions?",buttons:{Cancel:function(){Galaxy.modal.hide()},"Sign out":function(){window.location.href=Galaxy.root+"user/logout?session_csrf_token="+Galaxy.session_csrf_token}}})}}})}}),d=Backbone.View.extend({title:(0,n.default)("User Preferences"),initialize:function(){this.model=new l,this.setElement("<div/>"),this.render()},render:function(){var e=this,t=Galaxy.config;$.getJSON(Galaxy.root+"api/users/"+Galaxy.user.id,function(i){e.$preferences=$("<div/>").addClass("ui-panel").append($("<h2/>").append("User preferences")).append($("<p/>").append("You are logged in as <strong>"+_.escape(i.email)+"</strong>.")).append(e.$table=$("<table/>").addClass("ui-panel-table"));var s=u.default.get("message"),a=u.default.get("status");s&&a&&e.$preferences.prepend(new r.default.Message({message:s,status:a}).$el),t.use_remote_user||(e._addLink("information"),e._addLink("password")),t.enable_communication_server&&e._addLink("communication"),e._addLink("custom_builds"),e._addLink("permissions"),e._addLink("api_key"),t.has_user_tool_filters&&e._addLink("toolbox_filters"),t.enable_openid&&!t.use_remote_user&&e._addLink("openids"),Galaxy.session_csrf_token&&e._addLink("logout"),e.$preferences.append(e._templateFooter(i)),e.$el.empty().append(e.$preferences)})},_addLink:function(e){var t=this.model.get(e),i=$(this._templateLink(t)),s=i.find("a");t.onclick?s.on("click",function(){t.onclick()}):s.attr("href",Galaxy.root+"user/"+e),this.$table.append(i)},_templateLink:function(e){return'<tr><td><div class="ui-panel-icon fa '+e.icon+'"></td><td><a class="ui-panel-anchor" href="javascript:void(0)">'+e.title+'</a><div class="ui-form-info">'+e.description+"</div></td></tr>"},_templateFooter:function(e){return'<p class="ui-panel-footer">You are using <strong>'+e.nice_total_disk_usage+"</strong> of disk space in this Galaxy instance. "+(Galaxy.config.enable_quotas?"Your disk quota is: <strong>"+e.quota+"</strong>. ":"")+'Is your usage more than expected? See the <a href="https://galaxyproject.org/learn/managing-datasets/" target="_blank">documentation</a> for tips on how to find all of the data in your account.</p>'}});e.default={View:d,Model:l}});
|
||||
define("mvc/user/user-preferences",["exports","utils/localization","mvc/form/form-view","mvc/ui/ui-misc","utils/query-string-parsing"],function(e,t,i,s,o){"use strict";function a(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(e,"__esModule",{value:!0});var n=a(t),r=(a(i),a(s)),u=a(o),l=Backbone.Model.extend({initialize:function(e){(e=e||{}).user_id=e.user_id||Galaxy.user.id,this.set({user_id:e.user_id,information:{title:(0,n.default)("Manage information"),description:"Edit your email, addresses and custom parameters or change your username.",url:"api/users/"+e.user_id+"/information/inputs",icon:"fa-user",redirect:"user"},password:{title:(0,n.default)("Change password"),description:(0,n.default)("Allows you to change your login credentials."),icon:"fa-unlock-alt",url:"api/users/"+e.user_id+"/password/inputs",submit_title:"Save password",redirect:"user"},communication:{title:(0,n.default)("Change communication settings"),description:(0,n.default)("Enable or disable the communication feature to chat with other users."),url:"api/users/"+e.user_id+"/communication/inputs",icon:"fa-comments-o",redirect:"user"},permissions:{title:(0,n.default)("Set dataset permissions for new histories"),description:"Grant others default access to newly created histories. Changes made here will only affect histories created after these settings have been stored.",url:"api/users/"+e.user_id+"/permissions/inputs",icon:"fa-users",submit_title:"Save permissions",redirect:"user"},api_key:{title:(0,n.default)("Manage API key"),description:(0,n.default)("Access your current API key or create a new one."),url:"api/users/"+e.user_id+"/api_key/inputs",icon:"fa-key",submit_title:"Create a new key",submit_icon:"fa-check"},toolbox_filters:{title:(0,n.default)("Manage Toolbox filters"),description:(0,n.default)("Customize your Toolbox by displaying or omitting sets of Tools."),url:"api/users/"+e.user_id+"/toolbox_filters/inputs",icon:"fa-filter",submit_title:"Save filters",redirect:"user"},openids:{title:(0,n.default)("Manage OpenIDs"),description:(0,n.default)("Associate OpenIDs with your account."),icon:"fa-openid",onclick:function(){window.location.href=Galaxy.root+"openids/list"}},custom_builds:{title:(0,n.default)("Manage custom builds"),description:(0,n.default)("Add or remove custom builds using history datasets."),icon:"fa-cubes",onclick:function(){window.location.href=Galaxy.root+"custom_builds"}},logout:{title:(0,n.default)("Sign out"),description:(0,n.default)("Click here to sign out of all sessions."),icon:"fa-sign-out",onclick:function(){Galaxy.modal.show({title:(0,n.default)("Sign out"),body:"Do you want to continue and sign out of all active sessions?",buttons:{Cancel:function(){Galaxy.modal.hide()},"Sign out":function(){window.location.href=Galaxy.root+"user/logout?session_csrf_token="+Galaxy.session_csrf_token}}})}}})}}),d=Backbone.View.extend({title:(0,n.default)("User Preferences"),initialize:function(){this.model=new l,this.setElement("<div/>"),this.render()},render:function(){var e=this,t=Galaxy.config;$.getJSON(Galaxy.root+"api/users/"+Galaxy.user.id,function(i){e.$preferences=$("<div/>").addClass("ui-panel").append($("<h2/>").append("User preferences")).append($("<p/>").append("You are logged in as <strong>"+_.escape(i.email)+"</strong>.")).append(e.$table=$("<table/>").addClass("ui-panel-table"));var s=u.default.get("message"),o=u.default.get("status");s&&o&&e.$preferences.prepend(new r.default.Message({message:s,status:o}).$el),t.use_remote_user||(e._addLink("information"),e._addLink("password")),t.enable_communication_server&&e._addLink("communication"),e._addLink("custom_builds"),e._addLink("permissions"),e._addLink("api_key"),t.has_user_tool_filters&&e._addLink("toolbox_filters"),t.enable_openid&&!t.use_remote_user&&e._addLink("openids"),Galaxy.session_csrf_token&&e._addLink("logout"),e.$preferences.append(e._templateFooter(i)),e.$el.empty().append(e.$preferences)})},_addLink:function(e){var t=this.model.get(e),i=$(this._templateLink(t)),s=i.find("a");t.onclick?s.on("click",function(){t.onclick()}):s.attr("href",Galaxy.root+"user/"+e),this.$table.append(i)},_templateLink:function(e){return'<tr><td><div class="ui-panel-icon fa '+e.icon+'"></td><td><a class="ui-panel-anchor" href="javascript:void(0)">'+e.title+'</a><div class="ui-form-info">'+e.description+"</div></td></tr>"},_templateFooter:function(e){return'<p class="ui-panel-footer">You are using <strong>'+e.nice_total_disk_usage+"</strong> of disk space in this Galaxy instance. "+(Galaxy.config.enable_quotas?"Your disk quota is: <strong>"+e.quota+"</strong>. ":"")+'Is your usage more than expected? See the <a href="https://galaxyproject.org/learn/managing-datasets/" target="_blank">documentation</a> for tips on how to find all of the data in your account.</p>'}});e.default={View:d,Model:l}});
|
||||
@@ -0,0 +1 @@
|
||||
define("reports/grid/grid-model",["exports"],function(t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=Backbone.Model.extend({defaults:{url_base:"",async:!1,async_ops:[],categorical_filters:[],filters:{},sort_key:null,show_item_checkboxes:!1,advanced_search:!1,cur_page:1,num_pages:1,operation:void 0,item_ids:void 0},can_async_op:function(t){return-1!==_.indexOf(this.attributes.async_ops,t)},add_filter:function(t,e,i){if(i){var s,r=this.attributes.filters[t];if(null===r||void 0===r)s=e;else if("string"==typeof r)if("All"==r||r==e)s=e;else{var a=[];a[0]=r,a[1]=e,s=a}else-1===(s=r).indexOf(e)&&s.push(e);this.attributes.filters[t]=s}else this.attributes.filters[t]=e},remove_filter:function(t,e){var i=this.attributes.filters[t];if(null===i||void 0===i)return!1;if("string"==typeof i)this.attributes.filters[t]="";else{var s=_.indexOf(i,e);-1!==s&&(i[s]="")}},get_url_data:function(){var t={async:this.attributes.async,sort:this.attributes.sort_key,page:this.attributes.cur_page,show_item_checkboxes:this.attributes.show_item_checkboxes,advanced_search:this.attributes.advanced_search};this.attributes.operation&&(t.operation=this.attributes.operation),this.attributes.item_ids&&(t.id=this.attributes.item_ids);var e=this;return _.each(_.pairs(e.attributes.filters),function(e){t["f-"+e[0]]=e[1]}),t},get_url:function(t){return this.get("url_base")+"?"+$.param(this.get_url_data())+"&"+$.param(t)}})});
|
||||
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
@@ -1,4 +0,0 @@
|
||||
<%namespace name="grid_base" file="./grid_base.mako" import="*" />
|
||||
|
||||
${init()}
|
||||
${h.dumps( grid_base.get_grid_config() )}
|
||||
@@ -1,18 +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=active_view
|
||||
self.message_box_visible=False
|
||||
%>
|
||||
</%def>
|
||||
|
||||
<%def name="center_panel()">
|
||||
<div style="overflow: auto; height: 100%;">
|
||||
<div style="padding: 10px">
|
||||
${grid}
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
||||
@@ -16,7 +16,7 @@
|
||||
<li><a href="${h.url_for( controller='user', action='api_keys', cntrller=cntrller )}">${_('Manage your API keys')}</a></li>
|
||||
<li><a href="${h.url_for( controller='user', action='toolbox_filters', cntrller=cntrller )}">${_('Manage your ToolBox filters')}</a></li>
|
||||
%if trans.app.config.enable_openid and not trans.app.config.use_remote_user:
|
||||
<li><a href="${h.url_for( controller='user', action='openid_manage', cntrller=cntrller )}">${_('Manage OpenIDs')}</a> linked to your account</li>
|
||||
<li><a href="${h.url_for( controller='openids', action='list' )}">${_('Manage OpenIDs')}</a> linked to your account</li>
|
||||
%endif
|
||||
<li><a href="${h.url_for( controller='user', action='logout', logout_all=True )}" target="_top">${_('Logout')}</a> ${_('of all user sessions')}</li>
|
||||
%else:
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
## Template generates a grid that enables user to select items.
|
||||
<%inherit file="../grid_base.mako" />
|
||||
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="login.mako" import="render_openid_form" />
|
||||
|
||||
<%def name="load()">
|
||||
<%def name="body()">
|
||||
<h2>Associate more OpenIDs</h2>
|
||||
${render_openid_form( kwargs['redirect'], True, kwargs['openid_providers'] )}
|
||||
<br/><br/>
|
||||
${parent.load()}
|
||||
</%def>
|
||||
${render_openid_form( redirect, True, openid_providers )}
|
||||
</%def>
|
||||
@@ -1 +0,0 @@
|
||||
<%inherit file="/grid_base.mako"/>
|
||||
@@ -1,5 +1,5 @@
|
||||
<%!
|
||||
from galaxy.web.framework.helpers.grids import TextColumn
|
||||
from galaxy.webapps.reports.framework.grids import TextColumn
|
||||
|
||||
def inherit(context):
|
||||
kwargs = context.get( 'kwargs', {} )
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
## load javascript
|
||||
<script type="text/javascript">
|
||||
require(['mvc/grid/grid-view'], function(GridView) {
|
||||
require(['reports/grid/grid-view'], function(GridView) {
|
||||
$(function() {
|
||||
var gridView = new GridView.default( ${ h.dumps( self.get_grid_config( embedded=embedded, insert=insert ) ) } );
|
||||
});
|
||||
@@ -0,0 +1,4 @@
|
||||
<%namespace name="grid_base" file="/webapps/reports/grid_base.mako" import="*" />
|
||||
|
||||
${init()}
|
||||
${h.dumps( grid_base.get_grid_config() )}
|
||||
@@ -5,7 +5,7 @@
|
||||
${parent.javascripts()}
|
||||
|
||||
<script type="text/javascript">
|
||||
require(['reports_webapp/run_stats'], function(run_stats){
|
||||
require(['reports/run_stats'], function(run_stats){
|
||||
run_stats.create_chart(${jf_hr_data}, "jf_hr_chart", "hours", "Jobs Finished per Hour");
|
||||
run_stats.create_chart(${jf_dy_data}, "jf_dy_chart", "days", "Jobs Finished per Day");
|
||||
run_stats.create_chart(${jc_hr_data}, "jc_hr_chart", "hours", "Jobs Created per Hour");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace name="grid_base" file="/grid_base.mako" import="*" />
|
||||
<%namespace name="grid_base" file="/webapps/reports/grid_base.mako" import="*" />
|
||||
<%namespace name="grid_common" file="../common/grid_common.mako" import="*" />
|
||||
|
||||
<%def name="insert()">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace name="grid_base" file="/grid_base.mako" import="*" />
|
||||
<%namespace name="grid_base" file="/webapps/reports/grid_base.mako" import="*" />
|
||||
<%namespace name="grid_common" file="../common/grid_common.mako" import="*" />
|
||||
|
||||
<%def name="insert()">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<%!
|
||||
from galaxy.web.framework.helpers.grids import TextColumn, StateColumn, GridColumnFilter
|
||||
from galaxy.webapps.reports.framework.grids import TextColumn, StateColumn, GridColumnFilter
|
||||
from galaxy.web.framework.helpers import iff
|
||||
%>
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
<%inherit file="/grid_base.mako"/>
|
||||
<%inherit file="/webapps/reports/grid_base.mako"/>
|
||||
|
||||
Reference in New Issue
Block a user