WuttaWeb 0.19.0__tar.gz → 0.19.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/CHANGELOG.md +20 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/PKG-INFO +3 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/pyproject.toml +3 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/forms/schema.py +57 -19
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/forms/widgets.py +75 -7
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/grids/base.py +112 -27
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/progress.py +4 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/base.mako +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/batch/view.mako +1 -14
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/view.mako +15 -0
- wuttaweb-0.19.0/tests/util.py → wuttaweb-0.19.1/src/wuttaweb/testing.py +26 -39
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/util.py +33 -6
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/batch.py +11 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/master.py +84 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/db/test_continuum.py +1 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/forms/test_schema.py +127 -93
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/forms/test_widgets.py +162 -93
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/grids/test_base.py +96 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/grids/test_filters.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_auth.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_handler.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_menus.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_progress.py +5 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_util.py +17 -6
- wuttaweb-0.19.1/tests/util.py +40 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test___init__.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_auth.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_base.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_batch.py +7 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_common.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_email.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_essential.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_master.py +19 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_people.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_progress.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_roles.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_settings.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_upgrades.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/test_users.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/.gitignore +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/COPYING.txt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/README.md +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/Makefile +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/_static/.keepme +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.app.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.auth.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.cli.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.cli.webapp.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.conf.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.db.continuum.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.db.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.db.sess.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.emails.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.forms.base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.forms.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.forms.schema.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.forms.widgets.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.grids.base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.grids.filters.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.grids.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.handler.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.helpers.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.menus.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.progress.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.static.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.subscribers.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.util.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.auth.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.batch.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.common.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.email.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.essential.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.master.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.people.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.progress.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.roles.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.settings.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.upgrades.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/api/wuttaweb.views.users.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/conf.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/glossary.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/index.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/make.bat +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/narr/cli/builtin.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/narr/cli/index.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/narr/templates/base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/narr/templates/index.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/narr/templates/lookup.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/docs/narr/templates/overview.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/_version.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/app.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/auth.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/cli/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/cli/webapp.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/conf.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/db/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/db/continuum.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/db/sess.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/emails.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/forms/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/forms/base.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/grids/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/grids/filters.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/handler.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/helpers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/menus.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/static/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/static/img/favicon.ico +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/static/img/logo.png +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/static/img/testing.png +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/subscribers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/appinfo/index.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/auth/change_password.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/auth/login.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/base_meta.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/dateinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/datetimeinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/password.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/permissions.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/select.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/textarea.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/deform/textinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/email/settings/view.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/forbidden.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/form.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/grids/table_element.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/home.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/create.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/delete.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/edit.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/form.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/master/index.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/notfound.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/page.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/people/view_profile.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/progress.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/setup.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/upgrade.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/upgrades/view.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/templates/wutta-components.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/auth.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/base.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/common.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/email.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/essential.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/people.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/progress.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/roles.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/settings.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/upgrades.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/src/wuttaweb/views/users.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tasks.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/cli/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/cli/test_webapp.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/db/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/forms/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/forms/test_base.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/grids/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_oruga.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_oruga_bulma.css +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_oruga_bulma.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_vue.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/bb_vue_fontawesome.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/buefy.css +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/buefy.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/fontawesome.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/vue.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/libcache/vue_resource.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_app.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_emails.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_helpers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_static.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/test_subscribers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tests/views/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.1}/tox.ini +0 -0
|
@@ -5,6 +5,26 @@ All notable changes to wuttaweb will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## v0.19.1 (2025-01-06)
|
|
9
|
+
|
|
10
|
+
### Fix
|
|
11
|
+
|
|
12
|
+
- improve built-in grid renderer logic
|
|
13
|
+
- allow session injection for ObjectRef constructor
|
|
14
|
+
- improve rendering for batch row status
|
|
15
|
+
- add basic support for row grid "view" action links
|
|
16
|
+
- add "xref buttons" tool panel for master view
|
|
17
|
+
- add WuttaQuantity schema type, widget
|
|
18
|
+
- remove `session` param from some form schema, widget classes
|
|
19
|
+
- add grid renderers for bool, currency, quantity
|
|
20
|
+
- use proper bulma styles for markdown content
|
|
21
|
+
- use span element for readonly money field widget render
|
|
22
|
+
- include grid filters for all column properties of model class
|
|
23
|
+
- use app handler to render error string, when progress fails
|
|
24
|
+
- add schema node type, widget for "money" (currency) fields
|
|
25
|
+
- exclude FK fields by default, for model forms
|
|
26
|
+
- fix style for header title text
|
|
27
|
+
|
|
8
28
|
## v0.19.0 (2024-12-23)
|
|
9
29
|
|
|
10
30
|
### Feat
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: WuttaWeb
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.1
|
|
4
4
|
Summary: Web App for Wutta Framework
|
|
5
5
|
Project-URL: Homepage, https://wuttaproject.org/
|
|
6
6
|
Project-URL: Repository, https://forgejo.wuttaproject.org/wutta/wuttaweb
|
|
@@ -37,9 +37,10 @@ Requires-Dist: pyramid-fanstatic
|
|
|
37
37
|
Requires-Dist: pyramid-mako
|
|
38
38
|
Requires-Dist: pyramid-tm
|
|
39
39
|
Requires-Dist: pyramid>=2
|
|
40
|
+
Requires-Dist: sqlalchemy-utils
|
|
40
41
|
Requires-Dist: waitress
|
|
41
42
|
Requires-Dist: webhelpers2
|
|
42
|
-
Requires-Dist: wuttjamaican[db]>=0.19.
|
|
43
|
+
Requires-Dist: wuttjamaican[db]>=0.19.2
|
|
43
44
|
Requires-Dist: zope-sqlalchemy>=1.5
|
|
44
45
|
Provides-Extra: continuum
|
|
45
46
|
Requires-Dist: wutta-continuum; extra == 'continuum'
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "WuttaWeb"
|
|
9
|
-
version = "0.19.
|
|
9
|
+
version = "0.19.1"
|
|
10
10
|
description = "Web App for Wutta Framework"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
|
@@ -42,9 +42,10 @@ dependencies = [
|
|
|
42
42
|
"pyramid_fanstatic",
|
|
43
43
|
"pyramid_mako",
|
|
44
44
|
"pyramid_tm",
|
|
45
|
+
"SQLAlchemy-Utils",
|
|
45
46
|
"waitress",
|
|
46
47
|
"WebHelpers2",
|
|
47
|
-
"WuttJamaican[db]>=0.19.
|
|
48
|
+
"WuttJamaican[db]>=0.19.2",
|
|
48
49
|
"zope.sqlalchemy>=1.5",
|
|
49
50
|
]
|
|
50
51
|
|
|
@@ -155,25 +155,63 @@ class WuttaEnum(colander.Enum):
|
|
|
155
155
|
return widgets.SelectWidget(**kwargs)
|
|
156
156
|
|
|
157
157
|
|
|
158
|
+
class WuttaMoney(colander.Money):
|
|
159
|
+
"""
|
|
160
|
+
Custom schema type for "money" fields.
|
|
161
|
+
|
|
162
|
+
This is a subclass of :class:`colander:colander.Money`, but uses
|
|
163
|
+
the custom :class:`~wuttaweb.forms.widgets.WuttaMoneyInputWidget`
|
|
164
|
+
by default.
|
|
165
|
+
|
|
166
|
+
:param request: Current :term:`request` object.
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
def __init__(self, request, *args, **kwargs):
|
|
170
|
+
super().__init__(*args, **kwargs)
|
|
171
|
+
self.request = request
|
|
172
|
+
self.config = self.request.wutta_config
|
|
173
|
+
self.app = self.config.get_app()
|
|
174
|
+
|
|
175
|
+
def widget_maker(self, **kwargs):
|
|
176
|
+
""" """
|
|
177
|
+
return widgets.WuttaMoneyInputWidget(self.request, **kwargs)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class WuttaQuantity(colander.Decimal):
|
|
181
|
+
"""
|
|
182
|
+
Custom schema type for "quantity" fields.
|
|
183
|
+
|
|
184
|
+
This is a subclass of :class:`colander:colander.Decimal` but uses
|
|
185
|
+
:class:`~wuttaweb.forms.widgets.WuttaQuantityWidget` by default.
|
|
186
|
+
|
|
187
|
+
:param request: Current :term:`request` object.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
def __init__(self, request, *args, **kwargs):
|
|
191
|
+
super().__init__(*args, **kwargs)
|
|
192
|
+
self.request = request
|
|
193
|
+
self.config = self.request.wutta_config
|
|
194
|
+
self.app = self.config.get_app()
|
|
195
|
+
|
|
196
|
+
def widget_maker(self, **kwargs):
|
|
197
|
+
""" """
|
|
198
|
+
return widgets.WuttaQuantityWidget(self.request, **kwargs)
|
|
199
|
+
|
|
200
|
+
|
|
158
201
|
class WuttaSet(colander.Set):
|
|
159
202
|
"""
|
|
160
203
|
Custom schema type for :class:`python:set` fields.
|
|
161
204
|
|
|
162
|
-
This is a subclass of :class:`colander.Set
|
|
163
|
-
Wutta-related params to the constructor.
|
|
205
|
+
This is a subclass of :class:`colander.Set`.
|
|
164
206
|
|
|
165
207
|
:param request: Current :term:`request` object.
|
|
166
|
-
|
|
167
|
-
:param session: Optional :term:`db session` to use instead of
|
|
168
|
-
:class:`wuttaweb.db.sess.Session`.
|
|
169
208
|
"""
|
|
170
209
|
|
|
171
|
-
def __init__(self, request
|
|
210
|
+
def __init__(self, request):
|
|
172
211
|
super().__init__()
|
|
173
212
|
self.request = request
|
|
174
213
|
self.config = self.request.wutta_config
|
|
175
214
|
self.app = self.config.get_app()
|
|
176
|
-
self.session = session or Session()
|
|
177
215
|
|
|
178
216
|
|
|
179
217
|
class ObjectRef(colander.SchemaType):
|
|
@@ -209,16 +247,16 @@ class ObjectRef(colander.SchemaType):
|
|
|
209
247
|
self,
|
|
210
248
|
request,
|
|
211
249
|
empty_option=None,
|
|
212
|
-
session=None,
|
|
213
250
|
*args,
|
|
214
251
|
**kwargs,
|
|
215
252
|
):
|
|
253
|
+
# nb. allow session injection for tests
|
|
254
|
+
self.session = kwargs.pop('session', Session())
|
|
216
255
|
super().__init__(*args, **kwargs)
|
|
217
256
|
self.request = request
|
|
218
257
|
self.config = self.request.wutta_config
|
|
219
258
|
self.app = self.config.get_app()
|
|
220
259
|
self.model_instance = None
|
|
221
|
-
self.session = session or Session()
|
|
222
260
|
|
|
223
261
|
if empty_option:
|
|
224
262
|
if empty_option is True:
|
|
@@ -450,7 +488,7 @@ class RoleRefs(WuttaSet):
|
|
|
450
488
|
:returns: Instance of
|
|
451
489
|
:class:`~wuttaweb.forms.widgets.RoleRefsWidget`.
|
|
452
490
|
"""
|
|
453
|
-
kwargs.setdefault('session',
|
|
491
|
+
session = kwargs.setdefault('session', Session())
|
|
454
492
|
|
|
455
493
|
if 'values' not in kwargs:
|
|
456
494
|
model = self.app.model
|
|
@@ -458,20 +496,20 @@ class RoleRefs(WuttaSet):
|
|
|
458
496
|
|
|
459
497
|
# avoid built-ins which cannot be assigned to users
|
|
460
498
|
avoid = {
|
|
461
|
-
auth.get_role_authenticated(
|
|
462
|
-
auth.get_role_anonymous(
|
|
499
|
+
auth.get_role_authenticated(session),
|
|
500
|
+
auth.get_role_anonymous(session),
|
|
463
501
|
}
|
|
464
502
|
avoid = set([role.uuid for role in avoid])
|
|
465
503
|
|
|
466
504
|
# also avoid admin unless current user is root
|
|
467
505
|
if not self.request.is_root:
|
|
468
|
-
avoid.add(auth.get_role_administrator(
|
|
506
|
+
avoid.add(auth.get_role_administrator(session).uuid)
|
|
469
507
|
|
|
470
508
|
# everything else can be (un)assigned for users
|
|
471
|
-
roles =
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
509
|
+
roles = session.query(model.Role)\
|
|
510
|
+
.filter(~model.Role.uuid.in_(avoid))\
|
|
511
|
+
.order_by(model.Role.name)\
|
|
512
|
+
.all()
|
|
475
513
|
values = [(role.uuid.hex, role.name) for role in roles]
|
|
476
514
|
kwargs['values'] = values
|
|
477
515
|
|
|
@@ -496,7 +534,7 @@ class UserRefs(WuttaSet):
|
|
|
496
534
|
:returns: Instance of
|
|
497
535
|
:class:`~wuttaweb.forms.widgets.UserRefsWidget`.
|
|
498
536
|
"""
|
|
499
|
-
kwargs.setdefault('session',
|
|
537
|
+
kwargs.setdefault('session', Session())
|
|
500
538
|
return widgets.UserRefsWidget(self.request, **kwargs)
|
|
501
539
|
|
|
502
540
|
|
|
@@ -526,7 +564,7 @@ class Permissions(WuttaSet):
|
|
|
526
564
|
:returns: Instance of
|
|
527
565
|
:class:`~wuttaweb.forms.widgets.PermissionsWidget`.
|
|
528
566
|
"""
|
|
529
|
-
kwargs.setdefault('session',
|
|
567
|
+
kwargs.setdefault('session', Session())
|
|
530
568
|
kwargs.setdefault('permissions', self.permissions)
|
|
531
569
|
|
|
532
570
|
if 'values' not in kwargs:
|
|
@@ -41,6 +41,7 @@ in the namespace:
|
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
43
|
import datetime
|
|
44
|
+
import decimal
|
|
44
45
|
import os
|
|
45
46
|
|
|
46
47
|
import colander
|
|
@@ -135,26 +136,21 @@ class WuttaCheckboxChoiceWidget(CheckboxChoiceWidget):
|
|
|
135
136
|
Custom widget for :class:`python:set` fields.
|
|
136
137
|
|
|
137
138
|
This is a subclass of
|
|
138
|
-
:class:`deform:deform.widget.CheckboxChoiceWidget
|
|
139
|
-
Wutta-related params to the constructor.
|
|
139
|
+
:class:`deform:deform.widget.CheckboxChoiceWidget`.
|
|
140
140
|
|
|
141
141
|
:param request: Current :term:`request` object.
|
|
142
142
|
|
|
143
|
-
:param session: Optional :term:`db session` to use instead of
|
|
144
|
-
:class:`wuttaweb.db.sess.Session`.
|
|
145
|
-
|
|
146
143
|
It uses these Deform templates:
|
|
147
144
|
|
|
148
145
|
* ``checkbox_choice``
|
|
149
146
|
* ``readonly/checkbox_choice``
|
|
150
147
|
"""
|
|
151
148
|
|
|
152
|
-
def __init__(self, request,
|
|
149
|
+
def __init__(self, request, *args, **kwargs):
|
|
153
150
|
super().__init__(*args, **kwargs)
|
|
154
151
|
self.request = request
|
|
155
152
|
self.config = self.request.wutta_config
|
|
156
153
|
self.app = self.config.get_app()
|
|
157
|
-
self.session = session or Session()
|
|
158
154
|
|
|
159
155
|
|
|
160
156
|
class WuttaDateTimeWidget(DateTimeInputWidget):
|
|
@@ -194,6 +190,78 @@ class WuttaDateTimeWidget(DateTimeInputWidget):
|
|
|
194
190
|
return super().serialize(field, cstruct, **kw)
|
|
195
191
|
|
|
196
192
|
|
|
193
|
+
class WuttaMoneyInputWidget(MoneyInputWidget):
|
|
194
|
+
"""
|
|
195
|
+
Custom widget for "money" fields. This is used by default for
|
|
196
|
+
:class:`~wuttaweb.forms.schema.WuttaMoney` type nodes.
|
|
197
|
+
|
|
198
|
+
The main purpose of this widget is to leverage
|
|
199
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_currency()`
|
|
200
|
+
for the readonly display.
|
|
201
|
+
|
|
202
|
+
This is a subclass of
|
|
203
|
+
:class:`deform:deform.widget.MoneyInputWidget` and uses these
|
|
204
|
+
Deform templates:
|
|
205
|
+
|
|
206
|
+
* ``moneyinput``
|
|
207
|
+
|
|
208
|
+
:param request: Current :term:`request` object.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
def __init__(self, request, *args, **kwargs):
|
|
212
|
+
super().__init__(*args, **kwargs)
|
|
213
|
+
self.request = request
|
|
214
|
+
self.config = self.request.wutta_config
|
|
215
|
+
self.app = self.config.get_app()
|
|
216
|
+
|
|
217
|
+
def serialize(self, field, cstruct, **kw):
|
|
218
|
+
""" """
|
|
219
|
+
readonly = kw.get('readonly', self.readonly)
|
|
220
|
+
if readonly:
|
|
221
|
+
if cstruct in (colander.null, None):
|
|
222
|
+
return HTML.tag('span')
|
|
223
|
+
cstruct = decimal.Decimal(cstruct)
|
|
224
|
+
return HTML.tag('span', c=[self.app.render_currency(cstruct)])
|
|
225
|
+
|
|
226
|
+
return super().serialize(field, cstruct, **kw)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
class WuttaQuantityWidget(TextInputWidget):
|
|
230
|
+
"""
|
|
231
|
+
Custom widget for "quantity" fields. This is used by default for
|
|
232
|
+
:class:`~wuttaweb.forms.schema.WuttaQuantity` type nodes.
|
|
233
|
+
|
|
234
|
+
The main purpose of this widget is to leverage
|
|
235
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_quantity()`
|
|
236
|
+
for the readonly display.
|
|
237
|
+
|
|
238
|
+
This is a subclass of
|
|
239
|
+
:class:`deform:deform.widget.TextInputWidget` and uses these
|
|
240
|
+
Deform templates:
|
|
241
|
+
|
|
242
|
+
* ``textinput``
|
|
243
|
+
|
|
244
|
+
:param request: Current :term:`request` object.
|
|
245
|
+
"""
|
|
246
|
+
|
|
247
|
+
def __init__(self, request, *args, **kwargs):
|
|
248
|
+
super().__init__(*args, **kwargs)
|
|
249
|
+
self.request = request
|
|
250
|
+
self.config = self.request.wutta_config
|
|
251
|
+
self.app = self.config.get_app()
|
|
252
|
+
|
|
253
|
+
def serialize(self, field, cstruct, **kw):
|
|
254
|
+
""" """
|
|
255
|
+
readonly = kw.get('readonly', self.readonly)
|
|
256
|
+
if readonly:
|
|
257
|
+
if cstruct in (colander.null, None):
|
|
258
|
+
return HTML.tag('span')
|
|
259
|
+
cstruct = decimal.Decimal(cstruct)
|
|
260
|
+
return HTML.tag('span', c=[self.app.render_quantity(cstruct)])
|
|
261
|
+
|
|
262
|
+
return super().serialize(field, cstruct, **kw)
|
|
263
|
+
|
|
264
|
+
|
|
197
265
|
class FileDownloadWidget(Widget):
|
|
198
266
|
"""
|
|
199
267
|
Widget for use with :class:`~wuttaweb.forms.schema.FileDownload`
|
|
@@ -32,6 +32,7 @@ from collections import namedtuple, OrderedDict
|
|
|
32
32
|
|
|
33
33
|
import sqlalchemy as sa
|
|
34
34
|
from sqlalchemy import orm
|
|
35
|
+
from sqlalchemy_utils import get_columns
|
|
35
36
|
|
|
36
37
|
import paginate
|
|
37
38
|
from paginate_sqlalchemy import SqlalchemyOrmPage
|
|
@@ -115,7 +116,8 @@ class Grid:
|
|
|
115
116
|
|
|
116
117
|
Dict of column (cell) value renderer overrides.
|
|
117
118
|
|
|
118
|
-
See also :meth:`set_renderer()
|
|
119
|
+
See also :meth:`set_renderer()` and
|
|
120
|
+
:meth:`set_default_renderers()`.
|
|
119
121
|
|
|
120
122
|
.. attribute:: row_class
|
|
121
123
|
|
|
@@ -387,7 +389,6 @@ class Grid:
|
|
|
387
389
|
self.key = key
|
|
388
390
|
self.data = data
|
|
389
391
|
self.labels = labels or {}
|
|
390
|
-
self.renderers = renderers or {}
|
|
391
392
|
self.row_class = row_class
|
|
392
393
|
self.actions = actions or []
|
|
393
394
|
self.linked_columns = linked_columns or []
|
|
@@ -397,6 +398,10 @@ class Grid:
|
|
|
397
398
|
self.app = self.config.get_app()
|
|
398
399
|
|
|
399
400
|
self.set_columns(columns or self.get_columns())
|
|
401
|
+
self.renderers = {}
|
|
402
|
+
if renderers:
|
|
403
|
+
for key, val in renderers.items():
|
|
404
|
+
self.set_renderer(key, val)
|
|
400
405
|
self.set_default_renderers()
|
|
401
406
|
self.set_tools(tools)
|
|
402
407
|
|
|
@@ -591,8 +596,29 @@ class Grid:
|
|
|
591
596
|
grid = Grid(request, columns=['foo', 'bar'])
|
|
592
597
|
grid.set_renderer('foo', render_foo)
|
|
593
598
|
|
|
599
|
+
For convenience, in lieu of a renderer callable, you may
|
|
600
|
+
specify one of the following strings, which will be
|
|
601
|
+
interpreted as a built-in renderer callable, as shown below:
|
|
602
|
+
|
|
603
|
+
* ``'batch_id'`` -> :meth:`render_batch_id()`
|
|
604
|
+
* ``'boolean'`` -> :meth:`render_boolean()`
|
|
605
|
+
* ``'currency'`` -> :meth:`render_currency()`
|
|
606
|
+
* ``'datetime'`` -> :meth:`render_datetime()`
|
|
607
|
+
* ``'quantity'`` -> :meth:`render_quantity()`
|
|
608
|
+
|
|
594
609
|
Renderer overrides are tracked via :attr:`renderers`.
|
|
595
610
|
"""
|
|
611
|
+
builtins = {
|
|
612
|
+
'batch_id': self.render_batch_id,
|
|
613
|
+
'boolean': self.render_boolean,
|
|
614
|
+
'currency': self.render_currency,
|
|
615
|
+
'datetime': self.render_datetime,
|
|
616
|
+
'quantity': self.render_quantity,
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if renderer in builtins:
|
|
620
|
+
renderer = builtins[renderer]
|
|
621
|
+
|
|
596
622
|
if kwargs:
|
|
597
623
|
renderer = functools.partial(renderer, **kwargs)
|
|
598
624
|
self.renderers[key] = renderer
|
|
@@ -601,15 +627,18 @@ class Grid:
|
|
|
601
627
|
"""
|
|
602
628
|
Set default column value renderers, where applicable.
|
|
603
629
|
|
|
604
|
-
This
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
to a
|
|
630
|
+
This is called automatically from the class constructor. It
|
|
631
|
+
will add new entries to :attr:`renderers` for columns whose
|
|
632
|
+
data type implies a default renderer. This is only possible
|
|
633
|
+
if :attr:`model_class` is set to a SQLAlchemy mapped class.
|
|
608
634
|
|
|
609
|
-
This
|
|
610
|
-
:
|
|
611
|
-
|
|
612
|
-
:
|
|
635
|
+
This only looks for a couple of data types, and configures as
|
|
636
|
+
follows:
|
|
637
|
+
|
|
638
|
+
* :class:`sqlalchemy:sqlalchemy.types.Boolean` ->
|
|
639
|
+
:meth:`render_boolean()`
|
|
640
|
+
* :class:`sqlalchemy:sqlalchemy.types.DateTime` ->
|
|
641
|
+
:meth:`render_datetime()`
|
|
613
642
|
"""
|
|
614
643
|
if not self.model_class:
|
|
615
644
|
return
|
|
@@ -625,6 +654,8 @@ class Grid:
|
|
|
625
654
|
column = prop.columns[0]
|
|
626
655
|
if isinstance(column.type, sa.DateTime):
|
|
627
656
|
self.set_renderer(key, self.render_datetime)
|
|
657
|
+
elif isinstance(column.type, sa.Boolean):
|
|
658
|
+
self.set_renderer(key, self.render_boolean)
|
|
628
659
|
|
|
629
660
|
def set_link(self, key, link=True):
|
|
630
661
|
"""
|
|
@@ -1116,19 +1147,16 @@ class Grid:
|
|
|
1116
1147
|
filters = filters or {}
|
|
1117
1148
|
|
|
1118
1149
|
if self.model_class:
|
|
1119
|
-
#
|
|
1120
|
-
#
|
|
1121
|
-
#
|
|
1122
|
-
#
|
|
1123
|
-
#
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
if key in filters:
|
|
1150
|
+
# nb. i first tried self.get_model_columns() but my notes
|
|
1151
|
+
# say that was too aggressive in many cases. then i tried
|
|
1152
|
+
# using the *subset* of self.columns, just the ones which
|
|
1153
|
+
# corresponded to a property on the model class. and now
|
|
1154
|
+
# i am using sa-utils to give the "true" column list..
|
|
1155
|
+
for col in get_columns(self.model_class):
|
|
1156
|
+
if col.key in filters:
|
|
1127
1157
|
continue
|
|
1128
|
-
prop = getattr(self.model_class, key
|
|
1129
|
-
|
|
1130
|
-
and isinstance(prop.property, orm.ColumnProperty)):
|
|
1131
|
-
filters[prop.key] = self.make_filter(prop)
|
|
1158
|
+
prop = getattr(self.model_class, col.key)
|
|
1159
|
+
filters[prop.key] = self.make_filter(prop)
|
|
1132
1160
|
|
|
1133
1161
|
return filters
|
|
1134
1162
|
|
|
@@ -1755,23 +1783,80 @@ class Grid:
|
|
|
1755
1783
|
# rendering methods
|
|
1756
1784
|
##############################
|
|
1757
1785
|
|
|
1786
|
+
def render_batch_id(self, obj, key, value):
|
|
1787
|
+
"""
|
|
1788
|
+
Column renderer for batch ID values.
|
|
1789
|
+
|
|
1790
|
+
This is not used automatically but you can use it explicitly::
|
|
1791
|
+
|
|
1792
|
+
grid.set_renderer('foo', 'batch_id')
|
|
1793
|
+
"""
|
|
1794
|
+
if value is None:
|
|
1795
|
+
return ""
|
|
1796
|
+
|
|
1797
|
+
batch_id = int(value)
|
|
1798
|
+
return f'{batch_id:08d}'
|
|
1799
|
+
|
|
1800
|
+
def render_boolean(self, obj, key, value):
|
|
1801
|
+
"""
|
|
1802
|
+
Column renderer for boolean values.
|
|
1803
|
+
|
|
1804
|
+
This calls
|
|
1805
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_boolean()`
|
|
1806
|
+
for the return value.
|
|
1807
|
+
|
|
1808
|
+
This may be used automatically per
|
|
1809
|
+
:meth:`set_default_renderers()` or you can use it explicitly::
|
|
1810
|
+
|
|
1811
|
+
grid.set_renderer('foo', grid.render_boolean)
|
|
1812
|
+
"""
|
|
1813
|
+
return self.app.render_boolean(value)
|
|
1814
|
+
|
|
1815
|
+
def render_currency(self, obj, key, value, **kwargs):
|
|
1816
|
+
"""
|
|
1817
|
+
Column renderer for currency values.
|
|
1818
|
+
|
|
1819
|
+
This calls
|
|
1820
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_currency()`
|
|
1821
|
+
for the return value.
|
|
1822
|
+
|
|
1823
|
+
This is not used automatically but you can use it explicitly::
|
|
1824
|
+
|
|
1825
|
+
grid.set_renderer('foo', 'currency')
|
|
1826
|
+
grid.set_renderer('foo', 'currency', scale=4)
|
|
1827
|
+
"""
|
|
1828
|
+
return self.app.render_currency(value, **kwargs)
|
|
1829
|
+
|
|
1758
1830
|
def render_datetime(self, obj, key, value):
|
|
1759
1831
|
"""
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
calls
|
|
1832
|
+
Column renderer for :class:`python:datetime.datetime` values.
|
|
1833
|
+
|
|
1834
|
+
This calls
|
|
1763
1835
|
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_datetime()`
|
|
1764
1836
|
for the return value.
|
|
1765
1837
|
|
|
1766
1838
|
This may be used automatically per
|
|
1767
|
-
:meth:`set_default_renderers()` or you can use it explicitly
|
|
1768
|
-
for any :class:`python:datetime.datetime` column with::
|
|
1839
|
+
:meth:`set_default_renderers()` or you can use it explicitly::
|
|
1769
1840
|
|
|
1770
1841
|
grid.set_renderer('foo', grid.render_datetime)
|
|
1771
1842
|
"""
|
|
1772
1843
|
dt = getattr(obj, key)
|
|
1773
1844
|
return self.app.render_datetime(dt)
|
|
1774
1845
|
|
|
1846
|
+
def render_quantity(self, obj, key, value):
|
|
1847
|
+
"""
|
|
1848
|
+
Column renderer for quantity values.
|
|
1849
|
+
|
|
1850
|
+
This calls
|
|
1851
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_quantity()`
|
|
1852
|
+
for the return value.
|
|
1853
|
+
|
|
1854
|
+
This is not used automatically but you can use it explicitly::
|
|
1855
|
+
|
|
1856
|
+
grid.set_renderer('foo', grid.render_quantity)
|
|
1857
|
+
"""
|
|
1858
|
+
return self.app.render_quantity(value)
|
|
1859
|
+
|
|
1775
1860
|
def render_table_element(
|
|
1776
1861
|
self,
|
|
1777
1862
|
form=None,
|
|
@@ -92,6 +92,9 @@ class SessionProgress(ProgressBase):
|
|
|
92
92
|
"""
|
|
93
93
|
|
|
94
94
|
def __init__(self, request, key, success_msg=None, success_url=None, error_url=None):
|
|
95
|
+
self.request = request
|
|
96
|
+
self.config = self.request.wutta_config
|
|
97
|
+
self.app = self.config.get_app()
|
|
95
98
|
self.key = key
|
|
96
99
|
self.success_msg = success_msg
|
|
97
100
|
self.success_url = success_url
|
|
@@ -137,7 +140,7 @@ class SessionProgress(ProgressBase):
|
|
|
137
140
|
"""
|
|
138
141
|
self.session.load()
|
|
139
142
|
self.session['error'] = True
|
|
140
|
-
self.session['error_msg'] =
|
|
143
|
+
self.session['error_msg'] = self.app.render_error(error)
|
|
141
144
|
self.session['error_url'] = error_url or self.error_url
|
|
142
145
|
self.session.save()
|
|
143
146
|
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
## -*- coding: utf-8; -*-
|
|
2
2
|
<%inherit file="/master/view.mako" />
|
|
3
3
|
|
|
4
|
-
<%def name="extra_styles()">
|
|
5
|
-
${parent.extra_styles()}
|
|
6
|
-
<style>
|
|
7
|
-
|
|
8
|
-
## TODO: should we do something like this site-wide?
|
|
9
|
-
## (so far this is the only place we use markdown)
|
|
10
|
-
.markdown p {
|
|
11
|
-
margin-bottom: 1.5rem;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
</style>
|
|
15
|
-
</%def>
|
|
16
|
-
|
|
17
4
|
<%def name="tool_panels()">
|
|
18
5
|
${parent.tool_panels()}
|
|
19
6
|
${self.tool_panel_execution()}
|
|
@@ -65,7 +52,7 @@
|
|
|
65
52
|
<p class="block has-text-weight-bold">
|
|
66
53
|
What will happen when this batch is executed?
|
|
67
54
|
</p>
|
|
68
|
-
<div class="
|
|
55
|
+
<div class="content">
|
|
69
56
|
${execution_described|n}
|
|
70
57
|
</div>
|
|
71
58
|
${h.form(master.get_action_url('execute', batch), ref='executeForm')}
|
|
@@ -33,6 +33,21 @@
|
|
|
33
33
|
% endif
|
|
34
34
|
</%def>
|
|
35
35
|
|
|
36
|
+
<%def name="tool_panels()">
|
|
37
|
+
${parent.tool_panels()}
|
|
38
|
+
${self.tool_panel_xref()}
|
|
39
|
+
</%def>
|
|
40
|
+
|
|
41
|
+
<%def name="tool_panel_xref()">
|
|
42
|
+
% if xref_buttons:
|
|
43
|
+
<wutta-tool-panel heading="Cross-Reference">
|
|
44
|
+
% for button in xref_buttons:
|
|
45
|
+
${button}
|
|
46
|
+
% endfor
|
|
47
|
+
</wutta-tool-panel>
|
|
48
|
+
% endif
|
|
49
|
+
</%def>
|
|
50
|
+
|
|
36
51
|
<%def name="render_vue_templates()">
|
|
37
52
|
${parent.render_vue_templates()}
|
|
38
53
|
% if master.has_rows:
|