2
0
Fork 0

Compare commits

...

3 commits

Author SHA1 Message Date
Lance Edgar 3579bebdeb bump: version 0.10.1 → 0.10.2 2024-08-19 13:56:58 -05:00
Lance Edgar f7e371d21d fix: add render_vue_finalize() methods for grids, forms
to make the templates just that much cleaner
2024-08-19 13:40:23 -05:00
Lance Edgar 784f974c0d fix: avoid error when checking model for column property
assocation proxy sometimes throws a wrench in that..
2024-08-19 12:42:14 -05:00
9 changed files with 81 additions and 18 deletions

View file

@ -5,6 +5,13 @@ All notable changes to wuttaweb will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## v0.10.2 (2024-08-19)
### Fix
- add `render_vue_finalize()` methods for grids, forms
- avoid error when checking model for column property
## v0.10.1 (2024-08-19) ## v0.10.1 (2024-08-19)
### Fix ### Fix

View file

@ -6,7 +6,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "WuttaWeb" name = "WuttaWeb"
version = "0.10.1" version = "0.10.2"
description = "Web App for Wutta Framework" description = "Web App for Wutta Framework"
readme = "README.md" readme = "README.md"
authors = [{name = "Lance Edgar", email = "lance@edbob.org"}] authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]

View file

@ -918,19 +918,42 @@ class Form:
return HTML.tag('b-field', c=[html], **attrs) return HTML.tag('b-field', c=[html], **attrs)
def render_vue_finalize(self):
"""
Render the Vue "finalize" script for the form.
By default this simply returns:
.. code-block:: html
<script>
WuttaForm.data = function() { return WuttaFormData }
Vue.component('wutta-form', WuttaForm)
</script>
The actual output may depend on various form attributes, in
particular :attr:`vue_tagname`.
"""
set_data = f"{self.vue_component}.data = function() {{ return {self.vue_component}Data }}"
make_component = f"Vue.component('{self.vue_tagname}', {self.vue_component})"
return HTML.tag('script', c=['\n',
HTML.literal(set_data),
'\n',
HTML.literal(make_component),
'\n'])
def get_vue_model_data(self): def get_vue_model_data(self):
""" """
Returns a dict with form model data. Values may be nested Returns a dict with form model data. Values may be nested
depending on the types of fields contained in the form. depending on the types of fields contained in the form.
Note that the values need not be "converted" (to be This collects the ``cstruct`` values for all fields which are
JSON-compatible) at this stage, for instance ``colander.null`` present both in :attr:`fields` as well as the Deform schema.
is not a problem here. The point is to collect the raw data.
The dict should have a key/value for each field in the form. It also converts each as needed, to ensure it is
JSON-serializable.
This method is called by :meth:`render_vue_model_data()` which :returns: Dict of field/value items.
is responsible for ensuring JSON compatibility.
""" """
dform = self.get_deform() dform = self.get_deform()
model_data = {} model_data = {}

View file

@ -578,7 +578,8 @@ class Grid:
if key in sorters: if key in sorters:
continue continue
prop = getattr(self.model_class, key, None) prop = getattr(self.model_class, key, None)
if prop and isinstance(prop.property, orm.ColumnProperty): if (prop and hasattr(prop, 'property')
and isinstance(prop.property, orm.ColumnProperty)):
sorters[prop.key] = self.make_sorter(prop) sorters[prop.key] = self.make_sorter(prop)
return sorters return sorters
@ -1277,6 +1278,30 @@ class Grid:
output = render(template, context) output = render(template, context)
return HTML.literal(output) return HTML.literal(output)
def render_vue_finalize(self):
"""
Render the Vue "finalize" script for the grid.
By default this simply returns:
.. code-block:: html
<script>
WuttaGrid.data = function() { return WuttaGridData }
Vue.component('wutta-grid', WuttaGrid)
</script>
The actual output may depend on various grid attributes, in
particular :attr:`vue_tagname`.
"""
set_data = f"{self.vue_component}.data = function() {{ return {self.vue_component}Data }}"
make_component = f"Vue.component('{self.vue_tagname}', {self.vue_component})"
return HTML.tag('script', c=['\n',
HTML.literal(set_data),
'\n',
HTML.literal(make_component),
'\n'])
def get_vue_columns(self): def get_vue_columns(self):
""" """
Returns a list of Vue-compatible column definitions. Returns a list of Vue-compatible column definitions.

View file

@ -3,7 +3,9 @@
<%def name="page_content()"> <%def name="page_content()">
<div style="margin-top: 2rem; width: 50%;"> <div style="margin-top: 2rem; width: 50%;">
${form.render_vue_tag()} % if form is not Undefined:
${form.render_vue_tag()}
% endif
</div> </div>
</%def> </%def>
@ -17,10 +19,7 @@
<%def name="finalize_this_page_vars()"> <%def name="finalize_this_page_vars()">
${parent.finalize_this_page_vars()} ${parent.finalize_this_page_vars()}
% if form is not Undefined: % if form is not Undefined:
<script> ${form.render_vue_finalize()}
${form.vue_component}.data = function() { return ${form.vue_component}Data }
Vue.component('${form.vue_tagname}', ${form.vue_component})
</script>
% endif % endif
</%def> </%def>

View file

@ -37,7 +37,7 @@
## paging ## paging
% if grid.paginated: % if grid.paginated:
paginated paginated
pagination-size="is-small" pagination-size="${'small' if request.use_oruga else 'is-small'}"
:per-page="perPage" :per-page="perPage"
:current-page="currentPage" :current-page="currentPage"
@page-change="onPageChange" @page-change="onPageChange"

View file

@ -22,10 +22,7 @@
<%def name="finalize_this_page_vars()"> <%def name="finalize_this_page_vars()">
${parent.finalize_this_page_vars()} ${parent.finalize_this_page_vars()}
% if grid is not Undefined: % if grid is not Undefined:
<script> ${grid.render_vue_finalize()}
${grid.vue_component}.data = function() { return ${grid.vue_component}Data }
Vue.component('${grid.vue_tagname}', ${grid.vue_component})
</script>
% endif % endif
</%def> </%def>

View file

@ -405,6 +405,12 @@ class TestForm(TestCase):
self.assertIn('<script type="text/x-template" id="wutta-form-template">', html) self.assertIn('<script type="text/x-template" id="wutta-form-template">', html)
self.assertNotIn('@submit', html) self.assertNotIn('@submit', html)
def test_render_vue_finalize(self):
form = self.make_form()
html = form.render_vue_finalize()
self.assertIn('<script>', html)
self.assertIn("Vue.component('wutta-form', WuttaForm)", html)
def test_render_vue_field(self): def test_render_vue_field(self):
self.pyramid_config.include('pyramid_deform') self.pyramid_config.include('pyramid_deform')
schema = self.make_schema() schema = self.make_schema()

View file

@ -855,6 +855,12 @@ class TestGrid(WebTestCase):
html = grid.render_vue_template() html = grid.render_vue_template()
self.assertIn('<script type="text/x-template" id="wutta-grid-template">', html) self.assertIn('<script type="text/x-template" id="wutta-grid-template">', html)
def test_render_vue_finalize(self):
grid = self.make_grid()
html = grid.render_vue_finalize()
self.assertIn('<script>', html)
self.assertIn("Vue.component('wutta-grid', WuttaGrid)", html)
def test_get_vue_columns(self): def test_get_vue_columns(self):
# error if no columns are set # error if no columns are set