From 26ffcc865a00954564bfe162dba332308934bc73 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 14 Aug 2012 13:28:39 -0700 Subject: [PATCH] more template/css overhaul --- edbob/pyramid/grids/core.py | 69 +++--- edbob/pyramid/grids/search.py | 6 +- edbob/pyramid/static/css/crud.css | 98 -------- edbob/pyramid/static/css/edbob.css | 229 +----------------- edbob/pyramid/static/css/filters.css | 24 ++ edbob/pyramid/static/css/forms.css | 70 ++++++ edbob/pyramid/static/css/grids.css | 150 ++++++++++++ edbob/pyramid/static/css/index.css | 165 ------------- edbob/pyramid/static/js/edbob.js | 11 +- edbob/pyramid/templates/crud.mako | 1 + edbob/pyramid/templates/edbob/base.mako | 5 +- edbob/pyramid/templates/edbob/crud.mako | 19 +- .../templates/edbob/{index.mako => grid.mako} | 13 +- edbob/pyramid/templates/grid.mako | 3 + edbob/pyramid/templates/grids/grid.mako | 2 +- edbob/pyramid/templates/index.mako | 2 - edbob/pyramid/views/crud.py | 2 + edbob/pyramid/views/grids/alchemy.py | 12 +- edbob/pyramid/views/grids/core.py | 6 + edbob/pyramid/views/users.py | 30 +-- 20 files changed, 337 insertions(+), 580 deletions(-) delete mode 100644 edbob/pyramid/static/css/crud.css create mode 100644 edbob/pyramid/static/css/filters.css create mode 100644 edbob/pyramid/static/css/forms.css create mode 100644 edbob/pyramid/static/css/grids.css delete mode 100644 edbob/pyramid/static/css/index.css rename edbob/pyramid/templates/edbob/{index.mako => grid.mako} (70%) create mode 100644 edbob/pyramid/templates/grid.mako delete mode 100644 edbob/pyramid/templates/index.mako diff --git a/edbob/pyramid/grids/core.py b/edbob/pyramid/grids/core.py index 290e8f6..f1de01a 100644 --- a/edbob/pyramid/grids/core.py +++ b/edbob/pyramid/grids/core.py @@ -44,13 +44,19 @@ __all__ = ['Grid'] class Grid(edbob.Object): + full = False hoverable = True clickable = False checkboxes = False deletable = False + partial_only = False - row_route_name = None - row_route_kwargs = None + + click_route_name = None + click_route_kwargs = None + + delete_route_name = None + delete_route_kwargs = None def __init__(self, request, **kwargs): kwargs.setdefault('fields', OrderedDict()) @@ -65,23 +71,38 @@ class Grid(edbob.Object): def column_header(self, field): return literal('%s' % (field.name, field.label)) - def div_class(self): - if self.clickable: - return 'grid clickable' - if self.hoverable: - return 'grid hoverable' - return 'grid' - - def _div_attrs(self): - attrs = {'class_':'grid', 'url':self.request.current_route_url()} - if self.clickable: - attrs['class_'] = 'grid clickable' - elif self.hoverable: - attrs['class_'] = 'grid hoverable' - return attrs - def div_attrs(self): - return format_attrs(**self._div_attrs()) + classes = ['grid'] + if self.full: + classes.append('full') + if self.clickable: + classes.append('clickable') + if self.hoverable: + classes.append('hoverable') + return format_attrs( + class_=' '.join(classes), + url=self.request.current_route_url()) + + def get_delete_url(self, row): + kwargs = {} + if self.delete_route_kwargs: + if callable(self.delete_route_kwargs): + kwargs = self.delete_route_kwargs(row) + else: + kwargs = self.delete_route_kwargs + return self.request.route_url(self.delete_route_name, **kwargs) + + def get_row_attrs(self, row, i): + attrs = self.row_attrs(row, i) + if self.clickable: + kwargs = {} + if self.click_route_kwargs: + if callable(self.click_route_kwargs): + kwargs = self.click_route_kwargs(row) + else: + kwargs = self.click_route_kwargs + attrs['url'] = self.request.route_url(self.click_route_name, **kwargs) + return format_attrs(**attrs) def iter_fields(self): return self.fields.itervalues() @@ -99,15 +120,3 @@ class Grid(edbob.Object): def row_attrs(self, row, i): attrs = {'class_': 'odd' if i % 2 else 'even'} return attrs - - def get_row_attrs(self, row, i): - attrs = self.row_attrs(row, i) - if self.row_route_name: - kwargs = {} - if self.row_route_kwargs: - if callable(self.row_route_kwargs): - kwargs = self.row_route_kwargs(row) - else: - kwargs = self.row_route_kwargs - attrs['url'] = self.request.route_url(self.row_route_name, **kwargs) - return format_attrs(**attrs) diff --git a/edbob/pyramid/grids/search.py b/edbob/pyramid/grids/search.py index 4e92fcd..e318d7e 100644 --- a/edbob/pyramid/grids/search.py +++ b/edbob/pyramid/grids/search.py @@ -159,7 +159,7 @@ def filter_ilike(field): return {'lk': ilike, 'nl': not_ilike} -def get_filter_config(name, request, filter_map, **kwargs): +def get_filter_config(prefix, request, filter_map, **kwargs): """ Returns a configuration dictionary for a search form. """ @@ -191,7 +191,7 @@ def get_filter_config(name, request, filter_map, **kwargs): config.update(kwargs) # Update config with data cached in session. - update_config(request.session, prefix=name+'.') + update_config(request.session, prefix=prefix+'.') # Update config with data from GET/POST request. if request.params.get('filters') == 'true': @@ -201,7 +201,7 @@ def get_filter_config(name, request, filter_map, **kwargs): for key in config: if (not key.startswith('filter_factory_') and not key.startswith('filter_label_')): - request.session[name+'.'+key] = config[key] + request.session[prefix+'.'+key] = config[key] return config diff --git a/edbob/pyramid/static/css/crud.css b/edbob/pyramid/static/css/crud.css deleted file mode 100644 index 671227b..0000000 --- a/edbob/pyramid/static/css/crud.css +++ /dev/null @@ -1,98 +0,0 @@ - -/************************************************************ - * crud.css - * - * Styles specific to "object CRUD" pages. - ************************************************************/ - - -/****************************** - * Wrapper - ******************************/ - -div.crud { - font-size: 10pt; - margin: auto; -} - - -/****************************** - * Context Menu - ******************************/ - -div.crud #context-menu { - float: right; - list-style-type: none; -} - - -/****************************** - * Fieldsets - ******************************/ - -/* div.crud div.field-couple { */ -/* clear: both; */ -/* overflow: auto; */ -/* min-height: 30px; */ -/* } */ - -/* /\* div.crud div.field-couple div.label, *\/ */ -/* div.crud div.field-couple label { */ -/* display: block; */ -/* float: left; */ -/* width: 140px; */ -/* font-weight: bold; */ -/* margin-top: 2px; */ -/* white-space: nowrap; */ -/* } */ - -/* div.crud div.field-couple div.field { */ -/* display: block; */ -/* float: left; */ -/* margin-bottom: 5px; */ -/* line-height: 25px; */ -/* } */ - -/* div.crud div.field-couple div.field input[type=text], */ -/* div.crud div.field-couple div.field input[type=password], */ -/* div.crud div.field-couple div.field select { */ -/* width: 320px; */ -/* } */ - -/* unbound checkbox field, e.g. 'add another' */ -div.crud div.checkbox { - margin: 10px 0px; - padding-left: 3px; -} - -/* div.crud div.buttons { */ -/* clear: both; */ -/* margin-top: 10px; */ -/* } */ - -/* div.crud div.buttons * { */ -/* margin-right: 8px; */ -/* } */ - -/* div.crud table.fieldset tbody tr { */ -/* vertical-align: top; */ -/* } */ - -/* div.crud table.fieldset tbody td { */ -/* height: 30px; */ -/* padding: 2px; */ -/* } */ - -/* div.crud table.fieldset td.label { */ -/* font-weight: bold; */ -/* width: 120px; */ -/* } */ - -/* div.crud table.fieldset tbody td ul { */ -/* padding-left: 15px; */ -/* } */ - -/* div.crud table.fieldset tbody td ul li { */ -/* line-height: 1em; */ -/* margin-bottom: 4px; */ -/* } */ diff --git a/edbob/pyramid/static/css/edbob.css b/edbob/pyramid/static/css/edbob.css index 0afce70..dbaa538 100644 --- a/edbob/pyramid/static/css/edbob.css +++ b/edbob/pyramid/static/css/edbob.css @@ -9,7 +9,6 @@ html, body { font-family: sans-serif; - font-size: .9em; } a { @@ -28,11 +27,6 @@ li { overflow: auto; } -table.wrapper { - /* border: 1px solid black; */ - width: 100%; -} - .left { float: left; text-align: left; @@ -169,30 +163,6 @@ div.controls label { } -/****************************** - * Header Table - ******************************/ - -table.header { - padding-bottom: 5px; - width: 100%; -} - -table.header td.context-menu { - vertical-align: top; -} - -table.header td.context-menu ul { - list-style-type: none; - text-align: right; -} - -table.header td.tools { - text-align: right; - vertical-align: bottom; -} - - /****************************** * Dialogs ******************************/ @@ -201,200 +171,7 @@ div.dialog { display: none; } -#feedback-dialog textarea { - height: 180px; - width: 500px; -} - - -/****************************** - * Filters - ******************************/ - -div.filters div.filter div.value { - display: inline; -} - - -/****************************** - * Grids - ******************************/ - -div.grid { - clear: both; -} - -div.grid table { - border-top: 1px solid black; - border-left: 1px solid black; - border-collapse: collapse; - font-size: 9pt; - line-height: normal; - white-space: nowrap; -} - -div.grid.full table { - width: 100%; -} - -div.grid table th, -div.grid table td { - border-right: 1px solid black; - border-bottom: 1px solid black; - padding: 2px 3px; -} - -div.grid table th.sortable a { - display: block; - padding-right: 18px; -} - -div.grid table th.sorted { - background-position: right center; - background-repeat: no-repeat; -} - -div.grid table th.sorted.asc { - background-image: url(../img/sort_arrow_up.png); -} - -div.grid table th.sorted.desc { - background-image: url(../img/sort_arrow_down.png); -} - -div.grid table tbody td { - text-align: left; -} - -div.grid table tbody td.right { - text-align: right; -} - -div.grid table tr.odd { - background-color: #e0e0e0; -} - -/* div.grid table thead th.checkbox, */ -/* div.grid table tbody td.checkbox { */ -/* text-align: center; */ -/* vertical-align: middle; */ -/* width: 15px; */ +/* #feedback-dialog textarea { */ +/* height: 180px; */ +/* width: 500px; */ /* } */ - -/* div.grid table td.action { */ -/* cursor: default; */ -/* } */ - -div.grid table td.delete { - text-align: center; - width: 18px; - background-image: url(../img/delete.png); - background-repeat: no-repeat; - background-position: center; - cursor: pointer; -} - -div.grid table tbody tr.hovering { - background-color: #bbbbbb; -} - -div.grid table.hoverable tbody tr { - cursor: default; -} - -div.grid.clickable table tbody tr, -div.grid table.selectable tbody tr, -div.grid table.checkable tbody tr { - cursor: pointer; -} - -/* div.grid table.selectable tbody tr.selected, */ -/* div.grid table.checkable tbody tr.selected { */ -/* background-color: #666666; */ -/* color: white; */ -/* } */ - -div.pager { - margin-top: 5px; -} - -div.pager p { - font-size: 10pt; - margin: 0px; -} - -div.pager p.showing { - float: left; -} - -div.pager #grid-page-count { - font-size: 8pt; -} - -div.pager p.page-links { - float: right; -} - - -/* /\****************************** */ -/* * Sub-Grids */ -/* ******************************\/ */ - -/* div.subgrid { */ -/* margin-top: 20px; */ -/* } */ - -/* div.subgrid label { */ -/* font-weight: bold; */ -/* display: block; */ -/* float: left; */ -/* margin-bottom: 5px; */ -/* } */ - - -/****************************** - * Fieldsets - ******************************/ - -div.field-wrapper { - clear: both; - overflow: auto; - min-height: 30px; -} - -div.field-wrapper label { - display: block; - float: left; - width: 140px; - font-weight: bold; - margin-top: 2px; - white-space: nowrap; -} - -/* div.field-couple div.field-error { */ -/* clear: both; */ -/* color: #dd6666; */ -/* font-weight: bold; */ -/* } */ - -div.field-wrapper div.field { - display: block; - float: left; - margin-bottom: 5px; - line-height: 25px; -} - -div.field-wrapper div.field input[type=text], -div.field-wrapper div.field input[type=password], -div.field-wrapper div.field select { - width: 320px; -} - -div.buttons { - clear: both; - margin-top: 10px; -} - -div.buttons * { - margin-right: 8px; -} diff --git a/edbob/pyramid/static/css/filters.css b/edbob/pyramid/static/css/filters.css new file mode 100644 index 0000000..6cf4e8b --- /dev/null +++ b/edbob/pyramid/static/css/filters.css @@ -0,0 +1,24 @@ + +/****************************** + * Filters + ******************************/ + +div.filters div.filter { + margin-bottom: 10px; +} + +div.filters div.filter label { + margin-right: 8px; +} + +div.filters div.filter select.filter-type { + margin-right: 8px; +} + +div.filters div.filter div.value { + display: inline; +} + +div.filters div.buttons * { + margin-right: 8px; +} diff --git a/edbob/pyramid/static/css/forms.css b/edbob/pyramid/static/css/forms.css new file mode 100644 index 0000000..67b0eb9 --- /dev/null +++ b/edbob/pyramid/static/css/forms.css @@ -0,0 +1,70 @@ + +/****************************** + * Context Menu + ******************************/ + +div.form-wrapper ul.context-menu { + float: right; + list-style-type: none; + margin: 0px; + text-align: right; +} + + +/****************************** + * Forms + ******************************/ + +div.fieldset-form { + float: left; + margin-left: 50px; + margin-top: 10px; +} + + +/****************************** + * Fieldsets + ******************************/ + +div.field-wrapper { + clear: both; + overflow: auto; + min-height: 30px; +} + +div.field-wrapper label { + display: block; + float: left; + width: 140px; + font-weight: bold; + margin-top: 2px; + white-space: nowrap; +} + +/* div.field-couple div.field-error { */ +/* clear: both; */ +/* color: #dd6666; */ +/* font-weight: bold; */ +/* } */ + +div.field-wrapper div.field { + display: block; + float: left; + margin-bottom: 5px; + line-height: 25px; +} + +div.field-wrapper div.field input[type=text], +div.field-wrapper div.field input[type=password], +div.field-wrapper div.field select { + width: 320px; +} + +div.buttons { + clear: both; + margin-top: 10px; +} + +div.buttons * { + margin-right: 8px; +} diff --git a/edbob/pyramid/static/css/grids.css b/edbob/pyramid/static/css/grids.css new file mode 100644 index 0000000..2f9eba4 --- /dev/null +++ b/edbob/pyramid/static/css/grids.css @@ -0,0 +1,150 @@ + +/****************************** + * Grid Header + ******************************/ + +table.grid-header { + padding-bottom: 5px; + width: 100%; +} + + +/****************************** + * Context Menu + ******************************/ + +table.grid-header td.context-menu { + vertical-align: top; +} + +table.grid-header td.context-menu ul { + list-style-type: none; + margin: 0px; + text-align: right; +} + + +/****************************** + * Tools + ******************************/ + +table.grid-header td.tools { + text-align: right; + vertical-align: bottom; +} + + +/****************************** + * Grid + ******************************/ + +div.grid { + clear: both; +} + +div.grid table { + border-top: 1px solid black; + border-left: 1px solid black; + border-collapse: collapse; + font-size: 9pt; + line-height: normal; + white-space: nowrap; +} + +div.grid.full table { + width: 100%; +} + +div.grid table th, +div.grid table td { + border-right: 1px solid black; + border-bottom: 1px solid black; + padding: 2px 3px; +} + +div.grid table th.sortable a { + display: block; + padding-right: 18px; +} + +div.grid table th.sorted { + background-position: right center; + background-repeat: no-repeat; +} + +div.grid table th.sorted.asc { + background-image: url(../img/sort_arrow_up.png); +} + +div.grid table th.sorted.desc { + background-image: url(../img/sort_arrow_down.png); +} + +div.grid table tbody td { + text-align: left; +} + +div.grid table tbody td.right { + text-align: right; +} + +div.grid table tr.odd { + background-color: #e0e0e0; +} + +/* div.grid table thead th.checkbox, */ +/* div.grid table tbody td.checkbox { */ +/* text-align: center; */ +/* vertical-align: middle; */ +/* width: 15px; */ +/* } */ + +div.grid table td.delete { + text-align: center; + width: 18px; + background-image: url(../img/delete.png); + background-repeat: no-repeat; + background-position: center; + cursor: pointer; +} + +div.grid table tbody tr.hovering { + background-color: #bbbbbb; +} + +div.grid table.hoverable tbody tr { + cursor: default; +} + +div.grid.clickable table tbody tr, +div.grid table.selectable tbody tr, +div.grid table.checkable tbody tr { + cursor: pointer; +} + +/* div.grid table.selectable tbody tr.selected, */ +/* div.grid table.checkable tbody tr.selected { */ +/* background-color: #666666; */ +/* color: white; */ +/* } */ + +div.pager { + margin-top: 5px; +} + +div.pager p { + font-size: 10pt; + margin: 0px; +} + +div.pager p.showing { + float: left; +} + +div.pager #grid-page-count { + font-size: 8pt; +} + +div.pager p.page-links { + float: right; +} diff --git a/edbob/pyramid/static/css/index.css b/edbob/pyramid/static/css/index.css deleted file mode 100644 index 8beaa9b..0000000 --- a/edbob/pyramid/static/css/index.css +++ /dev/null @@ -1,165 +0,0 @@ - -/************************************************************ - * index.css - * - * Styles specific to "object index" pages. - ************************************************************/ - - -/****************************** - * Wrapper - ******************************/ - -div.object-index { - font-size: 10pt; -} - -div.object-index table.header { - padding-bottom: 5px; - width: 100%; -} - - -/****************************** - * Context Menu - ******************************/ - -div.object-index table.header td.context-menu { - vertical-align: top; -} - -div.object-index table.header td.context-menu ul { - list-style-type: none; - text-align: right; -} - - -/****************************** - * Filters - ******************************/ - -div.object-index div.filters div.filter { - margin-bottom: 10px; -} - -div.object-index div.filters div.filter label, -div.object-index div.filters div.filter select.filter-type { - margin-right: 8px; -} - -div.object-index div.filters div.buttons * { - margin-right: 8px; -} - - -/****************************** - * Tools - ******************************/ - -div.object-index table.header td.tools { - text-align: right; - vertical-align: bottom; -} - - -/****************************** - * Grids - ******************************/ - -/* div.object-index div.grid { */ -/* clear: both; */ -/* } */ - -div.object-index div.grid table { - /* border-top: 1px solid black; */ - /* border-left: 1px solid black; */ - /* border-collapse: collapse; */ - /* font-size: 9pt; */ - /* line-height: normal; */ - /* white-space: nowrap; */ - width: 100%; -} - -/* div.object-index div.grid table th, */ -/* div.object-index div.grid table td { */ -/* border-right: 1px solid black; */ -/* border-bottom: 1px solid black; */ -/* padding: 2px 3px; */ -/* } */ - -/* div.object-index div.grid table th.sortable a { */ -/* display: block; */ -/* padding-right: 18px; */ -/* } */ - -/* div.object-index div.grid table th.sorted { */ -/* background-position: right center; */ -/* background-repeat: no-repeat; */ -/* } */ - -/* div.object-index div.grid table th.sorted.asc { */ -/* background-image: url(../img/sort_arrow_up.png); */ -/* } */ - -/* div.object-index div.grid table th.sorted.desc { */ -/* background-image: url(../img/sort_arrow_down.png); */ -/* } */ - -/* div.object-index div.grid table tbody td { */ -/* text-align: left; */ -/* } */ - -/* div.object-index div.grid table tr.even { */ -/* background-color: #e0e0e0; */ -/* } */ - -/* div.object-index div.grid table td.delete { */ -/* text-align: center; */ -/* width: 18px; */ -/* background-image: url(../img/delete.png); */ -/* background-repeat: no-repeat; */ -/* background-position: center; */ -/* cursor: pointer; */ -/* } */ - -/* div.object-index div.grid table tbody tr.hovering { */ -/* background-color: #bbbbbb; */ -/* } */ - -/* div.object-index div.grid table.hoverable tbody tr { */ -/* cursor: default; */ -/* } */ - -/* div.object-index div.grid.clickable table tbody tr, */ -/* div.object-index div.grid table.selectable tbody tr, */ -/* div.object-index div.grid table.checkable tbody tr { */ -/* cursor: pointer; */ -/* } */ - -/* div.grid table.selectable tbody tr.selected, */ -/* div.grid table.checkable tbody tr.selected { */ -/* background-color: #666666; */ -/* color: white; */ -/* } */ - -/* div.object-index div.pager { */ -/* margin-top: 5px; */ -/* } */ - -/* div.object-index div.pager p { */ -/* font-size: 10pt; */ -/* margin: 0px; */ -/* } */ - -/* div.object-index div.pager p.showing { */ -/* float: left; */ -/* } */ - -/* div.object-index div.pager #grid-page-count { */ -/* font-size: 8pt; */ -/* height: 21px; */ -/* } */ - -/* div.object-index div.pager p.page-links { */ -/* float: right; */ -/* } */ diff --git a/edbob/pyramid/static/js/edbob.js b/edbob/pyramid/static/js/edbob.js index 1bda139..d36fc3e 100644 --- a/edbob/pyramid/static/js/edbob.js +++ b/edbob/pyramid/static/js/edbob.js @@ -287,18 +287,13 @@ $(function() { $(this).toggleClass('selected'); }); - $('div.grid td.delete').live('click', function() { - var grid = $(this).parents('div.grid:first'); - var url = grid.attr('delurl'); + $('div.grid table tbody td.delete').live('click', function() { + var url = $(this).attr('url'); if (url) { if (confirm("Do you really wish to delete this object?")) { - location.href = url.replace(/%7Buuid%7D/, get_uuid(this)); + location.href = url; } - } else { - alert("Hm, I don't know how to delete that..\n\n" - + "(Add a 'delurl' parameter to the AlchemyGrid instance.)"); } - return false; }); $('#grid-page-count').live('change', function() { diff --git a/edbob/pyramid/templates/crud.mako b/edbob/pyramid/templates/crud.mako index 6a1a27f..0ca6e40 100644 --- a/edbob/pyramid/templates/crud.mako +++ b/edbob/pyramid/templates/crud.mako @@ -1,2 +1,3 @@ <%inherit file="/edbob/crud.mako" /> + ${parent.body()} diff --git a/edbob/pyramid/templates/edbob/base.mako b/edbob/pyramid/templates/edbob/base.mako index 346e5d7..b8f3279 100644 --- a/edbob/pyramid/templates/edbob/base.mako +++ b/edbob/pyramid/templates/edbob/base.mako @@ -18,9 +18,12 @@ ${h.javascript_link(request.static_url('edbob.pyramid:static/js/jquery.autocomplete.js'))} ${h.javascript_link(request.static_url('edbob.pyramid:static/js/edbob.js'))} - ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/smoothness/jquery-ui-1.8.2.custom.css'))} ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/edbob.css'))} + ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/grids.css'))} + ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/filters.css'))} + ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/forms.css'))} ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/autocomplete.css'))} + ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/smoothness/jquery-ui-1.8.2.custom.css'))} ${self.head_tags()} diff --git a/edbob/pyramid/templates/edbob/crud.mako b/edbob/pyramid/templates/edbob/crud.mako index c8d2e21..c874825 100644 --- a/edbob/pyramid/templates/edbob/crud.mako +++ b/edbob/pyramid/templates/edbob/crud.mako @@ -2,26 +2,11 @@ <%def name="title()">${(fieldset.crud_title+' : '+fieldset.get_display_text() if fieldset.edit else 'New '+fieldset.crud_title) if crud else ''|n} -<%def name="head_tags()"> - ${parent.head_tags()} - - - <%def name="context_menu_items()"> -
+
-
    +
      ${self.context_menu_items()}
    diff --git a/edbob/pyramid/templates/edbob/index.mako b/edbob/pyramid/templates/edbob/grid.mako similarity index 70% rename from edbob/pyramid/templates/edbob/index.mako rename to edbob/pyramid/templates/edbob/grid.mako index 2aeae65..1c3bba1 100644 --- a/edbob/pyramid/templates/edbob/index.mako +++ b/edbob/pyramid/templates/edbob/grid.mako @@ -1,16 +1,11 @@ <%inherit file="/base.mako" /> -<%def name="head_tags()"> - ${parent.head_tags()} - ${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/index.css'))} - - <%def name="context_menu_items()"> <%def name="tools()"> -
    +
    - +
    % if search: -
    @@ -30,8 +25,8 @@ ${self.tools()}
    + ${grid} -
    +
    diff --git a/edbob/pyramid/templates/grid.mako b/edbob/pyramid/templates/grid.mako new file mode 100644 index 0000000..1f4d8ba --- /dev/null +++ b/edbob/pyramid/templates/grid.mako @@ -0,0 +1,3 @@ +<%inherit file="/edbob/grid.mako" /> + +${parent.body()} diff --git a/edbob/pyramid/templates/grids/grid.mako b/edbob/pyramid/templates/grids/grid.mako index 34d0b73..3bbc9ad 100644 --- a/edbob/pyramid/templates/grids/grid.mako +++ b/edbob/pyramid/templates/grids/grid.mako @@ -29,7 +29,7 @@ ${col.callback(row)} % endfor % if grid.deletable: -   +   % endif % endfor diff --git a/edbob/pyramid/templates/index.mako b/edbob/pyramid/templates/index.mako deleted file mode 100644 index f7a178f..0000000 --- a/edbob/pyramid/templates/index.mako +++ /dev/null @@ -1,2 +0,0 @@ -<%inherit file="/edbob/index.mako" /> -${parent.body()} diff --git a/edbob/pyramid/views/crud.py b/edbob/pyramid/views/crud.py index 5d17a62..08acc71 100644 --- a/edbob/pyramid/views/crud.py +++ b/edbob/pyramid/views/crud.py @@ -134,6 +134,8 @@ class Crud(object): model = Session.query(self.mapped_class).get(uuid) if uuid else None assert model Session.delete(model) + self.request.session.flash("The %s has been deleted." % + self.mapped_class.__name__) return HTTPFound(location=self.home_url) @classmethod diff --git a/edbob/pyramid/views/grids/alchemy.py b/edbob/pyramid/views/grids/alchemy.py index e2a63a3..3e763f1 100644 --- a/edbob/pyramid/views/grids/alchemy.py +++ b/edbob/pyramid/views/grids/alchemy.py @@ -31,6 +31,7 @@ from webhelpers import paginate from edbob.pyramid import grids from edbob.pyramid import Session from edbob.pyramid.views.grids.core import GridView +from edbob.util import requires_impl __all__ = ['AlchemyGridView', 'SortableAlchemyGridView', @@ -64,6 +65,11 @@ class SortableAlchemyGridView(AlchemyGridView): sort = None + @property + @requires_impl(is_property=True) + def config_prefix(self): + pass + def join_map(self): return {} @@ -79,7 +85,7 @@ class SortableAlchemyGridView(AlchemyGridView): def make_sort_config(self, **kwargs): return grids.util.get_sort_config( - self.route_name, self.request, **kwargs) + self.config_prefix, self.request, **kwargs) def sort_config(self): return self.make_sort_config(sort=self.sort) @@ -111,6 +117,8 @@ class SortableAlchemyGridView(AlchemyGridView): class PagedAlchemyGridView(SortableAlchemyGridView): + full = True + def make_pager(self): config = self._sort_config query = self.query() @@ -144,7 +152,7 @@ class SearchableAlchemyGridView(PagedAlchemyGridView): def make_filter_config(self, **kwargs): return grids.search.get_filter_config( - self.route_name, self.request, self.filter_map(), **kwargs) + self.config_prefix, self.request, self.filter_map(), **kwargs) def filter_config(self): return self.make_filter_config() diff --git a/edbob/pyramid/views/grids/core.py b/edbob/pyramid/views/grids/core.py index 9e34708..0159d48 100644 --- a/edbob/pyramid/views/grids/core.py +++ b/edbob/pyramid/views/grids/core.py @@ -39,13 +39,19 @@ class GridView(View): route_url = None renderer = None permission = None + + full = False checkboxes = False clickable = False + deletable = False + partial_only = False def update_grid_kwargs(self, kwargs): + kwargs.setdefault('full', self.full) kwargs.setdefault('checkboxes', self.checkboxes) kwargs.setdefault('clickable', self.clickable) + kwargs.setdefault('deletable', self.deletable) kwargs.setdefault('partial_only', self.partial_only) def make_grid(self, **kwargs): diff --git a/edbob/pyramid/views/users.py b/edbob/pyramid/views/users.py index 68f0551..be0a611 100644 --- a/edbob/pyramid/views/users.py +++ b/edbob/pyramid/views/users.py @@ -34,17 +34,16 @@ from formalchemy.fields import SelectFieldRenderer import edbob from edbob.db.auth import set_user_password from edbob.pyramid import Session -from edbob.pyramid.filters import filter_ilike -from edbob.pyramid.grids import sorter -from edbob.pyramid.views import GridView +from edbob.pyramid.views import SearchableAlchemyGridView from edbob.pyramid.views.crud import Crud -class UserGrid(GridView): +class UsersGrid(SearchableAlchemyGridView): mapped_class = edbob.User - route_name = 'users.list' - route_prefix = 'user' + route_name = 'users' + route_url = '/users' + sort = 'username' def join_map(self): return { @@ -55,27 +54,22 @@ class UserGrid(GridView): def filter_map(self): return self.make_filter_map( ilike=['username'], - person=filter_ilike(edbob.Person.display_name)) + person=self.filter_ilike(edbob.Person.display_name)) - def search_config(self, fmap): - return self.make_search_config( - fmap, + def filter_config(self): + return self.make_filter_config( include_filter_username=True, filter_type_username='lk', include_filter_person=True, filter_type_person='lk') - def grid_config(self, search, fmap): - return self.make_grid_config(search, fmap, - sort='username') - def sort_map(self): return self.make_sort_map( 'username', - person=sorter(edbob.Person.display_name)) + person=self.sorter(edbob.Person.display_name)) - def grid(self, data, config): - g = self.make_grid(data, config) + def grid(self): + g = self.make_grid() g.configure( include=[ g.username, @@ -219,5 +213,5 @@ class UserCrud(Crud): def includeme(config): - UserGrid.add_route(config, 'users.list', '/users') + UsersGrid.add_route(config) UserCrud.add_routes(config)