WuttaWeb 0.19.0__tar.gz → 0.19.2__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.2}/CHANGELOG.md +30 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/PKG-INFO +2 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/pyproject.toml +2 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/forms/schema.py +69 -19
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/forms/widgets.py +44 -7
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/grids/base.py +125 -28
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/progress.py +4 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/base.mako +2 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/batch/view.mako +1 -14
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/view.mako +15 -0
- wuttaweb-0.19.0/tests/util.py → wuttaweb-0.19.2/src/wuttaweb/testing.py +26 -39
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/util.py +33 -6
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/batch.py +11 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/master.py +87 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/db/test_continuum.py +1 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/forms/test_schema.py +152 -94
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/forms/test_widgets.py +132 -93
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/grids/test_base.py +96 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/grids/test_filters.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_auth.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_handler.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_menus.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_progress.py +5 -2
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_util.py +17 -6
- wuttaweb-0.19.2/tests/util.py +40 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test___init__.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_auth.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_base.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_batch.py +7 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_common.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_email.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_essential.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_master.py +51 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_people.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_progress.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_roles.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_settings.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_upgrades.py +1 -1
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/views/test_users.py +1 -1
- wuttaweb-0.19.0/tests/views/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/.gitignore +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/COPYING.txt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/README.md +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/Makefile +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/_static/.keepme +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.app.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.auth.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.cli.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.cli.webapp.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.conf.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.db.continuum.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.db.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.db.sess.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.emails.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.forms.base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.forms.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.forms.schema.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.forms.widgets.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.grids.base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.grids.filters.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.grids.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.handler.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.helpers.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.menus.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.progress.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.static.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.subscribers.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.util.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.auth.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.batch.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.common.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.email.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.essential.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.master.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.people.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.progress.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.roles.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.settings.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.upgrades.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/api/wuttaweb.views.users.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/conf.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/glossary.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/index.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/make.bat +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/narr/cli/builtin.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/narr/cli/index.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/narr/templates/base.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/narr/templates/index.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/narr/templates/lookup.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/docs/narr/templates/overview.rst +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/_version.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/app.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/auth.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/cli/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/cli/webapp.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/conf.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/db/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/db/continuum.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/db/sess.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/emails.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/forms/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/forms/base.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/grids/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/grids/filters.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/handler.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/helpers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/menus.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/static/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/static/img/favicon.ico +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/static/img/logo.png +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/static/img/testing.png +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/subscribers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/appinfo/index.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/auth/change_password.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/auth/login.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/base_meta.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/dateinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/datetimeinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/password.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/permissions.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/select.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/textarea.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/deform/textinput.pt +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/email/settings/view.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/forbidden.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/form.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/grids/table_element.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/home.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/create.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/delete.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/edit.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/form.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/master/index.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/notfound.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/page.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/people/view_profile.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/progress.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/setup.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/upgrade.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/upgrades/view.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/templates/wutta-components.mako +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/auth.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/base.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/common.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/email.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/essential.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/people.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/progress.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/roles.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/settings.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/upgrades.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/src/wuttaweb/views/users.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tasks.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/cli/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/cli/test_webapp.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/db/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/forms/test_base.py +0 -0
- {wuttaweb-0.19.0/tests/forms → wuttaweb-0.19.2/tests/grids}/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_oruga.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_oruga_bulma.css +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_oruga_bulma.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_vue.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/bb_vue_fontawesome.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/buefy.css +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/buefy.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/fontawesome.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/vue.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/libcache/vue_resource.js +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_app.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_emails.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_helpers.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_static.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tests/test_subscribers.py +0 -0
- {wuttaweb-0.19.0/tests/grids → wuttaweb-0.19.2/tests/views}/__init__.py +0 -0
- {wuttaweb-0.19.0 → wuttaweb-0.19.2}/tox.ini +0 -0
|
@@ -5,6 +5,36 @@ 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.2 (2025-01-07)
|
|
9
|
+
|
|
10
|
+
### Fix
|
|
11
|
+
|
|
12
|
+
- always use prop key for default grid filters
|
|
13
|
+
- avoid `request.current_route_url()` for user menu
|
|
14
|
+
- add `scale` kwarg for `WuttaMoney` schema type, widget
|
|
15
|
+
- make WuttaQuantity serialize w/ app handler, remove custom widget
|
|
16
|
+
- bugfix for bool simple settings with default value
|
|
17
|
+
|
|
18
|
+
## v0.19.1 (2025-01-06)
|
|
19
|
+
|
|
20
|
+
### Fix
|
|
21
|
+
|
|
22
|
+
- improve built-in grid renderer logic
|
|
23
|
+
- allow session injection for ObjectRef constructor
|
|
24
|
+
- improve rendering for batch row status
|
|
25
|
+
- add basic support for row grid "view" action links
|
|
26
|
+
- add "xref buttons" tool panel for master view
|
|
27
|
+
- add WuttaQuantity schema type, widget
|
|
28
|
+
- remove `session` param from some form schema, widget classes
|
|
29
|
+
- add grid renderers for bool, currency, quantity
|
|
30
|
+
- use proper bulma styles for markdown content
|
|
31
|
+
- use span element for readonly money field widget render
|
|
32
|
+
- include grid filters for all column properties of model class
|
|
33
|
+
- use app handler to render error string, when progress fails
|
|
34
|
+
- add schema node type, widget for "money" (currency) fields
|
|
35
|
+
- exclude FK fields by default, for model forms
|
|
36
|
+
- fix style for header title text
|
|
37
|
+
|
|
8
38
|
## v0.19.0 (2024-12-23)
|
|
9
39
|
|
|
10
40
|
### Feat
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: WuttaWeb
|
|
3
|
-
Version: 0.19.
|
|
3
|
+
Version: 0.19.2
|
|
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
|
|
@@ -39,7 +39,7 @@ Requires-Dist: pyramid-tm
|
|
|
39
39
|
Requires-Dist: pyramid>=2
|
|
40
40
|
Requires-Dist: waitress
|
|
41
41
|
Requires-Dist: webhelpers2
|
|
42
|
-
Requires-Dist: wuttjamaican[db]>=0.19.
|
|
42
|
+
Requires-Dist: wuttjamaican[db]>=0.19.2
|
|
43
43
|
Requires-Dist: zope-sqlalchemy>=1.5
|
|
44
44
|
Provides-Extra: continuum
|
|
45
45
|
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.2"
|
|
10
10
|
description = "Web App for Wutta Framework"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
|
@@ -44,7 +44,7 @@ dependencies = [
|
|
|
44
44
|
"pyramid_tm",
|
|
45
45
|
"waitress",
|
|
46
46
|
"WebHelpers2",
|
|
47
|
-
"WuttJamaican[db]>=0.19.
|
|
47
|
+
"WuttJamaican[db]>=0.19.2",
|
|
48
48
|
"zope.sqlalchemy>=1.5",
|
|
49
49
|
]
|
|
50
50
|
|
|
@@ -155,25 +155,75 @@ 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
|
+
:param scale: If this kwarg is specified, it will be passed along
|
|
169
|
+
to the widget constructor.
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
def __init__(self, request, *args, **kwargs):
|
|
173
|
+
self.scale = kwargs.pop('scale', None)
|
|
174
|
+
super().__init__(*args, **kwargs)
|
|
175
|
+
self.request = request
|
|
176
|
+
self.config = self.request.wutta_config
|
|
177
|
+
self.app = self.config.get_app()
|
|
178
|
+
|
|
179
|
+
def widget_maker(self, **kwargs):
|
|
180
|
+
""" """
|
|
181
|
+
if self.scale:
|
|
182
|
+
kwargs.setdefault('scale', self.scale)
|
|
183
|
+
return widgets.WuttaMoneyInputWidget(self.request, **kwargs)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class WuttaQuantity(colander.Decimal):
|
|
187
|
+
"""
|
|
188
|
+
Custom schema type for "quantity" fields.
|
|
189
|
+
|
|
190
|
+
This is a subclass of :class:`colander:colander.Decimal` but will
|
|
191
|
+
serialize values via
|
|
192
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_quantity()`.
|
|
193
|
+
|
|
194
|
+
:param request: Current :term:`request` object.
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
def __init__(self, request, *args, **kwargs):
|
|
198
|
+
super().__init__(*args, **kwargs)
|
|
199
|
+
self.request = request
|
|
200
|
+
self.config = self.request.wutta_config
|
|
201
|
+
self.app = self.config.get_app()
|
|
202
|
+
|
|
203
|
+
def serialize(self, node, appstruct):
|
|
204
|
+
""" """
|
|
205
|
+
if appstruct in (colander.null, None):
|
|
206
|
+
return colander.null
|
|
207
|
+
|
|
208
|
+
# nb. we render as quantity here to avoid values like 12.0000,
|
|
209
|
+
# so we just show value like 12 instead
|
|
210
|
+
return self.app.render_quantity(appstruct)
|
|
211
|
+
|
|
212
|
+
|
|
158
213
|
class WuttaSet(colander.Set):
|
|
159
214
|
"""
|
|
160
215
|
Custom schema type for :class:`python:set` fields.
|
|
161
216
|
|
|
162
|
-
This is a subclass of :class:`colander.Set
|
|
163
|
-
Wutta-related params to the constructor.
|
|
217
|
+
This is a subclass of :class:`colander.Set`.
|
|
164
218
|
|
|
165
219
|
: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
220
|
"""
|
|
170
221
|
|
|
171
|
-
def __init__(self, request
|
|
222
|
+
def __init__(self, request):
|
|
172
223
|
super().__init__()
|
|
173
224
|
self.request = request
|
|
174
225
|
self.config = self.request.wutta_config
|
|
175
226
|
self.app = self.config.get_app()
|
|
176
|
-
self.session = session or Session()
|
|
177
227
|
|
|
178
228
|
|
|
179
229
|
class ObjectRef(colander.SchemaType):
|
|
@@ -209,16 +259,16 @@ class ObjectRef(colander.SchemaType):
|
|
|
209
259
|
self,
|
|
210
260
|
request,
|
|
211
261
|
empty_option=None,
|
|
212
|
-
session=None,
|
|
213
262
|
*args,
|
|
214
263
|
**kwargs,
|
|
215
264
|
):
|
|
265
|
+
# nb. allow session injection for tests
|
|
266
|
+
self.session = kwargs.pop('session', Session())
|
|
216
267
|
super().__init__(*args, **kwargs)
|
|
217
268
|
self.request = request
|
|
218
269
|
self.config = self.request.wutta_config
|
|
219
270
|
self.app = self.config.get_app()
|
|
220
271
|
self.model_instance = None
|
|
221
|
-
self.session = session or Session()
|
|
222
272
|
|
|
223
273
|
if empty_option:
|
|
224
274
|
if empty_option is True:
|
|
@@ -450,7 +500,7 @@ class RoleRefs(WuttaSet):
|
|
|
450
500
|
:returns: Instance of
|
|
451
501
|
:class:`~wuttaweb.forms.widgets.RoleRefsWidget`.
|
|
452
502
|
"""
|
|
453
|
-
kwargs.setdefault('session',
|
|
503
|
+
session = kwargs.setdefault('session', Session())
|
|
454
504
|
|
|
455
505
|
if 'values' not in kwargs:
|
|
456
506
|
model = self.app.model
|
|
@@ -458,20 +508,20 @@ class RoleRefs(WuttaSet):
|
|
|
458
508
|
|
|
459
509
|
# avoid built-ins which cannot be assigned to users
|
|
460
510
|
avoid = {
|
|
461
|
-
auth.get_role_authenticated(
|
|
462
|
-
auth.get_role_anonymous(
|
|
511
|
+
auth.get_role_authenticated(session),
|
|
512
|
+
auth.get_role_anonymous(session),
|
|
463
513
|
}
|
|
464
514
|
avoid = set([role.uuid for role in avoid])
|
|
465
515
|
|
|
466
516
|
# also avoid admin unless current user is root
|
|
467
517
|
if not self.request.is_root:
|
|
468
|
-
avoid.add(auth.get_role_administrator(
|
|
518
|
+
avoid.add(auth.get_role_administrator(session).uuid)
|
|
469
519
|
|
|
470
520
|
# everything else can be (un)assigned for users
|
|
471
|
-
roles =
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
521
|
+
roles = session.query(model.Role)\
|
|
522
|
+
.filter(~model.Role.uuid.in_(avoid))\
|
|
523
|
+
.order_by(model.Role.name)\
|
|
524
|
+
.all()
|
|
475
525
|
values = [(role.uuid.hex, role.name) for role in roles]
|
|
476
526
|
kwargs['values'] = values
|
|
477
527
|
|
|
@@ -496,7 +546,7 @@ class UserRefs(WuttaSet):
|
|
|
496
546
|
:returns: Instance of
|
|
497
547
|
:class:`~wuttaweb.forms.widgets.UserRefsWidget`.
|
|
498
548
|
"""
|
|
499
|
-
kwargs.setdefault('session',
|
|
549
|
+
kwargs.setdefault('session', Session())
|
|
500
550
|
return widgets.UserRefsWidget(self.request, **kwargs)
|
|
501
551
|
|
|
502
552
|
|
|
@@ -526,7 +576,7 @@ class Permissions(WuttaSet):
|
|
|
526
576
|
:returns: Instance of
|
|
527
577
|
:class:`~wuttaweb.forms.widgets.PermissionsWidget`.
|
|
528
578
|
"""
|
|
529
|
-
kwargs.setdefault('session',
|
|
579
|
+
kwargs.setdefault('session', Session())
|
|
530
580
|
kwargs.setdefault('permissions', self.permissions)
|
|
531
581
|
|
|
532
582
|
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,47 @@ 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
|
+
:param scale: If this kwarg is specified, it will be passed along
|
|
211
|
+
to ``render_currency()`` call.
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
def __init__(self, request, *args, **kwargs):
|
|
215
|
+
self.scale = kwargs.pop('scale', 2)
|
|
216
|
+
super().__init__(*args, **kwargs)
|
|
217
|
+
self.request = request
|
|
218
|
+
self.config = self.request.wutta_config
|
|
219
|
+
self.app = self.config.get_app()
|
|
220
|
+
|
|
221
|
+
def serialize(self, field, cstruct, **kw):
|
|
222
|
+
""" """
|
|
223
|
+
readonly = kw.get('readonly', self.readonly)
|
|
224
|
+
if readonly:
|
|
225
|
+
if cstruct in (colander.null, None):
|
|
226
|
+
return HTML.tag('span')
|
|
227
|
+
cstruct = decimal.Decimal(cstruct)
|
|
228
|
+
text = self.app.render_currency(cstruct, scale=self.scale)
|
|
229
|
+
return HTML.tag('span', c=[text])
|
|
230
|
+
|
|
231
|
+
return super().serialize(field, cstruct, **kw)
|
|
232
|
+
|
|
233
|
+
|
|
197
234
|
class FileDownloadWidget(Widget):
|
|
198
235
|
"""
|
|
199
236
|
Widget for use with :class:`~wuttaweb.forms.schema.FileDownload`
|
|
@@ -115,7 +115,8 @@ class Grid:
|
|
|
115
115
|
|
|
116
116
|
Dict of column (cell) value renderer overrides.
|
|
117
117
|
|
|
118
|
-
See also :meth:`set_renderer()
|
|
118
|
+
See also :meth:`set_renderer()` and
|
|
119
|
+
:meth:`set_default_renderers()`.
|
|
119
120
|
|
|
120
121
|
.. attribute:: row_class
|
|
121
122
|
|
|
@@ -387,7 +388,6 @@ class Grid:
|
|
|
387
388
|
self.key = key
|
|
388
389
|
self.data = data
|
|
389
390
|
self.labels = labels or {}
|
|
390
|
-
self.renderers = renderers or {}
|
|
391
391
|
self.row_class = row_class
|
|
392
392
|
self.actions = actions or []
|
|
393
393
|
self.linked_columns = linked_columns or []
|
|
@@ -397,6 +397,10 @@ class Grid:
|
|
|
397
397
|
self.app = self.config.get_app()
|
|
398
398
|
|
|
399
399
|
self.set_columns(columns or self.get_columns())
|
|
400
|
+
self.renderers = {}
|
|
401
|
+
if renderers:
|
|
402
|
+
for key, val in renderers.items():
|
|
403
|
+
self.set_renderer(key, val)
|
|
400
404
|
self.set_default_renderers()
|
|
401
405
|
self.set_tools(tools)
|
|
402
406
|
|
|
@@ -591,8 +595,29 @@ class Grid:
|
|
|
591
595
|
grid = Grid(request, columns=['foo', 'bar'])
|
|
592
596
|
grid.set_renderer('foo', render_foo)
|
|
593
597
|
|
|
598
|
+
For convenience, in lieu of a renderer callable, you may
|
|
599
|
+
specify one of the following strings, which will be
|
|
600
|
+
interpreted as a built-in renderer callable, as shown below:
|
|
601
|
+
|
|
602
|
+
* ``'batch_id'`` -> :meth:`render_batch_id()`
|
|
603
|
+
* ``'boolean'`` -> :meth:`render_boolean()`
|
|
604
|
+
* ``'currency'`` -> :meth:`render_currency()`
|
|
605
|
+
* ``'datetime'`` -> :meth:`render_datetime()`
|
|
606
|
+
* ``'quantity'`` -> :meth:`render_quantity()`
|
|
607
|
+
|
|
594
608
|
Renderer overrides are tracked via :attr:`renderers`.
|
|
595
609
|
"""
|
|
610
|
+
builtins = {
|
|
611
|
+
'batch_id': self.render_batch_id,
|
|
612
|
+
'boolean': self.render_boolean,
|
|
613
|
+
'currency': self.render_currency,
|
|
614
|
+
'datetime': self.render_datetime,
|
|
615
|
+
'quantity': self.render_quantity,
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if renderer in builtins:
|
|
619
|
+
renderer = builtins[renderer]
|
|
620
|
+
|
|
596
621
|
if kwargs:
|
|
597
622
|
renderer = functools.partial(renderer, **kwargs)
|
|
598
623
|
self.renderers[key] = renderer
|
|
@@ -601,15 +626,18 @@ class Grid:
|
|
|
601
626
|
"""
|
|
602
627
|
Set default column value renderers, where applicable.
|
|
603
628
|
|
|
604
|
-
This
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
to a
|
|
629
|
+
This is called automatically from the class constructor. It
|
|
630
|
+
will add new entries to :attr:`renderers` for columns whose
|
|
631
|
+
data type implies a default renderer. This is only possible
|
|
632
|
+
if :attr:`model_class` is set to a SQLAlchemy mapped class.
|
|
633
|
+
|
|
634
|
+
This only looks for a couple of data types, and configures as
|
|
635
|
+
follows:
|
|
608
636
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
637
|
+
* :class:`sqlalchemy:sqlalchemy.types.Boolean` ->
|
|
638
|
+
:meth:`render_boolean()`
|
|
639
|
+
* :class:`sqlalchemy:sqlalchemy.types.DateTime` ->
|
|
640
|
+
:meth:`render_datetime()`
|
|
613
641
|
"""
|
|
614
642
|
if not self.model_class:
|
|
615
643
|
return
|
|
@@ -625,6 +653,8 @@ class Grid:
|
|
|
625
653
|
column = prop.columns[0]
|
|
626
654
|
if isinstance(column.type, sa.DateTime):
|
|
627
655
|
self.set_renderer(key, self.render_datetime)
|
|
656
|
+
elif isinstance(column.type, sa.Boolean):
|
|
657
|
+
self.set_renderer(key, self.render_boolean)
|
|
628
658
|
|
|
629
659
|
def set_link(self, key, link=True):
|
|
630
660
|
"""
|
|
@@ -1116,19 +1146,29 @@ class Grid:
|
|
|
1116
1146
|
filters = filters or {}
|
|
1117
1147
|
|
|
1118
1148
|
if self.model_class:
|
|
1119
|
-
|
|
1120
|
-
#
|
|
1121
|
-
#
|
|
1122
|
-
#
|
|
1123
|
-
#
|
|
1124
|
-
#
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1149
|
+
|
|
1150
|
+
# nb. i have found this confusing for some reason. some
|
|
1151
|
+
# things i've tried so far include:
|
|
1152
|
+
#
|
|
1153
|
+
# i first tried self.get_model_columns() but my notes say
|
|
1154
|
+
# that was too aggressive in many cases.
|
|
1155
|
+
#
|
|
1156
|
+
# then i tried using the *subset* of self.columns, just
|
|
1157
|
+
# the ones which correspond to a property on the model
|
|
1158
|
+
# class. but sometimes that skips filters we need.
|
|
1159
|
+
#
|
|
1160
|
+
# then i tried get_columns() from sa-utils to give the
|
|
1161
|
+
# "true" column list, but that fails when the underlying
|
|
1162
|
+
# column has different name than the prop/attr key.
|
|
1163
|
+
#
|
|
1164
|
+
# so now, we are looking directly at the sa mapper, for
|
|
1165
|
+
# all column attrs and then using the prop key.
|
|
1166
|
+
|
|
1167
|
+
inspector = sa.inspect(self.model_class)
|
|
1168
|
+
for prop in inspector.column_attrs:
|
|
1169
|
+
if prop.key not in filters:
|
|
1170
|
+
attr = getattr(self.model_class, prop.key)
|
|
1171
|
+
filters[prop.key] = self.make_filter(attr)
|
|
1132
1172
|
|
|
1133
1173
|
return filters
|
|
1134
1174
|
|
|
@@ -1755,23 +1795,80 @@ class Grid:
|
|
|
1755
1795
|
# rendering methods
|
|
1756
1796
|
##############################
|
|
1757
1797
|
|
|
1798
|
+
def render_batch_id(self, obj, key, value):
|
|
1799
|
+
"""
|
|
1800
|
+
Column renderer for batch ID values.
|
|
1801
|
+
|
|
1802
|
+
This is not used automatically but you can use it explicitly::
|
|
1803
|
+
|
|
1804
|
+
grid.set_renderer('foo', 'batch_id')
|
|
1805
|
+
"""
|
|
1806
|
+
if value is None:
|
|
1807
|
+
return ""
|
|
1808
|
+
|
|
1809
|
+
batch_id = int(value)
|
|
1810
|
+
return f'{batch_id:08d}'
|
|
1811
|
+
|
|
1812
|
+
def render_boolean(self, obj, key, value):
|
|
1813
|
+
"""
|
|
1814
|
+
Column renderer for boolean values.
|
|
1815
|
+
|
|
1816
|
+
This calls
|
|
1817
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_boolean()`
|
|
1818
|
+
for the return value.
|
|
1819
|
+
|
|
1820
|
+
This may be used automatically per
|
|
1821
|
+
:meth:`set_default_renderers()` or you can use it explicitly::
|
|
1822
|
+
|
|
1823
|
+
grid.set_renderer('foo', grid.render_boolean)
|
|
1824
|
+
"""
|
|
1825
|
+
return self.app.render_boolean(value)
|
|
1826
|
+
|
|
1827
|
+
def render_currency(self, obj, key, value, **kwargs):
|
|
1828
|
+
"""
|
|
1829
|
+
Column renderer for currency values.
|
|
1830
|
+
|
|
1831
|
+
This calls
|
|
1832
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_currency()`
|
|
1833
|
+
for the return value.
|
|
1834
|
+
|
|
1835
|
+
This is not used automatically but you can use it explicitly::
|
|
1836
|
+
|
|
1837
|
+
grid.set_renderer('foo', 'currency')
|
|
1838
|
+
grid.set_renderer('foo', 'currency', scale=4)
|
|
1839
|
+
"""
|
|
1840
|
+
return self.app.render_currency(value, **kwargs)
|
|
1841
|
+
|
|
1758
1842
|
def render_datetime(self, obj, key, value):
|
|
1759
1843
|
"""
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
calls
|
|
1844
|
+
Column renderer for :class:`python:datetime.datetime` values.
|
|
1845
|
+
|
|
1846
|
+
This calls
|
|
1763
1847
|
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_datetime()`
|
|
1764
1848
|
for the return value.
|
|
1765
1849
|
|
|
1766
1850
|
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::
|
|
1851
|
+
:meth:`set_default_renderers()` or you can use it explicitly::
|
|
1769
1852
|
|
|
1770
1853
|
grid.set_renderer('foo', grid.render_datetime)
|
|
1771
1854
|
"""
|
|
1772
1855
|
dt = getattr(obj, key)
|
|
1773
1856
|
return self.app.render_datetime(dt)
|
|
1774
1857
|
|
|
1858
|
+
def render_quantity(self, obj, key, value):
|
|
1859
|
+
"""
|
|
1860
|
+
Column renderer for quantity values.
|
|
1861
|
+
|
|
1862
|
+
This calls
|
|
1863
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_quantity()`
|
|
1864
|
+
for the return value.
|
|
1865
|
+
|
|
1866
|
+
This is not used automatically but you can use it explicitly::
|
|
1867
|
+
|
|
1868
|
+
grid.set_renderer('foo', grid.render_quantity)
|
|
1869
|
+
"""
|
|
1870
|
+
return self.app.render_quantity(value)
|
|
1871
|
+
|
|
1775
1872
|
def render_table_element(
|
|
1776
1873
|
self,
|
|
1777
1874
|
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
|
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
#content-title h1 {
|
|
158
|
-
max-width:
|
|
158
|
+
max-width: 80%;
|
|
159
159
|
overflow: hidden;
|
|
160
160
|
padding-left: 0.5rem;
|
|
161
161
|
text-overflow: ellipsis;
|
|
@@ -659,7 +659,7 @@
|
|
|
659
659
|
% if request.is_root:
|
|
660
660
|
${h.form(url('stop_root'), ref='stopBeingRootForm')}
|
|
661
661
|
${h.csrf_token(request)}
|
|
662
|
-
<input type="hidden" name="referrer" value="${request.
|
|
662
|
+
<input type="hidden" name="referrer" value="${request.url}" />
|
|
663
663
|
<a @click="stopBeingRoot()"
|
|
664
664
|
class="navbar-item has-background-danger has-text-white">
|
|
665
665
|
Stop being root
|
|
@@ -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:
|