Remove some more references to 'newgrids' / old MasterView

This commit is contained in:
Lance Edgar 2017-07-14 19:20:19 -05:00
parent 172efe2ab9
commit 52c7f485ab
9 changed files with 134 additions and 145 deletions

View file

@ -51,7 +51,7 @@ class Grid(object):
Core grid class. In sore need of documentation. Core grid class. In sore need of documentation.
""" """
def __init__(self, key, data, columns, width='auto', request=None, mobile=False, model_class=None, def __init__(self, key, data, columns=None, width='auto', request=None, mobile=False, model_class=None,
enums={}, labels={}, renderers={}, extra_row_class=None, linked_columns=[], url='#', enums={}, labels={}, renderers={}, extra_row_class=None, linked_columns=[], url='#',
joiners={}, filterable=False, filters={}, joiners={}, filterable=False, filters={},
sortable=False, sorters={}, default_sortkey=None, default_sortdir='asc', sortable=False, sorters={}, default_sortkey=None, default_sortdir='asc',
@ -66,6 +66,8 @@ class Grid(object):
self.request = request self.request = request
self.mobile = mobile self.mobile = mobile
self.model_class = model_class self.model_class = model_class
if self.model_class and self.columns is None:
self.columns = self.make_columns()
self.enums = enums or {} self.enums = enums or {}
self.labels = labels or {} self.labels = labels or {}
@ -93,6 +95,16 @@ class Grid(object):
self._whgrid_kwargs = kwargs self._whgrid_kwargs = kwargs
def make_columns(self):
"""
Return a default list of columns, based on :attr:`model_class`.
"""
if not self.model_class:
raise ValueError("Must define model_class to use make_columns()")
mapper = orm.class_mapper(self.model_class)
return [prop.key for prop in mapper.iterate_properties]
def hide_column(self, key): def hide_column(self, key):
if key in self.columns: if key in self.columns:
self.columns.remove(key) self.columns.remove(key)

View file

@ -1,8 +1,8 @@
## -*- coding: utf-8 -*- ## -*- coding: utf-8; -*-
<%inherit file="/master/view.mako" /> <%inherit file="/master/view.mako" />
<%def name="head_tags()"> <%def name="extra_styles()">
${parent.head_tags()} ${parent.extra_styles()}
${h.stylesheet_link(request.static_url('tailbone:static/css/perms.css'))} ${h.stylesheet_link(request.static_url('tailbone:static/css/perms.css'))}
</%def> </%def>

View file

@ -28,7 +28,7 @@ from __future__ import unicode_literals, absolute_import
from rattail.db import model from rattail.db import model
from tailbone.views import MasterView from tailbone.views import MasterView2 as MasterView
class CategoriesView(MasterView): class CategoriesView(MasterView):
@ -39,18 +39,18 @@ class CategoriesView(MasterView):
model_title_plural = "Categories" model_title_plural = "Categories"
route_prefix = 'categories' route_prefix = 'categories'
grid_columns = [
'code',
'number',
'name',
'department',
]
def configure_grid(self, g): def configure_grid(self, g):
super(CategoriesView, self).configure_grid(g)
g.filters['name'].default_active = True g.filters['name'].default_active = True
g.filters['name'].default_verb = 'contains' g.filters['name'].default_verb = 'contains'
g.default_sortkey = 'code' g.default_sortkey = 'code'
g.configure(
include=[
g.code,
g.number,
g.name,
g.department,
],
readonly=True)
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.configure( fs.configure(

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
@ -36,7 +36,8 @@ from rattail.time import localtime
import formalchemy as fa import formalchemy as fa
from tailbone import forms from tailbone import forms
from tailbone.views import MasterView from tailbone.views import MasterView2 as MasterView
from tailbone.util import raw_datetime
class CustomerOrderItemsView(MasterView): class CustomerOrderItemsView(MasterView):
@ -50,6 +51,18 @@ class CustomerOrderItemsView(MasterView):
editable = False editable = False
deletable = False deletable = False
grid_columns = [
'person',
'product_brand',
'product_description',
'product_size',
'case_quantity',
'cases_ordered',
'units_ordered',
'order_created',
'status_code',
]
has_rows = True has_rows = True
model_row_class = model.CustomerOrderItemEvent model_row_class = model.CustomerOrderItemEvent
rows_title = "Event History" rows_title = "Event History"
@ -58,61 +71,53 @@ class CustomerOrderItemsView(MasterView):
rows_pageable = False rows_pageable = False
rows_viewable = False rows_viewable = False
row_grid_columns = [
'occurred',
'type_code',
'user',
'note',
]
def query(self, session): def query(self, session):
return session.query(model.CustomerOrderItem)\ return session.query(model.CustomerOrderItem)\
.join(model.CustomerOrder)\ .join(model.CustomerOrder)\
.options(orm.joinedload(model.CustomerOrderItem.order)\ .options(orm.joinedload(model.CustomerOrderItem.order)\
.joinedload(model.CustomerOrder.person)) .joinedload(model.CustomerOrder.person))
def _preconfigure_grid(self, g): def configure_grid(self, g):
super(CustomerOrderItemsView, self).configure_grid(g)
g.joiners['person'] = lambda q: q.outerjoin(model.Person) g.set_joiner('person', lambda q: q.outerjoin(model.Person))
g.filters['person'] = g.make_filter('person', model.Person.display_name, label="Person Name",
g.filters['person'] = g.make_filter('person', model.Person.display_name,
default_active=True, default_verb='contains') default_active=True, default_verb='contains')
g.sorters['person'] = g.make_sorter(model.Person.display_name)
g.filters['product_brand'].label = "Brand" g.set_sorter('person', model.Person.display_name)
g.product_brand.set(label="Brand") g.set_sorter('order_created', model.CustomerOrder.created)
g.filters['product_description'].label = "Description"
g.product_description.set(label="Description")
g.filters['product_size'].label = "Size"
g.product_size.set(label="Size")
g.case_quantity.set(renderer=forms.renderers.QuantityFieldRenderer)
g.cases_ordered.set(renderer=forms.renderers.QuantityFieldRenderer)
g.units_ordered.set(renderer=forms.renderers.QuantityFieldRenderer)
g.total_price.set(renderer=forms.renderers.CurrencyFieldRenderer)
g.filters['status_code'].label = "Status"
g.status_code.set(label="Status")
g.append(fa.Field('person', value=lambda i: i.order.person))
g.sorters['order_created'] = g.make_sorter(model.CustomerOrder.created)
g.append(fa.Field('order_created',
value=lambda i: localtime(self.rattail_config, i.order.created, from_utc=True),
renderer=forms.renderers.DateTimeFieldRenderer))
g.default_sortkey = 'order_created' g.default_sortkey = 'order_created'
g.default_sortdir = 'desc' g.default_sortdir = 'desc'
def configure_grid(self, g): g.set_type('case_quantity', 'quantity')
g.configure( g.set_type('cases_ordered', 'quantity')
include=[ g.set_type('units_ordered', 'quantity')
g.person, g.set_type('total_price', 'currency')
g.product_brand,
g.product_description, g.set_renderer('person', self.render_person)
g.product_size, g.set_renderer('order_created', self.render_order_created)
g.case_quantity,
g.cases_ordered, g.set_label('person', "Person Name")
g.units_ordered, g.set_label('product_brand', "Brand")
g.order_created, g.set_label('product_description', "Description")
g.status_code, g.set_label('product_size', "Size")
], g.set_label('status_code', "Status")
readonly=True)
def render_person(self, item, column):
return item.order.person
def render_order_created(self, item, column):
value = localtime(self.rattail_config, item.order.created, from_utc=True)
return raw_datetime(self.rattail_config, value)
def _preconfigure_fieldset(self, fs): def _preconfigure_fieldset(self, fs):
fs.order.set(renderer=forms.renderers.CustomerOrderFieldRenderer) fs.order.set(renderer=forms.renderers.CustomerOrderFieldRenderer)
@ -151,21 +156,12 @@ class CustomerOrderItemsView(MasterView):
.order_by(model.CustomerOrderItemEvent.occurred, .order_by(model.CustomerOrderItemEvent.occurred,
model.CustomerOrderItemEvent.type_code) model.CustomerOrderItemEvent.type_code)
def _preconfigure_row_grid(self, g):
g.occurred.set(label="When")
g.type_code.set(label="What") # TODO: enum renderer
g.user.set(label="Who")
g.note.set(label="Notes")
def configure_row_grid(self, g): def configure_row_grid(self, g):
g.configure( super(CustomerOrderItemsView, self).configure_row_grid(g)
include=[ g.set_label('occurred', "When")
g.occurred, g.set_label('type_code', "What") # TODO: enum renderer
g.type_code, g.set_label('user', "Who")
g.user, g.set_label('note', "Notes")
g.note,
],
readonly=True)
def includeme(config): def includeme(config):

View file

@ -32,7 +32,7 @@ from rattail.db import model
from tailbone import forms from tailbone import forms
from tailbone.db import Session from tailbone.db import Session
from tailbone.views import MasterView from tailbone.views import MasterView2 as MasterView
class CustomerOrdersView(MasterView): class CustomerOrdersView(MasterView):
@ -45,43 +45,42 @@ class CustomerOrdersView(MasterView):
editable = False editable = False
deletable = False deletable = False
grid_columns = [
'id',
'customer',
'person',
'created',
'status_code',
]
def query(self, session): def query(self, session):
return session.query(model.CustomerOrder)\ return session.query(model.CustomerOrder)\
.options(orm.joinedload(model.CustomerOrder.customer)) .options(orm.joinedload(model.CustomerOrder.customer))
def _preconfigure_grid(self, g): def configure_grid(self, g):
g.joiners['customer'] = lambda q: q.outerjoin(model.Customer) super(CustomerOrdersView, self).configure_grid(g)
g.sorters['customer'] = g.make_sorter(model.Customer.name)
g.set_joiner('customer', lambda q: q.outerjoin(model.Customer))
g.set_joiner('person', lambda q: q.outerjoin(model.Person))
g.filters['customer'] = g.make_filter('customer', model.Customer.name, g.filters['customer'] = g.make_filter('customer', model.Customer.name,
label="Customer Name", label="Customer Name",
default_active=True, default_active=True,
default_verb='contains') default_verb='contains')
g.joiners['person'] = lambda q: q.outerjoin(model.Person)
g.sorters['person'] = g.make_sorter(model.Person.display_name)
g.filters['person'] = g.make_filter('person', model.Person.display_name, g.filters['person'] = g.make_filter('person', model.Person.display_name,
label="Person Name", label="Person Name",
default_active=True, default_active=True,
default_verb='contains') default_verb='contains')
# TODO: enum choices renderer g.set_sorter('customer', model.Customer.name)
g.filters['status_code'].label = "Status" g.set_sorter('person', model.Person.display_name)
g.status_code.set(label="Status")
g.id.set(label="ID")
g.default_sortkey = 'created' g.default_sortkey = 'created'
g.default_sortdir = 'desc' g.default_sortdir = 'desc'
def configure_grid(self, g): # TODO: enum choices renderer
g.configure( g.set_label('status_code', "Status")
include=[ g.set_label('id', "ID")
g.id,
g.customer,
g.person,
g.created,
g.status_code,
],
readonly=True)
def _preconfigure_fieldset(self, fs): def _preconfigure_fieldset(self, fs):
fs.customer.set(options=[]) fs.customer.set(options=[])

View file

@ -26,10 +26,11 @@ Department Views
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import six
from rattail.db import model from rattail.db import model
from tailbone import grids3 as grids from tailbone import grids3 as grids
from tailbone.newgrids import AlchemyGrid
from tailbone.views import MasterView2 as MasterView, AutocompleteView from tailbone.views import MasterView2 as MasterView, AutocompleteView
@ -61,21 +62,13 @@ class DepartmentsView(MasterView):
def template_kwargs_view(self, **kwargs): def template_kwargs_view(self, **kwargs):
department = kwargs['instance'] department = kwargs['instance']
if department.employees: if department.employees:
employees = sorted(department.employees, key=six.text_type)
# TODO: This is the second attempt (after role.users) at using a actions = [
# new grid outside of the context of a primary master grid. The
# API here is really much hairier than I'd like... Looks like we
# shouldn't need a key for this one, for instance (no settings
# required), but there is plenty of room for improvement here.
employees = sorted(department.employees, key=unicode)
employees = AlchemyGrid('departments.employees', self.request, data=employees, model_class=model.Employee,
main_actions=[
grids.GridAction('view', icon='zoomin', grids.GridAction('view', icon='zoomin',
url=lambda r, i: self.request.route_url('employees.view', uuid=r.uuid)), url=lambda r, i: self.request.route_url('employees.view', uuid=r.uuid))
]) ]
employees.configure(include=[employees.display_name], readonly=True) kwargs['employees'] = grids.Grid(None, employees, ['display_name'], request=self.request,
kwargs['employees'] = employees model_class=model.Employee, main_actions=actions)
else: else:
kwargs['employees'] = None kwargs['employees'] = None
return kwargs return kwargs

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
@ -29,7 +29,7 @@ from __future__ import unicode_literals, absolute_import
from rattail.db import model from rattail.db import model
from tailbone import forms from tailbone import forms
from tailbone.views import MasterView from tailbone.views import MasterView2 as MasterView
class DepositLinksView(MasterView): class DepositLinksView(MasterView):
@ -39,20 +39,18 @@ class DepositLinksView(MasterView):
model_class = model.DepositLink model_class = model.DepositLink
url_prefix = '/deposit-links' url_prefix = '/deposit-links'
def _preconfigure_grid(self, g): grid_columns = [
'code',
'description',
'amount',
]
def configure_grid(self, g):
super(DepositLinksView, self).configure_grid(g)
g.filters['description'].default_active = True g.filters['description'].default_active = True
g.filters['description'].default_verb = 'contains' g.filters['description'].default_verb = 'contains'
g.default_sortkey = 'code' g.default_sortkey = 'code'
g.amount.set(renderer=forms.renderers.CurrencyFieldRenderer) g.set_type('amount', 'currency')
def configure_grid(self, g):
g.configure(
include=[
g.code,
g.description,
g.amount,
],
readonly=True)
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.configure( fs.configure(

View file

@ -36,7 +36,6 @@ from formalchemy.fields import IntegerFieldRenderer
from tailbone import forms, grids3 as grids from tailbone import forms, grids3 as grids
from tailbone.db import Session from tailbone.db import Session
from tailbone.newgrids import AlchemyGrid
from tailbone.views.principal import PrincipalMasterView from tailbone.views.principal import PrincipalMasterView
@ -76,21 +75,13 @@ class RolesView(PrincipalMasterView):
def template_kwargs_view(self, **kwargs): def template_kwargs_view(self, **kwargs):
role = kwargs['instance'] role = kwargs['instance']
if role.users: if role.users:
# TODO: This is the first attempt at using a new grid outside of
# the context of a primary master grid. The API here is really
# much hairier than I'd like... Looks like we shouldn't need a key
# for this one, for instance (no settings required), but there is
# plenty of room for improvement here.
users = sorted(role.users, key=lambda u: u.username) users = sorted(role.users, key=lambda u: u.username)
users = AlchemyGrid('roles.users', self.request, data=users, model_class=model.User, actions = [
main_actions=[
grids.GridAction('view', icon='zoomin', grids.GridAction('view', icon='zoomin',
url=lambda r, i: self.request.route_url('users.view', uuid=r.uuid)), url=lambda r, i: self.request.route_url('users.view', uuid=r.uuid))
]) ]
users.configure(include=[users.username], readonly=True) kwargs['users'] = grids.Grid(None, users, ['username'], request=self.request, model_class=model.User,
kwargs['users'] = users main_actions=actions)
else: else:
kwargs['users'] = None kwargs['users'] = None
kwargs['guest_role'] = guest_role(Session()) kwargs['guest_role'] = guest_role(Session())

View file

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8; -*-
################################################################################ ################################################################################
# #
# Rattail -- Retail Software Framework # Rattail -- Retail Software Framework
@ -28,7 +28,7 @@ from __future__ import unicode_literals, absolute_import
from rattail.db import model from rattail.db import model
from tailbone.views import MasterView from tailbone.views import MasterView2 as MasterView
class TaxesView(MasterView): class TaxesView(MasterView):
@ -39,17 +39,17 @@ class TaxesView(MasterView):
model_title_plural = "Taxes" model_title_plural = "Taxes"
route_prefix = 'taxes' route_prefix = 'taxes'
grid_columns = [
'code',
'description',
'rate',
]
def configure_grid(self, g): def configure_grid(self, g):
super(TaxesView, self).configure_grid(g)
g.filters['description'].default_active = True g.filters['description'].default_active = True
g.filters['description'].default_verb = 'contains' g.filters['description'].default_verb = 'contains'
g.default_sortkey = 'code' g.default_sortkey = 'code'
g.configure(
include=[
g.code,
g.description,
g.rate,
],
readonly=True)
def configure_fieldset(self, fs): def configure_fieldset(self, fs):
fs.configure( fs.configure(