WuttaWeb 0.20.4__tar.gz → 0.20.6__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.20.4 → wuttaweb-0.20.6}/CHANGELOG.md +22 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/PKG-INFO +2 -2
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/pyproject.toml +2 -2
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/cli/webapp.py +1 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/forms/base.py +3 -2
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/grids/base.py +23 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/menus.py +3 -1
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/base.mako +16 -7
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/grids/vue_template.mako +12 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/page.mako +1 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/common.py +13 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/master.py +8 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/roles.py +35 -4
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/cli/test_webapp.py +4 -2
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/grids/test_base.py +20 -2
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_roles.py +22 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/.gitignore +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/COPYING.txt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/README.md +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/Makefile +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/_static/.keepme +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.app.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.auth.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.cli.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.cli.webapp.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.conf.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.db.continuum.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.db.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.db.sess.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.emails.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.forms.base.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.forms.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.forms.schema.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.forms.widgets.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.grids.base.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.grids.filters.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.grids.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.handler.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.helpers.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.menus.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.progress.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.static.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.subscribers.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.util.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.auth.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.base.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.batch.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.common.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.email.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.essential.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.master.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.people.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.progress.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.reports.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.roles.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.settings.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.upgrades.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/api/wuttaweb.views.users.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/conf.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/glossary.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/index.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/make.bat +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/narr/cli/builtin.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/narr/cli/index.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/narr/templates/base.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/narr/templates/index.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/narr/templates/lookup.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/docs/narr/templates/overview.rst +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/_version.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/app.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/auth.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/cli/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/conf.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/db/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/db/continuum.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/db/sess.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/emails.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/forms/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/forms/schema.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/forms/widgets.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/grids/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/grids/filters.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/handler.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/helpers.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/progress.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/static/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/static/img/favicon.ico +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/static/img/logo.png +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/static/img/testing.png +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/subscribers.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/appinfo/index.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/auth/change_password.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/auth/login.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/base_meta.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/batch/view.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/configure.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/dateinput.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/datetimeinput.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/password.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/permissions.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/select.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/textarea.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/deform/textinput.pt +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/email/settings/view.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/forbidden.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/form.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/grids/table_element.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/home.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/configure.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/create.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/delete.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/edit.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/form.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/index.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/master/view.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/notfound.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/people/view_profile.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/progress.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/reports/view.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/setup.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/upgrade.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/upgrades/view.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/templates/wutta-components.mako +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/testing.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/util.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/auth.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/base.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/batch.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/email.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/essential.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/people.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/progress.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/reports.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/settings.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/upgrades.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/src/wuttaweb/views/users.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tasks.py +0 -0
- {wuttaweb-0.20.4/tests/views → wuttaweb-0.20.6/tests}/__init__.py +0 -0
- {wuttaweb-0.20.4/tests/grids → wuttaweb-0.20.6/tests/cli}/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/db/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/db/test_continuum.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/forms/test_base.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/forms/test_schema.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/forms/test_widgets.py +0 -0
- {wuttaweb-0.20.4/tests/cli → wuttaweb-0.20.6/tests/grids}/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/grids/test_filters.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_oruga.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_oruga_bulma.css +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_oruga_bulma.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_vue.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/bb_vue_fontawesome.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/buefy.css +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/buefy.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/fontawesome.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/vue.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/libcache/vue_resource.js +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_app.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_auth.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_emails.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_handler.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_helpers.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_menus.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_progress.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_static.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_subscribers.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/test_util.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/util.py +0 -0
- {wuttaweb-0.20.4/tests → wuttaweb-0.20.6/tests/views}/__init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test___init__.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_auth.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_base.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_batch.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_common.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_email.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_essential.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_master.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_people.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_progress.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_reports.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_settings.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_upgrades.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tests/views/test_users.py +0 -0
- {wuttaweb-0.20.4 → wuttaweb-0.20.6}/tox.ini +0 -0
|
@@ -5,6 +5,28 @@ 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.20.6 (2025-01-26)
|
|
9
|
+
|
|
10
|
+
### Fix
|
|
11
|
+
|
|
12
|
+
- add `setup_enhance_admin_user()` method for initial setup
|
|
13
|
+
- add `render_percent()` method for Grid
|
|
14
|
+
- allow override for Admin menu title
|
|
15
|
+
- add `index_title_controls()` def block for base template
|
|
16
|
+
- add `make_users_grid()` method for RoleView
|
|
17
|
+
- fallback to empty string for uvicorn `root_path`
|
|
18
|
+
- add `root_path` config setting for running webapp via uvicorn
|
|
19
|
+
|
|
20
|
+
## v0.20.5 (2025-01-23)
|
|
21
|
+
|
|
22
|
+
### Fix
|
|
23
|
+
|
|
24
|
+
- improve styling for grid tools section
|
|
25
|
+
- add basic checkbox support for grids
|
|
26
|
+
- add WuttaRequestMixin for ThisPage component
|
|
27
|
+
- avoid literal `None` when rendering form field value
|
|
28
|
+
- let header title be even wider
|
|
29
|
+
|
|
8
30
|
## v0.20.4 (2025-01-15)
|
|
9
31
|
|
|
10
32
|
### Fix
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: WuttaWeb
|
|
3
|
-
Version: 0.20.
|
|
3
|
+
Version: 0.20.6
|
|
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.20.
|
|
42
|
+
Requires-Dist: wuttjamaican[db]>=0.20.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.20.
|
|
9
|
+
version = "0.20.6"
|
|
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.20.
|
|
47
|
+
"WuttJamaican[db]>=0.20.2",
|
|
48
48
|
"zope.sqlalchemy>=1.5",
|
|
49
49
|
]
|
|
50
50
|
|
|
@@ -74,6 +74,7 @@ def webapp(
|
|
|
74
74
|
'reload_dirs': config.get_list(f'{config.appname}.web.app.reload_dirs'),
|
|
75
75
|
'factory': config.get_bool(f'{config.appname}.web.app.factory', default=False),
|
|
76
76
|
'interface': config.get(f'{config.appname}.web.app.interface', default='auto'),
|
|
77
|
+
'root_path': config.get(f'{config.appname}.web.app.root_path', default=''),
|
|
77
78
|
}
|
|
78
79
|
|
|
79
80
|
# also must inject our config files to env, since there is no
|
|
@@ -1033,12 +1033,13 @@ class Form:
|
|
|
1033
1033
|
# render static text if field not in deform/schema
|
|
1034
1034
|
# TODO: need to abstract this somehow
|
|
1035
1035
|
if self.model_instance:
|
|
1036
|
-
|
|
1036
|
+
value = self.model_instance[fieldname]
|
|
1037
|
+
html = str(value) if value is not None else ''
|
|
1037
1038
|
else:
|
|
1038
1039
|
html = ''
|
|
1039
1040
|
|
|
1040
1041
|
# mark all that as safe
|
|
1041
|
-
html = HTML.literal(html)
|
|
1042
|
+
html = HTML.literal(html or ' ')
|
|
1042
1043
|
|
|
1043
1044
|
# render field label
|
|
1044
1045
|
label = self.get_label(fieldname)
|
|
@@ -118,6 +118,11 @@ class Grid:
|
|
|
118
118
|
See also :meth:`set_renderer()` and
|
|
119
119
|
:meth:`set_default_renderers()`.
|
|
120
120
|
|
|
121
|
+
.. attribute:: checkable
|
|
122
|
+
|
|
123
|
+
Boolean indicating whether the grid should expose per-row
|
|
124
|
+
checkboxes.
|
|
125
|
+
|
|
121
126
|
.. attribute:: row_class
|
|
122
127
|
|
|
123
128
|
This represents the CSS ``class`` attribute for a row within
|
|
@@ -362,6 +367,7 @@ class Grid:
|
|
|
362
367
|
data=None,
|
|
363
368
|
labels={},
|
|
364
369
|
renderers={},
|
|
370
|
+
checkable=False,
|
|
365
371
|
row_class=None,
|
|
366
372
|
actions=[],
|
|
367
373
|
linked_columns=[],
|
|
@@ -388,6 +394,7 @@ class Grid:
|
|
|
388
394
|
self.key = key
|
|
389
395
|
self.data = data
|
|
390
396
|
self.labels = labels or {}
|
|
397
|
+
self.checkable = checkable
|
|
391
398
|
self.row_class = row_class
|
|
392
399
|
self.actions = actions or []
|
|
393
400
|
self.linked_columns = linked_columns or []
|
|
@@ -605,6 +612,7 @@ class Grid:
|
|
|
605
612
|
* ``'date'`` -> :meth:`render_date()`
|
|
606
613
|
* ``'datetime'`` -> :meth:`render_datetime()`
|
|
607
614
|
* ``'quantity'`` -> :meth:`render_quantity()`
|
|
615
|
+
* ``'percent'`` -> :meth:`render_percent()`
|
|
608
616
|
|
|
609
617
|
Renderer overrides are tracked via :attr:`renderers`.
|
|
610
618
|
"""
|
|
@@ -615,6 +623,7 @@ class Grid:
|
|
|
615
623
|
'date': self.render_date,
|
|
616
624
|
'datetime': self.render_datetime,
|
|
617
625
|
'quantity': self.render_quantity,
|
|
626
|
+
'percent': self.render_percent,
|
|
618
627
|
}
|
|
619
628
|
|
|
620
629
|
if renderer in builtins:
|
|
@@ -1877,6 +1886,20 @@ class Grid:
|
|
|
1877
1886
|
dt = getattr(obj, key)
|
|
1878
1887
|
return self.app.render_datetime(dt)
|
|
1879
1888
|
|
|
1889
|
+
def render_percent(self, obj, key, value, **kwargs):
|
|
1890
|
+
"""
|
|
1891
|
+
Column renderer for percentage values.
|
|
1892
|
+
|
|
1893
|
+
This calls
|
|
1894
|
+
:meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_percent()`
|
|
1895
|
+
for the return value.
|
|
1896
|
+
|
|
1897
|
+
This is not used automatically but you can use it explicitly::
|
|
1898
|
+
|
|
1899
|
+
grid.set_renderer('foo', 'percent')
|
|
1900
|
+
"""
|
|
1901
|
+
return self.app.render_percent(value, **kwargs)
|
|
1902
|
+
|
|
1880
1903
|
def render_quantity(self, obj, key, value):
|
|
1881
1904
|
"""
|
|
1882
1905
|
Column renderer for quantity values.
|
|
@@ -143,6 +143,8 @@ class MenuHandler(GenericHandler):
|
|
|
143
143
|
which will ultimately be one element of the final list of
|
|
144
144
|
dicts as described in :class:`MenuHandler`.
|
|
145
145
|
|
|
146
|
+
:param title: Override the menu title; default is "Admin".
|
|
147
|
+
|
|
146
148
|
:param include_people: You can pass this flag to indicate the
|
|
147
149
|
admin menu should contain an entry for the "People" view.
|
|
148
150
|
"""
|
|
@@ -198,7 +200,7 @@ class MenuHandler(GenericHandler):
|
|
|
198
200
|
])
|
|
199
201
|
|
|
200
202
|
return {
|
|
201
|
-
'title': "Admin",
|
|
203
|
+
'title': kwargs.get('title', "Admin"),
|
|
202
204
|
'type': 'menu',
|
|
203
205
|
'items': items,
|
|
204
206
|
}
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
#content-title h1 {
|
|
158
|
-
max-width:
|
|
158
|
+
max-width: 95%;
|
|
159
159
|
overflow: hidden;
|
|
160
160
|
padding-left: 0.5rem;
|
|
161
161
|
text-overflow: ellipsis;
|
|
@@ -186,6 +186,11 @@
|
|
|
186
186
|
width: 100%;
|
|
187
187
|
}
|
|
188
188
|
|
|
189
|
+
.wutta-grid-tools-wrapper {
|
|
190
|
+
display: flex;
|
|
191
|
+
gap: 0.5rem;
|
|
192
|
+
}
|
|
193
|
+
|
|
189
194
|
##############################
|
|
190
195
|
## forms
|
|
191
196
|
##############################
|
|
@@ -243,12 +248,7 @@
|
|
|
243
248
|
% else:
|
|
244
249
|
<h1 class="title">${index_title}</h1>
|
|
245
250
|
% endif
|
|
246
|
-
|
|
247
|
-
<wutta-button once type="is-primary"
|
|
248
|
-
tag="a" href="${url(f'{route_prefix}.create')}"
|
|
249
|
-
icon-left="plus"
|
|
250
|
-
label="Create New" />
|
|
251
|
-
% endif
|
|
251
|
+
${self.index_title_controls()}
|
|
252
252
|
% endif
|
|
253
253
|
</div>
|
|
254
254
|
</div>
|
|
@@ -344,6 +344,15 @@
|
|
|
344
344
|
</footer>
|
|
345
345
|
</%def>
|
|
346
346
|
|
|
347
|
+
<%def name="index_title_controls()">
|
|
348
|
+
% if master and master.creatable and not master.creating and master.has_perm('create'):
|
|
349
|
+
<wutta-button once type="is-primary"
|
|
350
|
+
tag="a" href="${url(f'{route_prefix}.create')}"
|
|
351
|
+
icon-left="plus"
|
|
352
|
+
label="Create New" />
|
|
353
|
+
% endif
|
|
354
|
+
</%def>
|
|
355
|
+
|
|
347
356
|
<%def name="render_vue_template_whole_page()">
|
|
348
357
|
<script type="text/x-template" id="whole-page-template">
|
|
349
358
|
|
|
@@ -116,6 +116,13 @@
|
|
|
116
116
|
hoverable
|
|
117
117
|
icon-pack="fas"
|
|
118
118
|
|
|
119
|
+
## checkboxes
|
|
120
|
+
% if grid.checkable:
|
|
121
|
+
checkable
|
|
122
|
+
checkbox-position="right"
|
|
123
|
+
:checked-rows.sync="checkedRows"
|
|
124
|
+
% endif
|
|
125
|
+
|
|
119
126
|
## sorting
|
|
120
127
|
% if grid.sortable:
|
|
121
128
|
## nb. buefy/oruga only support *one* default sorter
|
|
@@ -267,6 +274,11 @@
|
|
|
267
274
|
shareLink: null,
|
|
268
275
|
% endif
|
|
269
276
|
|
|
277
|
+
## checkboxes
|
|
278
|
+
% if grid.checkable:
|
|
279
|
+
checkedRows: [],
|
|
280
|
+
% endif
|
|
281
|
+
|
|
270
282
|
## filtering
|
|
271
283
|
% if grid.filterable:
|
|
272
284
|
filters: ${json.dumps(grid.get_vue_filters())|n},
|
|
@@ -245,6 +245,8 @@ class CommonView(View):
|
|
|
245
245
|
session.add(person)
|
|
246
246
|
user.person = person
|
|
247
247
|
|
|
248
|
+
self.setup_enhance_admin_user(user)
|
|
249
|
+
|
|
248
250
|
# send user to /login
|
|
249
251
|
self.request.session.flash("Account created! Please login below.")
|
|
250
252
|
return self.redirect(self.request.route_url('login'))
|
|
@@ -254,6 +256,17 @@ class CommonView(View):
|
|
|
254
256
|
'form': form,
|
|
255
257
|
}
|
|
256
258
|
|
|
259
|
+
def setup_enhance_admin_user(self, user):
|
|
260
|
+
"""
|
|
261
|
+
Further "enhance" the initial admin user when it is first created.
|
|
262
|
+
|
|
263
|
+
This does nothing by default; subclass can override if needed.
|
|
264
|
+
|
|
265
|
+
:param user: New admin
|
|
266
|
+
:class:`~wuttjamaican:wuttjamaican.db.model.auth.User`
|
|
267
|
+
which was just created as part of initial setup.
|
|
268
|
+
"""
|
|
269
|
+
|
|
257
270
|
@classmethod
|
|
258
271
|
def defaults(cls, config):
|
|
259
272
|
cls._defaults(config)
|
|
@@ -189,6 +189,12 @@ class MasterView(View):
|
|
|
189
189
|
|
|
190
190
|
This is optional; see also :meth:`get_grid_columns()`.
|
|
191
191
|
|
|
192
|
+
.. attribute:: checkable
|
|
193
|
+
|
|
194
|
+
Boolean indicating whether the grid should expose per-row
|
|
195
|
+
checkboxes. This is passed along to set
|
|
196
|
+
:attr:`~wuttaweb.grids.base.Grid.checkable` on the grid.
|
|
197
|
+
|
|
192
198
|
.. method:: grid_row_class(obj, data, i)
|
|
193
199
|
|
|
194
200
|
This method is *not* defined on the ``MasterView`` base class;
|
|
@@ -395,6 +401,7 @@ class MasterView(View):
|
|
|
395
401
|
# features
|
|
396
402
|
listable = True
|
|
397
403
|
has_grid = True
|
|
404
|
+
checkable = False
|
|
398
405
|
filterable = True
|
|
399
406
|
filter_defaults = None
|
|
400
407
|
sortable = True
|
|
@@ -1992,6 +1999,7 @@ class MasterView(View):
|
|
|
1992
1999
|
|
|
1993
2000
|
kwargs['tools'] = tools
|
|
1994
2001
|
|
|
2002
|
+
kwargs.setdefault('checkable', self.checkable)
|
|
1995
2003
|
if hasattr(self, 'grid_row_class'):
|
|
1996
2004
|
kwargs.setdefault('row_class', self.grid_row_class)
|
|
1997
2005
|
kwargs.setdefault('filterable', self.filterable)
|
|
@@ -28,7 +28,7 @@ from wuttjamaican.db.model import Role, Permission
|
|
|
28
28
|
from wuttaweb.views import MasterView
|
|
29
29
|
from wuttaweb.db import Session
|
|
30
30
|
from wuttaweb.forms import widgets
|
|
31
|
-
from wuttaweb.forms.schema import
|
|
31
|
+
from wuttaweb.forms.schema import Permissions, RoleRef
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
class RoleView(MasterView):
|
|
@@ -123,9 +123,7 @@ class RoleView(MasterView):
|
|
|
123
123
|
# users
|
|
124
124
|
if not (self.creating or self.editing):
|
|
125
125
|
f.append('users')
|
|
126
|
-
f.
|
|
127
|
-
f.set_node('users', UserRefs(self.request))
|
|
128
|
-
f.set_default('users', [u.uuid for u in role.users])
|
|
126
|
+
f.set_grid('users', self.make_users_grid(role))
|
|
129
127
|
|
|
130
128
|
# permissions
|
|
131
129
|
f.append('permissions')
|
|
@@ -134,6 +132,39 @@ class RoleView(MasterView):
|
|
|
134
132
|
if not self.creating:
|
|
135
133
|
f.set_default('permissions', list(role.permissions))
|
|
136
134
|
|
|
135
|
+
def make_users_grid(self, role):
|
|
136
|
+
"""
|
|
137
|
+
Make and return the grid for the Users field.
|
|
138
|
+
|
|
139
|
+
This grid is shown for the Users field when viewing a Role.
|
|
140
|
+
|
|
141
|
+
:returns: Fully configured :class:`~wuttaweb.grids.base.Grid`
|
|
142
|
+
instance.
|
|
143
|
+
"""
|
|
144
|
+
model = self.app.model
|
|
145
|
+
route_prefix = self.get_route_prefix()
|
|
146
|
+
|
|
147
|
+
grid = self.make_grid(key=f'{route_prefix}.view.users',
|
|
148
|
+
model_class=model.User,
|
|
149
|
+
data=role.users,
|
|
150
|
+
columns=[
|
|
151
|
+
'username',
|
|
152
|
+
'person',
|
|
153
|
+
'active',
|
|
154
|
+
])
|
|
155
|
+
|
|
156
|
+
if self.request.has_perm('users.view'):
|
|
157
|
+
url = lambda user, i: self.request.route_url('users.view', uuid=user.uuid)
|
|
158
|
+
grid.add_action('view', icon='eye', url=url)
|
|
159
|
+
grid.set_link('person')
|
|
160
|
+
grid.set_link('username')
|
|
161
|
+
|
|
162
|
+
if self.request.has_perm('users.edit'):
|
|
163
|
+
url = lambda user, i: self.request.route_url('users.edit', uuid=user.uuid)
|
|
164
|
+
grid.add_action('edit', url=url)
|
|
165
|
+
|
|
166
|
+
return grid
|
|
167
|
+
|
|
137
168
|
def unique_name(self, node, value):
|
|
138
169
|
""" """
|
|
139
170
|
model = self.app.model
|
|
@@ -88,7 +88,8 @@ app.spec = wuttaweb.app:make_wsgi_app
|
|
|
88
88
|
reload=False,
|
|
89
89
|
reload_dirs=None,
|
|
90
90
|
factory=False,
|
|
91
|
-
interface='auto'
|
|
91
|
+
interface='auto',
|
|
92
|
+
root_path='')
|
|
92
93
|
|
|
93
94
|
# with reload
|
|
94
95
|
uvicorn.run.reset_mock()
|
|
@@ -101,4 +102,5 @@ app.spec = wuttaweb.app:make_wsgi_app
|
|
|
101
102
|
reload=True,
|
|
102
103
|
reload_dirs=None,
|
|
103
104
|
factory=False,
|
|
104
|
-
interface='auto'
|
|
105
|
+
interface='auto',
|
|
106
|
+
root_path='')
|
|
@@ -1409,6 +1409,24 @@ class TestGrid(WebTestCase):
|
|
|
1409
1409
|
value = decimal.Decimal('-42.42')
|
|
1410
1410
|
self.assertEqual(grid.render_currency(obj, 'foo', value), '($42.42)')
|
|
1411
1411
|
|
|
1412
|
+
def test_render_percent(self):
|
|
1413
|
+
grid = self.make_grid(columns=['foo', 'bar'])
|
|
1414
|
+
obj = MagicMock()
|
|
1415
|
+
|
|
1416
|
+
# null
|
|
1417
|
+
self.assertEqual(grid.render_percent(obj, 'foo', None), "")
|
|
1418
|
+
|
|
1419
|
+
# typical
|
|
1420
|
+
self.assertEqual(grid.render_percent(obj, 'foo', 12.3419), '12.34 %')
|
|
1421
|
+
|
|
1422
|
+
# more decimal places
|
|
1423
|
+
self.assertEqual(grid.render_percent(obj, 'foo', 12.3419, decimals=3), '12.342 %')
|
|
1424
|
+
self.assertEqual(grid.render_percent(obj, 'foo', 12.3419, decimals=4), '12.3419 %')
|
|
1425
|
+
|
|
1426
|
+
# negative
|
|
1427
|
+
self.assertEqual(grid.render_percent(obj, 'foo', -12.3419), '(12.34 %)')
|
|
1428
|
+
self.assertEqual(grid.render_percent(obj, 'foo', -12.3419, decimals=3), '(12.342 %)')
|
|
1429
|
+
|
|
1412
1430
|
def test_render_quantity(self):
|
|
1413
1431
|
grid = self.make_grid(columns=['foo', 'bar'])
|
|
1414
1432
|
obj = MagicMock()
|
|
@@ -1433,7 +1451,7 @@ class TestGrid(WebTestCase):
|
|
|
1433
1451
|
# null
|
|
1434
1452
|
obj = MagicMock(dt=None)
|
|
1435
1453
|
result = grid.render_date(obj, 'dt', None)
|
|
1436
|
-
self.
|
|
1454
|
+
self.assertEqual(result, '')
|
|
1437
1455
|
|
|
1438
1456
|
# typical
|
|
1439
1457
|
dt = datetime.date(2025, 1, 13)
|
|
@@ -1446,7 +1464,7 @@ class TestGrid(WebTestCase):
|
|
|
1446
1464
|
|
|
1447
1465
|
obj = MagicMock(dt=None)
|
|
1448
1466
|
result = grid.render_datetime(obj, 'dt', None)
|
|
1449
|
-
self.
|
|
1467
|
+
self.assertEqual(result, '')
|
|
1450
1468
|
|
|
1451
1469
|
dt = datetime.datetime(2024, 12, 12, 13, 44, tzinfo=datetime.timezone.utc)
|
|
1452
1470
|
obj = MagicMock(dt=dt)
|
|
@@ -7,6 +7,7 @@ from sqlalchemy import orm
|
|
|
7
7
|
import colander
|
|
8
8
|
|
|
9
9
|
from wuttaweb.views import roles as mod
|
|
10
|
+
from wuttaweb.grids import Grid
|
|
10
11
|
from wuttaweb.forms.schema import RoleRef
|
|
11
12
|
from wuttaweb.testing import WebTestCase
|
|
12
13
|
|
|
@@ -93,6 +94,27 @@ class TestRoleView(WebTestCase):
|
|
|
93
94
|
view.configure_form(form)
|
|
94
95
|
self.assertIsNotNone(form.validators['name'])
|
|
95
96
|
|
|
97
|
+
def test_make_users_grid(self):
|
|
98
|
+
model = self.app.model
|
|
99
|
+
view = self.make_view()
|
|
100
|
+
role = model.Role(name="Manager")
|
|
101
|
+
|
|
102
|
+
# basic
|
|
103
|
+
grid = view.make_users_grid(role)
|
|
104
|
+
self.assertIsInstance(grid, Grid)
|
|
105
|
+
self.assertFalse(grid.linked_columns)
|
|
106
|
+
self.assertFalse(grid.actions)
|
|
107
|
+
|
|
108
|
+
# view + edit actions
|
|
109
|
+
with patch.object(self.request, 'is_root', new=True):
|
|
110
|
+
grid = view.make_users_grid(role)
|
|
111
|
+
self.assertIsInstance(grid, Grid)
|
|
112
|
+
self.assertIn('person', grid.linked_columns)
|
|
113
|
+
self.assertIn('username', grid.linked_columns)
|
|
114
|
+
self.assertEqual(len(grid.actions), 2)
|
|
115
|
+
self.assertEqual(grid.actions[0].key, 'view')
|
|
116
|
+
self.assertEqual(grid.actions[1].key, 'edit')
|
|
117
|
+
|
|
96
118
|
def test_unique_name(self):
|
|
97
119
|
model = self.app.model
|
|
98
120
|
view = self.make_view()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|