Showcase Vue JS by transforming a mako file to javascript

This commit is contained in:
anuprulez
2017-11-09 19:06:21 -05:00
committed by Dannon Baker
parent 886cd6c62e
commit c903e9fe1a
18 changed files with 140 additions and 86 deletions
+8 -1
View File
@@ -10,6 +10,8 @@ import Router from "layout/router";
import Utils from "utils/utils";
import Page from "layout/page";
var UserAPIKeys = require( 'mvc/user/user_api_keys' );
window.app = function app(options, bootstrapped) {
window.Galaxy = new GalaxyApp.GalaxyApp(options, bootstrapped);
Galaxy.debug("admin app");
@@ -24,7 +26,8 @@ window.app = function app(options, bootstrapped) {
"(/)admin(/)quotas": "show_quotas",
"(/)admin(/)repositories": "show_repositories",
"(/)admin(/)forms": "show_forms",
"(/)admin(/)form(/)(:form_id)": "show_form"
"(/)admin(/)form(/)(:form_id)": "show_form",
'(/)admin/api_keys': 'show_user_api_keys'
},
authenticate: function(args, name) {
@@ -91,6 +94,10 @@ window.app = function app(options, bootstrapped) {
);
},
show_user_api_keys: function() {
this.page.display( new UserAPIKeys.View() );
},
show_forms: function() {
this.page.display(
new GridView({
@@ -73,7 +73,8 @@ var AdminPanel = Backbone.View.extend({
},
{
title: "API keys",
url: "userskeys/all_users"
url : 'admin/api_keys',
target : '__use_router__'
},
{
title: "Impersonate a user",
@@ -0,0 +1,87 @@
define( [ 'libs/vue', "libs/toastr" ], function( Vue, mod_toastr ) {
var UserAPIKeysView = Backbone.View.extend({
initialize: function() {
mod_toastr.options.timeOut = 1000;
this.setElement( '<div/>' );
this.render();
},
render: function() {
var self = this,
url = Galaxy.root + 'userskeys/all_users';
self.$el.empty().append( self._template() );
self.fetchUsers( url );
},
/** Load users and their keys */
fetchUsers: function( url ) {
var self = this;
$.getJSON( url, function( users ) {
// apply vue model on the dom
// timeout is used to ensure dom is created first and then
// vue model is applied with the required data
setTimeout(function() {
self.applyVue( users );
});
});
},
/** Create model for the view using vue */
applyVue: function( users ) {
var form_vue = new Vue({
el: '#form-userkeys',
data: {
users: users // data model
},
methods: {
// bind event from view
generateKey: function( id ) {
var self = this;
// fetch fresh model
$.ajax({
url: Galaxy.root + 'userskeys/admin_api_keys',
data: { 'uid': id },
success: function( users ) {
mod_toastr.success("Successfully generated a user key");
// refresh the model
self._data.users = users;
},
error: function( ) {
mod_toastr.success("Error occured while loading data");
}
});
}
}
});
},
_template: function() {
return '<div id="form-userkeys" class="toolForm" v-cloak>' +
'<div class="toolFormTitle">User Information</div>' +
'<div v-if="users && users.length > 0">' +
'<table class="grid">' +
'<thead><th>Encoded UID</th><th>Email</th><th>API Key</th><th>Actions</th></thead>' +
'<tbody>' +
'<tr v-for="user in users">' +
'<td>' + '{{ user.uid }}' + '</td>' +
'<td>' + '{{ user.email }}' + '</td>' +
'<td>' + '{{ user.key }}' + '</td>' +
'<td>' +
'<input type="button" value="Generate a new key now" v-on:click="generateKey( user.uid )" />' +
'</td>' +
'</tbody>' +
'</table>' +
'</div>' +
'<div v-else>' +
'<div>No informations available</div>' +
'</div>' +
'<div style="clear: both"></div>' +
'</div>';
}
});
return {
View: UserAPIKeysView
};
});
+5
View File
@@ -1855,3 +1855,8 @@ div.toolTitleNoSection
visibility: visible;
opacity: 1;
}
/* For Vue */
[v-cloak] {
display:none;
}
+2 -1
View File
@@ -105,7 +105,8 @@ def paste_app_factory(global_conf, **kwargs):
webapp.add_client_route('/admin/repositories', 'admin')
webapp.add_client_route('/admin/tool_versions', 'admin')
webapp.add_client_route('/admin/quotas', 'admin')
webapp.add_client_route('/admin/form/{form_id}', 'admin')
webapp.add_client_route('/admin/forms/{form_id}', 'admin')
webapp.add_client_route('/admin/api_keys', 'admin')
webapp.add_client_route('/tours')
webapp.add_client_route('/tours/{tour_id}')
webapp.add_client_route('/user')
@@ -31,37 +31,29 @@ class User(BaseUIController, UsesFormDefinitionsMixin):
@web.require_login()
@web.require_admin
def index(self, trans, cntrller, **kwd):
return trans.fill_template('webapps/galaxy/user/list_users.mako', action='all_users', cntrller=cntrller)
return self.get_all_users( trans )
@web.expose
@web.require_login()
@web.require_admin
def admin_api_keys(self, trans, cntrller, uid, **kwd):
def admin_api_keys(self, trans, uid, **kwd):
params = util.Params(kwd)
message = escape(util.restore_text(params.get('message', '')))
status = params.get('status', 'done')
uid = params.get('uid', uid)
if params.get('new_api_key_button', False):
new_key = trans.app.model.APIKeys()
new_key.user_id = uid
new_key.key = trans.app.security.get_new_guid()
trans.sa_session.add(new_key)
trans.sa_session.flush()
message = "A new web API key has been generated for (%s)" % escape(new_key.user.email)
status = "done"
return trans.response.send_redirect(web.url_for(controller='userskeys',
action='all_users',
cntrller=cntrller,
message=message,
status=status))
new_key = trans.app.model.APIKeys()
new_key.user_id = trans.security.decode_id( uid )
new_key.key = trans.app.security.get_new_guid()
trans.sa_session.add(new_key)
trans.sa_session.flush()
return self.get_all_users( trans )
@web.expose
@web.require_login()
@web.require_admin
def all_users(self, trans, cntrller="userskeys", **kwd):
params = util.Params(kwd)
message = escape(util.restore_text(params.get('message', '')))
status = params.get('status', 'done')
def all_users(self, trans, **kwd):
return self.get_all_users( trans )
@web.json
def get_all_users( self, trans ):
users = []
for user in trans.sa_session.query(trans.app.model.User) \
.filter(trans.app.model.User.table.c.deleted == false()) \
@@ -71,9 +63,5 @@ class User(BaseUIController, UsesFormDefinitionsMixin):
for api_user in trans.sa_session.query(trans.app.model.APIKeys) \
.filter(trans.app.model.APIKeys.user_id == uid):
userkey = api_user.key
users.append({'uid': uid, 'email': user.email, 'key': userkey})
return trans.fill_template('webapps/galaxy/user/list_users.mako',
cntrller=cntrller,
users=users,
message=message,
status=status)
users.append({'uid': trans.security.encode_id( uid ), 'email': user.email, 'key': userkey})
return users
@@ -0,0 +1 @@
{"version":3,"sources":["mvc/user/user_api_keys.js"],"names":["define","Vue","mod_toastr","View","Backbone","extend","options","timeOut","UserAPIKeysView","initialize","render","self","this","url","Galaxy","root","empty","append","_template","fetchUsers","$","getJSON","users","setTimeout","applyVue","el","form_vue","data","generateKey","id","methods","uid","success","error","_data"],"mappings":"2DAAAA,QAAU,WAAY,eAAiB,SAAUC,EAAKC,GAmFlD,OACIC,KAlFkBC,SAASD,KAAKE,QAFxCL,WAAU,WAIEE,EAAWI,QAAQC,QAAU,IAFjCC,KAAAA,WAAAA,UACAC,KAAAA,UAGIC,OAAA,WACH,IALsCC,EAAAC,KAS/BC,EAAMC,OAAOC,KAAO,sBAF5BL,EAAAA,IAAQM,QAAAC,OAAAN,EAAWO,aACfP,EAAAQ,WAAWN,IAIdM,WAZsC,SAAAN,GAgBnC,IAAIF,EAAOC,KAFfQ,EAAAC,QAAAR,EAAA,SAAAS,GAIQC,WAAA,WACAZ,EAAAa,SAAAF,QAMPE,SAzBsC,SAAAF,GA6BpB,IAAIrB,GAFvBwB,GAAA,iBACAD,MACQE,MAAAA,GAEAC,SAAMC,YAFa,SAAAC,GAKnBC,IAAAA,EAASlB,KAELgB,EAAAA,MACIf,IAAIF,OAAOI,KAAX,2BACAY,MAAAI,IAAAF,GACAT,QAAO,SAAAE,GACHT,EAAKC,QAAc,qCAEnBkB,EAAAA,MAASV,MAAAA,GAELW,MAAA,WACAtB,EAAKuB,QAAMZ,4CAhBRJ,UAAvB,WAyBH,MAtDsC","file":"../../../scripts/mvc/user/user_api_keys.js","sourcesContent":["define( [ 'libs/vue', \"libs/toastr\" ], function( Vue, mod_toastr ) {\n\n var UserAPIKeysView = Backbone.View.extend({\n initialize: function() {\n mod_toastr.options.timeOut = 1000;\n this.setElement( '<div/>' );\n this.render();\n },\n\n render: function() {\n var self = this,\n url = Galaxy.root + 'userskeys/all_users';\n self.$el.empty().append( self._template() );\n self.fetchUsers( url );\n },\n\n /** Load users and their keys */\n fetchUsers: function( url ) {\n var self = this;\n $.getJSON( url, function( users ) {\n // apply vue model on the dom\n // timeout is used to ensure dom is created first and then\n // vue model is applied with the required data\n setTimeout(function() { \n self.applyVue( users );\n });\n });\n },\n\n /** Create model for the view using vue */\n applyVue: function( users ) {\n var form_vue = new Vue({\n el: '#form-userkeys',\n data: {\n users: users // data model\n },\n methods: {\n // bind event from view\n generateKey: function( id ) {\n var self = this;\n // fetch fresh model\n $.ajax({\n url: Galaxy.root + 'userskeys/admin_api_keys',\n data: { 'uid': id },\n success: function( users ) {\n mod_toastr.success(\"Successfully generated a user key\");\n // refresh the model\n self._data.users = users;\n },\n error: function( ) {\n mod_toastr.success(\"Error occured while loading data\");\n }\n });\n }\n }\n });\n },\n\n _template: function() {\n return '<div id=\"form-userkeys\" class=\"toolForm\" v-cloak>' +\n '<div class=\"toolFormTitle\">User Information</div>' +\n '<div v-if=\"users && users.length > 0\">' +\n '<table class=\"grid\">' +\n '<thead><th>Encoded UID</th><th>Email</th><th>API Key</th><th>Actions</th></thead>' +\n '<tbody>' +\n '<tr v-for=\"user in users\">' +\n '<td>' + '{{ user.uid }}' + '</td>' +\n '<td>' + '{{ user.email }}' + '</td>' +\n '<td>' + '{{ user.key }}' + '</td>' +\n '<td>' +\n '<input type=\"button\" value=\"Generate a new key now\" v-on:click=\"generateKey( user.uid )\" />' +\n '</td>' +\n '</tbody>' +\n '</table>' +\n '</div>' +\n '<div v-else>' +\n '<div>No informations available</div>' +\n '</div>' +\n '<div style=\"clear: both\"></div>' +\n '</div>';\n }\n });\n\n return {\n View: UserAPIKeysView\n };\n});\n"]}
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
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1,2 +1,2 @@
webpackJsonp([2],{116:function(e,t,i){"use strict";(function(e,t){function a(e){return e&&e.__esModule?e:{default:e}}var n=i(0),r=a(n),o=i(26),l=a(o),u=i(4),d=a(u),c=i(27),f=a(c),p=r.default;window.app=function(i,a){window.Galaxy=new l.default.GalaxyApp(i,a),Galaxy.debug("login app");var n=encodeURI(i.redirect);if(!i.show_welcome_with_login){var o=r.default.param({use_panels:"True",redirect:n});return void(window.location.href=Galaxy.root+"user/login?"+o)}var u=e.View.extend({initialize:function(t){this.page=t,this.model=new e.Model({title:(0,d.default)("Login required")}),this.setElement(this._template())},render:function(){this.page.$("#galaxy_main").prop("src",i.welcome_url)},_template:function(){return'<iframe src="'+i.root+"user/login?"+p.param({redirect:n})+'" frameborder="0" style="width: 100%; height: 100%;"/>'}});p(function(){Galaxy.page=new f.default.View(t.extend(i,{Right:u}))})}}).call(t,i(2),i(1))}},[116]);
webpackJsonp([2],{116:function(e,t,i){"use strict";(function(e,t){function a(e){return e&&e.__esModule?e:{default:e}}var n=i(0),r=a(n),o=i(27),l=a(o),u=i(4),d=a(u),c=i(28),f=a(c),p=r.default;window.app=function(i,a){window.Galaxy=new l.default.GalaxyApp(i,a),Galaxy.debug("login app");var n=encodeURI(i.redirect);if(!i.show_welcome_with_login){var o=r.default.param({use_panels:"True",redirect:n});return void(window.location.href=Galaxy.root+"user/login?"+o)}var u=e.View.extend({initialize:function(t){this.page=t,this.model=new e.Model({title:(0,d.default)("Login required")}),this.setElement(this._template())},render:function(){this.page.$("#galaxy_main").prop("src",i.welcome_url)},_template:function(){return'<iframe src="'+i.root+"user/login?"+p.param({redirect:n})+'" frameborder="0" style="width: 100%; height: 100%;"/>'}});p(function(){Galaxy.page=new f.default.View(t.extend(i,{Right:u}))})}}).call(t,i(2),i(1))}},[116]);
//# sourceMappingURL=login.bundled.js.map
File diff suppressed because one or more lines are too long
+2
View File
@@ -0,0 +1,2 @@
define("mvc/user/user_api_keys",[],function(){"use strict";define(["libs/vue","libs/toastr"],function(e,t){return{View:Backbone.View.extend({initialize:function(){t.options.timeOut=1e3,this.setElement("<div/>"),this.render()},render:function(){var e=this,t=Galaxy.root+"userskeys/all_users";e.$el.empty().append(e._template()),e.fetchUsers(t)},fetchUsers:function(e){var t=this;$.getJSON(e,function(e){setTimeout(function(){t.applyVue(e)})})},applyVue:function(s){new e({el:"#form-userkeys",data:{users:s},methods:{generateKey:function(e){var s=this;$.ajax({url:Galaxy.root+"userskeys/admin_api_keys",data:{uid:e},success:function(e){t.success("Successfully generated a user key"),s._data.users=e},error:function(){t.success("Error occured while loading data")}})}}})},_template:function(){return'<div id="form-userkeys" class="toolForm" v-cloak><div class="toolFormTitle">User Information</div><div v-if="users && users.length > 0"><table class="grid"><thead><th>Encoded UID</th><th>Email</th><th>API Key</th><th>Actions</th></thead><tbody><tr v-for="user in users"><td>{{ user.uid }}</td><td>{{ user.email }}</td><td>{{ user.key }}</td><td><input type="button" value="Generate a new key now" v-on:click="generateKey( user.uid )" /></td></tbody></table></div><div v-else><div>No informations available</div></div><div style="clear: both"></div></div>'}})}})});
//# sourceMappingURL=../../../maps/mvc/user/user_api_keys.js.map
File diff suppressed because one or more lines are too long
@@ -1,38 +0,0 @@
<%inherit file="/base.mako"/>
<%namespace file="/message.mako" import="render_msg" />
%if message:
${render_msg( message, status )}
%endif
%if users:
<div class="toolForm">
<div class="toolFormTitle">User Information</div>
<table class="grid">
<thead><th>UID</th><th>email</th><th>API Key</th><th>Actions</th></thead>
<tbody>
%for user in users:
<tr>
<td>${user['uid']}</td>
<td>${user['email']}</td>
<td>${user['key']}</td>
<td>
<form action="${h.url_for( controller='userskeys', action='admin_api_keys', cntrller=cntrller )}" method="POST">
<input type="hidden" name="uid" value=${user['uid']} />
<input type="submit" name="new_api_key_button" value="Generate a new key now" />
</form>
</td>
</tr>
%endfor
</tbody>
</table>
<div style="clear: both"></div>
</div>
%else:
<div>No informations available</div>
%endif
<p/>