Add very basic Vue.js grid/index experiment for Users table

This commit is contained in:
Lance Edgar 2018-11-26 22:07:30 -06:00
parent 25e61cc8d5
commit 993d8c3b4e
4 changed files with 137 additions and 0 deletions

View file

@ -47,3 +47,8 @@ class ConfigExtension(BaseExtension):
def configure(self, config): def configure(self, config):
Session.configure(rattail_config=config) Session.configure(rattail_config=config)
configure_session(config, Session) configure_session(config, Session)
def expose_vuejs_experiments(config):
return config.getbool('tailbone', 'expose_vuejs_experiments',
default=False)

View file

@ -0,0 +1,11 @@
## -*- coding: utf-8; -*-
<%inherit file="/principal/index.mako" />
<%def name="context_menu_items()">
${parent.context_menu_items()}
% if expose_vuejs_experiments:
<li>${h.link_to("Vue.js Index", url('{}.vue_index'.format(route_prefix)))}</li>
% endif
</%def>
${parent.body()}

View file

@ -0,0 +1,95 @@
## -*- coding: utf-8; -*-
<%inherit file="/users/index.mako" />
<%def name="extra_javascript()">
${parent.extra_javascript()}
<!-- vue -->
${h.javascript_link('https://cdn.jsdelivr.net/npm/vue')}
<!-- vuex -->
${h.javascript_link('https://unpkg.com/vuex')}
<!-- vue-tables-2 -->
${h.javascript_link('https://cdn.jsdelivr.net/npm/vue-tables-2@1.4.70/dist/vue-tables-2.min.js')}
<!-- bulma -->
${h.stylesheet_link('https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css')}
## <style type="text/css">
## /* workaround for header logo */
## .home img { height: 49px; }
## </style>
</%def>
## TODO: just, ugh.
<br /><br /><br />
<div id="vue-app">
## TODO: need to make endpoint a bit more configurable somehow
<v-server-table name="users" url="/api/users" :columns="columns" :options="options"></v-server-table>
</div>
<script type="text/javascript">
// Vue.use(Vuex);
var store = new Vuex.Store({
// state: {
// appVersion: null,
// // TODO: is this really needed or can we just always check appsettings?
// production: appsettings.production,
// user: null,
// pageTitle: null
// },
// mutations: {
// setAppVersion(state, payload) {
// state.appVersion = payload;
// },
// setPageTitle(state, payload) {
// state.pageTitle = payload;
// },
// setUser(state, payload) {
// state.user = payload;
// }
// },
// actions: {
// }
})
Vue.use(VueTables.ServerTable, {}, true, 'bulma', 'default');
var app = new Vue({
el: '#vue-app',
store: store,
data: {
columns: [
'username',
'person'
],
options: {
filterable: false,
sortable: [
'username'// ,
// TODO: add sort for Person.display_name
// 'person'
],
orderBy: {
column: 'username',
ascending: true
},
perPageValues: [10, 25, 50, 100, 200],
// preserveState: true,
saveState: true,
// TODO: why doesn't local storage work? but alas, table does not
// properly submit the 'orderBy' param, and results aren't paginated
storage: 'session'
}
}
});
// $.get('/api/users', {sort: 'username|desc', page: 1, per_page: 10}, function(data) {
// app.users = data.users;
// });
</script>

View file

@ -42,6 +42,7 @@ from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView from tailbone.views import MasterView
from tailbone.views.principal import PrincipalMasterView, PermissionsRenderer from tailbone.views.principal import PrincipalMasterView, PermissionsRenderer
from tailbone.config import expose_vuejs_experiments
class UsersView(PrincipalMasterView): class UsersView(PrincipalMasterView):
@ -124,6 +125,16 @@ class UsersView(PrincipalMasterView):
g.set_link('last_name') g.set_link('last_name')
g.set_link('display_name') g.set_link('display_name')
def template_kwargs_index(self, **kwargs):
kwargs['expose_vuejs_experiments'] = expose_vuejs_experiments(self.rattail_config)
return kwargs
def vue_index(self):
if not expose_vuejs_experiments(self.rattail_config):
raise self.notfound()
return self.render_to_response('vue_index', {})
def unique_username(self, node, value): def unique_username(self, node, value):
query = self.Session.query(model.User)\ query = self.Session.query(model.User)\
.filter(model.User.username == value) .filter(model.User.username == value)
@ -308,6 +319,21 @@ class UsersView(PrincipalMasterView):
assert not removing._roles assert not removing._roles
self.Session.delete(removing) self.Session.delete(removing)
@classmethod
def defaults(cls, config):
rattail_config = config.registry.settings.get('rattail_config')
route_prefix = cls.get_route_prefix()
url_prefix = cls.get_url_prefix()
permission_prefix = cls.get_permission_prefix()
# vue-index
config.add_route('{}.vue_index'.format(route_prefix), '{}/vue-index/'.format(url_prefix))
config.add_view(cls, attr='vue_index', route_name='{}.vue_index'.format(route_prefix),
permission='{}.list'.format(permission_prefix))
cls._principal_defaults(config)
cls._defaults(config)
class UserEventsView(MasterView): class UserEventsView(MasterView):
""" """