mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-25 00:12:08 +08:00
Merge pull request #7097 from guerler/display_applications
Replace display applications mako with vue component
This commit is contained in:
@@ -14,6 +14,7 @@ import DataTables from "components/admin/DataTables.vue";
|
||||
import DataTypes from "components/admin/DataTypes.vue";
|
||||
import DataManagerView from "components/admin/DataManager/DataManagerView.vue";
|
||||
import DataManagerRouter from "components/admin/DataManager/DataManagerRouter.vue";
|
||||
import DisplayApplications from "components/admin/DisplayApplications.vue";
|
||||
import Vue from "vue";
|
||||
import { serverPath } from "utils/serverPath";
|
||||
|
||||
@@ -33,6 +34,7 @@ window.app = function app(options, bootstrapped) {
|
||||
"(/)admin(/)users": "show_users",
|
||||
"(/)admin(/)roles": "show_roles",
|
||||
"(/)admin(/)groups": "show_groups",
|
||||
"(/)admin(/)display_applications": "show_display_applications",
|
||||
"(/)admin(/)tool_versions": "show_tool_versions",
|
||||
"(/)admin(/)quotas": "show_quotas",
|
||||
"(/)admin(/)repositories": "show_repositories",
|
||||
@@ -111,19 +113,26 @@ window.app = function app(options, bootstrapped) {
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
_display_vue_helper: function(component, props) {
|
||||
let instance = Vue.extend(component);
|
||||
let vm = document.createElement("div");
|
||||
this.page.display(vm);
|
||||
new instance(props).$mount(vm);
|
||||
},
|
||||
|
||||
show_data_tables: function() {
|
||||
this._display_vue_helper(DataTables);
|
||||
},
|
||||
|
||||
show_data_types: function() {
|
||||
this._display_vue_helper(DataTypes);
|
||||
},
|
||||
|
||||
show_display_applications: function() {
|
||||
this._display_vue_helper(DisplayApplications);
|
||||
},
|
||||
|
||||
show_data_manager: function(path) {
|
||||
let vueMount = document.createElement("div");
|
||||
this.page.display(vueMount);
|
||||
|
||||
@@ -34,6 +34,7 @@ var AdminPanel = Backbone.View.extend({
|
||||
{
|
||||
title: _l("Display applications"),
|
||||
url: "admin/display_applications",
|
||||
target: "__use_router__",
|
||||
id: "admin-link-display-applications"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import axios from "axios";
|
||||
|
||||
export function getDisplayApplications() {
|
||||
let url = `${getAppRoot()}api/display_applications`;
|
||||
return axios.get(url);
|
||||
}
|
||||
|
||||
export function reloadDisplayApplications(ids) {
|
||||
let url = `${getAppRoot()}api/display_applications/reload`;
|
||||
return axios.post(url, {ids: ids});
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-alert :show="messageVisible" :variant="messageVariant">
|
||||
{{ messageText }}
|
||||
</b-alert>
|
||||
<b-alert :show="warningVisible" variant="warning">
|
||||
No display applications available.
|
||||
</b-alert>
|
||||
<div v-if="applicationsVisible" class="card-header">
|
||||
There are currently {{ applicationsLength }}
|
||||
<b-button size="sm" @click.prevent="reloadAll()" title="Reload all display applications" data-placement="bottom">
|
||||
<span class="fa fa-refresh"/>
|
||||
</b-button>
|
||||
display applications loaded.
|
||||
</div>
|
||||
<b-table id="display-applications-grid" v-if="applicationsVisible" striped :fields="applicationsAttributes" :items="applications">
|
||||
<template slot="reload" slot-scope="data">
|
||||
<b-button size="sm" title="Reload display application" data-placement="bottom" @click.prevent="reload(data.item.id, data.index)">
|
||||
<span class="fa fa-refresh"/>
|
||||
</b-button>
|
||||
</template>
|
||||
<template slot="links" slot-scope="data">
|
||||
<li v-for="link in data.item.links">{{ link.name }}</li>
|
||||
</template>
|
||||
</b-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getDisplayApplications, reloadDisplayApplications } from "./AdminServices.js"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
applications: [],
|
||||
applicationsLoaded: false,
|
||||
applicationsAttributes: [
|
||||
{ key: 'reload' },
|
||||
{ key: 'name', sortable: true },
|
||||
{ key: 'id', sortable: true },
|
||||
{ key: 'version' },
|
||||
{ key: 'links' }
|
||||
],
|
||||
messageText: null,
|
||||
messageVariant: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
applicationsIndex: function() {
|
||||
let result = {};
|
||||
for (let app of this.applications) {
|
||||
result[app.id] = app;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
applicationsAll: function() {
|
||||
let result = [];
|
||||
for (let app of this.applications) {
|
||||
result.push(app.id);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
applicationsVisible: function() {
|
||||
return this.applications.length > 0;
|
||||
},
|
||||
applicationsLength: function() {
|
||||
return this.applications.length;
|
||||
},
|
||||
messageVisible: function() {
|
||||
return this.messageText != null;
|
||||
},
|
||||
warningVisible: function() {
|
||||
return !this.applicationsVisible && this.applicationsLoaded;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
getDisplayApplications()
|
||||
.then(response => {
|
||||
this.applications = response.data;
|
||||
this.applicationsLoaded = true;
|
||||
})
|
||||
.catch(e => {
|
||||
this._errorMessage(e);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
reload: function(id) {
|
||||
this._reload([id]);
|
||||
},
|
||||
reloadAll: function() {
|
||||
let ids = [];
|
||||
for (let app of this.applications) {
|
||||
ids.push(app.id);
|
||||
}
|
||||
this._reload(ids);
|
||||
},
|
||||
_reload: function(ids) {
|
||||
this._highlightRows(this.applicationsAll, "default");
|
||||
reloadDisplayApplications(ids)
|
||||
.then(response => {
|
||||
this.messageVariant = "info";
|
||||
this.messageText = response.data.message;
|
||||
this._highlightRows(response.data.failed, "danger");
|
||||
this._highlightRows(response.data.reloaded, "success");
|
||||
})
|
||||
.catch(e => {
|
||||
this._errorMessage(e);
|
||||
});
|
||||
},
|
||||
_highlightRows: function(appList, status) {
|
||||
for (let appIndex of appList) {
|
||||
let app = this.applicationsIndex[appIndex];
|
||||
if (app) {
|
||||
app._rowVariant = status;
|
||||
}
|
||||
}
|
||||
},
|
||||
_errorMessage: function(e) {
|
||||
let message = e && e.response && e.response.data && e.response.data.err_msg;
|
||||
this.messageText = message || "Request failed for an unknown reason.";
|
||||
this.messageVariant = "danger";
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,61 @@
|
||||
"""
|
||||
API operations on annotations.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from galaxy import queue_worker
|
||||
from galaxy.web import expose_api, require_admin
|
||||
from galaxy.web.base.controller import BaseAPIController
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DisplayApplicationsController(BaseAPIController):
|
||||
|
||||
@expose_api
|
||||
def index(self, trans, **kwd):
|
||||
"""
|
||||
GET /api/display_applications/
|
||||
|
||||
Returns the list of display applications.
|
||||
|
||||
:returns: list of available display applications
|
||||
:rtype: list
|
||||
"""
|
||||
response = []
|
||||
for display_app in trans.app.datatypes_registry.display_applications.values():
|
||||
response.append({
|
||||
'id' : display_app.id,
|
||||
'name': display_app.name,
|
||||
'version': display_app.version,
|
||||
'filename_': display_app._filename,
|
||||
'links': [{'name': l.name} for l in display_app.links.values()]
|
||||
})
|
||||
return response
|
||||
|
||||
@expose_api
|
||||
@require_admin
|
||||
def reload(self, trans, payload={}, **kwd):
|
||||
"""
|
||||
POST /api/display_applications/reload
|
||||
|
||||
Reloads the list of display applications.
|
||||
|
||||
:param ids: list containing ids of display to be reloaded
|
||||
:type ids: list
|
||||
"""
|
||||
ids = payload.get('ids')
|
||||
queue_worker.send_control_task(trans.app,
|
||||
'reload_display_application',
|
||||
noop_self=True,
|
||||
kwargs={'display_application_ids': ids})
|
||||
reloaded, failed = trans.app.datatypes_registry.reload_display_applications(ids)
|
||||
if not reloaded and failed:
|
||||
message = 'Unable to reload any of the %i requested display applications ("%s").' % (len(failed), '", "'.join(failed))
|
||||
elif failed:
|
||||
message = 'Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").' % (len(reloaded), '", "'.join(reloaded), len(failed), '", "'.join(failed))
|
||||
elif not reloaded:
|
||||
message = 'You need to request at least one display application to reload.'
|
||||
else:
|
||||
message = 'Reloaded %i requested display applications ("%s").' % (len(reloaded), '", "'.join(reloaded))
|
||||
return {'message': message, 'reloaded': reloaded, 'failed': failed}
|
||||
@@ -103,6 +103,7 @@ def app_factory(global_conf, load_app_kwds={}, **kwargs):
|
||||
webapp.add_client_route('/admin/data_types', 'admin')
|
||||
webapp.add_client_route('/admin/data_manager{path_info:.*}', 'admin')
|
||||
webapp.add_client_route('/admin/users', 'admin')
|
||||
webapp.add_client_route('/admin/display_applications', 'admin')
|
||||
webapp.add_client_route('/admin/roles', 'admin')
|
||||
webapp.add_client_route('/admin/forms', 'admin')
|
||||
webapp.add_client_route('/admin/groups', 'admin')
|
||||
@@ -553,6 +554,22 @@ def populate_api_routes(webapp, app):
|
||||
action='get_api_key',
|
||||
conditions=dict(method=["GET"]))
|
||||
|
||||
# ======================================
|
||||
# ====== DISPLAY APPLICATIONS API ======
|
||||
# ======================================
|
||||
|
||||
webapp.mapper.connect('index',
|
||||
'/api/display_applications',
|
||||
controller='display_applications',
|
||||
action='index',
|
||||
conditions=dict(method=["GET"]))
|
||||
|
||||
webapp.mapper.connect('reload',
|
||||
'/api/display_applications/reload',
|
||||
controller='display_applications',
|
||||
action='reload',
|
||||
conditions=dict(method=["POST"]))
|
||||
|
||||
# =====================
|
||||
# ===== TOURS API =====
|
||||
# =====================
|
||||
|
||||
@@ -908,29 +908,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
def tool_errors(self, trans, **kwd):
|
||||
return trans.fill_template('admin/tool_errors.mako', tool_errors=global_tool_errors.error_stack)
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def display_applications(self, trans, **kwd):
|
||||
return trans.fill_template('admin/view_display_applications.mako', display_applications=trans.app.datatypes_registry.display_applications)
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def reload_display_application(self, trans, **kwd):
|
||||
galaxy.queue_worker.send_control_task(trans.app,
|
||||
'reload_display_application',
|
||||
noop_self=True,
|
||||
kwargs={'display_application_ids': kwd.get('id')})
|
||||
reloaded, failed = trans.app.datatypes_registry.reload_display_applications(kwd.get('id'))
|
||||
if not reloaded and failed:
|
||||
return trans.show_error_message('Unable to reload any of the %i requested display applications ("%s").'
|
||||
% (len(failed), '", "'.join(failed)))
|
||||
if failed:
|
||||
return trans.show_warn_message('Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").'
|
||||
% (len(reloaded), '", "'.join(reloaded), len(failed), '", "'.join(failed)))
|
||||
if not reloaded:
|
||||
return trans.show_warn_message('You need to request at least one display application to reload.')
|
||||
return trans.show_ok_message('Reloaded %i requested display applications ("%s").' % (len(reloaded), '", "'.join(reloaded)))
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def center(self, trans, **kwd):
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="card" id="display-applications-grid">
|
||||
<div class="card-header">There are currently ${len( display_applications )} <a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application' ) }" title="Reload all display applications" data-placement="bottom">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a> display applications loaded.</div>
|
||||
<div class="card-body overflow-auto">
|
||||
<table class="manage-table colored">
|
||||
<tr>
|
||||
<th>Reload</th>
|
||||
<th>Name</th>
|
||||
<th>ID</th>
|
||||
<th>Version</th>
|
||||
<th>Links</th>
|
||||
<th>Filename</th>
|
||||
</tr>
|
||||
<% ctr = 0 %>
|
||||
%for display_app in display_applications.values():
|
||||
%if ctr % 2 == 1:
|
||||
<tr class="odd_row">
|
||||
%else:
|
||||
<tr class="tr">
|
||||
%endif
|
||||
<td>
|
||||
<a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application', id=display_app.id ) }" title="Reload ${ display_app.name | h } display application" data-placement="bottom">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a>
|
||||
</td>
|
||||
<td>${ display_app.name | h }</td>
|
||||
<td>${ display_app.id | h }</td>
|
||||
<td>${ display_app.version | h }</td>
|
||||
<td><ul>
|
||||
%for link in display_app.links.values():
|
||||
<li>${ link.name | h }</li>
|
||||
%endfor
|
||||
</ul></td>
|
||||
<td>${ display_app._filename | h }</td>
|
||||
</tr>
|
||||
<% ctr += 1 %>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,8 +23,7 @@ class AdminAppTestCase(SeleniumTestCase):
|
||||
self.screenshot("admin_data_tables")
|
||||
|
||||
admin_component.index.display_applications.wait_for_and_click()
|
||||
with self.main_panel():
|
||||
admin_component.display_applications_grid.wait_for_visible()
|
||||
self.assert_warning_message("No display applications available.")
|
||||
self.screenshot("admin_display_applications")
|
||||
|
||||
admin_component.index.jobs.wait_for_and_click()
|
||||
|
||||
Reference in New Issue
Block a user