WuttaWeb 0.26.0__tar.gz → 0.27.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.26.0 → wuttaweb-0.27.1}/CHANGELOG.md +34 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/PKG-INFO +3 -2
- wuttaweb-0.27.1/docs/api/wuttaweb.views.views.rst +6 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/index.rst +1 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/pyproject.toml +3 -3
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/app.py +5 -0
- wuttaweb-0.27.1/src/wuttaweb/code-templates/new-master-view.mako +116 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/code-templates/new-table.mako +11 -15
- wuttaweb-0.27.1/src/wuttaweb/conf.py +89 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/db/continuum.py +8 -4
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/forms/widgets.py +1 -1
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/grids/base.py +28 -8
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/alembic/dashboard.mako +4 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/appinfo/index.mako +30 -20
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/base.mako +4 -0
- wuttaweb-0.27.1/src/wuttaweb/templates/batch/view.mako +113 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/form.mako +4 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/view.mako +2 -2
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/tables/app/create.mako +2 -2
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/tables/app/index.mako +8 -0
- wuttaweb-0.27.1/src/wuttaweb/templates/views/master/configure.mako +31 -0
- wuttaweb-0.27.1/src/wuttaweb/templates/views/master/create.mako +846 -0
- wuttaweb-0.27.1/src/wuttaweb/templates/views/master/index.mako +17 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/testing.py +55 -1
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/batch.py +7 -3
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/common.py +17 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/essential.py +2 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/master.py +30 -27
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/people.py +3 -1
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/reports.py +1 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/tables.py +95 -15
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/upgrades.py +0 -6
- wuttaweb-0.27.1/src/wuttaweb/views/views.py +469 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tasks.py +2 -1
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/db/test_continuum.py +8 -4
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/forms/test_widgets.py +2 -1
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/grids/test_base.py +19 -4
- wuttaweb-0.27.1/tests/test_conf.py +61 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_batch.py +1 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_tables.py +44 -1
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_users.py +180 -1
- wuttaweb-0.27.1/tests/views/test_views.py +370 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tox.ini +8 -4
- wuttaweb-0.26.0/src/wuttaweb/conf.py +0 -46
- wuttaweb-0.26.0/src/wuttaweb/templates/batch/view.mako +0 -111
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/.gitignore +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/.hgignore +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/.pylintrc +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/COPYING.txt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/README.md +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/Makefile +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/_static/.keepme +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.app.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.auth.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.cli.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.cli.webapp.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.conf.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.db.continuum.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.db.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.db.sess.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.diffs.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.emails.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.forms.base.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.forms.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.forms.schema.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.forms.widgets.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.grids.base.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.grids.filters.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.grids.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.handler.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.helpers.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.menus.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.progress.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.static.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.subscribers.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.util.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.alembic.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.auth.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.base.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.batch.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.common.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.email.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.essential.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.master.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.people.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.progress.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.reports.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.roles.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.settings.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.tables.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.upgrades.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/api/wuttaweb.views.users.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/conf.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/glossary.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/make.bat +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/narr/cli/builtin.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/narr/cli/index.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/narr/templates/base.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/narr/templates/index.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/narr/templates/lookup.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/docs/narr/templates/overview.rst +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/_version.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/auth.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/cli/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/cli/webapp.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/db/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/db/sess.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/diffs.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/emails.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/forms/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/forms/base.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/forms/schema.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/grids/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/grids/filters.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/handler.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/helpers.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/menus.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/progress.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/static/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/static/img/favicon.ico +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/static/img/logo.png +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/static/img/testing.png +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/subscribers.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/alembic/migrations/configure.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/alembic/migrations/create.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/alembic/migrations/index.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/alembic/migrations/view.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/auth/change_password.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/auth/login.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/base_meta.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/configure.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/dateinput.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/datetimeinput.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/password.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/permissions.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/select.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/textarea.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/textinput.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/deform/wutta_checked_password.pt +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/diff.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/email/settings/view.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/forbidden.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/forms/vue_buttons.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/forms/vue_fields.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/grids/table_element.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/home.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/configure.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/create.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/create_row.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/delete.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/edit.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/form.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/index.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/view_version.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/master/view_versions.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/notfound.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/page.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/people/view_profile.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/progress.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/reports/view.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/setup.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/themes/butterfly/base.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/themes/butterfly/buefy-components.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/themes/butterfly/buefy-plugin.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/themes/butterfly/http-plugin.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/upgrade.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/upgrades/index.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/upgrades/view.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/users/view.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/templates/wutta-components.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/util.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/alembic.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/auth.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/base.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/email.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/progress.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/roles.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/settings.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/src/wuttaweb/views/users.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/cli/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/cli/test_webapp.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/db/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/forms/main_template.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/forms/main_template_with_fields.mako +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/forms/test_base.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/forms/test_schema.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/grids/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/grids/test_filters.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_oruga.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_oruga_bulma.css +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_oruga_bulma.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_vue.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/bb_vue_fontawesome.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/buefy.css +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/buefy.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/fontawesome.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/vue.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/libcache/vue_resource.js +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_app.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_auth.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_diffs.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_emails.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_handler.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_helpers.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_menus.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_progress.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_static.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_subscribers.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/test_util.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/util.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/__init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test___init__.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_alembic.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_auth.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_base.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_common.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_email.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_essential.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_master.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_people.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_progress.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_reports.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_roles.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_settings.py +0 -0
- {wuttaweb-0.26.0 → wuttaweb-0.27.1}/tests/views/test_upgrades.py +0 -0
|
@@ -5,6 +5,40 @@ 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.27.1 (2026-01-03)
|
|
9
|
+
|
|
10
|
+
### Fix
|
|
11
|
+
|
|
12
|
+
- add separate def for middle buttons on App Info page
|
|
13
|
+
- expose version history for site admin in default setup
|
|
14
|
+
- only show execution panel if batch view supports it
|
|
15
|
+
- remove the Users field for create/edit Person
|
|
16
|
+
- only show "create row" button if batch view supports it
|
|
17
|
+
- show proper batch status text, from enum
|
|
18
|
+
- use wutta hint from model, for master view title
|
|
19
|
+
- accept dict instead of true enum, for `Grid.set_enum()`
|
|
20
|
+
- improve FK handling in generated model class code
|
|
21
|
+
- use custom UUID type when generating model class code for FK
|
|
22
|
+
- fix spacing style when viewing object with row grid
|
|
23
|
+
- grant access to alembic, tables, master view admin for new apps
|
|
24
|
+
|
|
25
|
+
## v0.27.0 (2025-12-31)
|
|
26
|
+
|
|
27
|
+
### Feat
|
|
28
|
+
|
|
29
|
+
- add wizard for generating new master view code
|
|
30
|
+
- add basic MasterView to show all registered master views
|
|
31
|
+
- add MasterView registry/discovery mechanism
|
|
32
|
+
|
|
33
|
+
### Fix
|
|
34
|
+
|
|
35
|
+
- show db backend (dialect name) on App Info page
|
|
36
|
+
- prevent whitespace wrap for tool panel header
|
|
37
|
+
- render datetimes with tooltip showing time delta from now
|
|
38
|
+
- fallback to default continuum plugin logic, when no request
|
|
39
|
+
- flush session when creating new object via MasterView
|
|
40
|
+
- fix page title for Alembic Dashboard
|
|
41
|
+
|
|
8
42
|
## v0.26.0 (2025-12-28)
|
|
9
43
|
|
|
10
44
|
### Feat
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: WuttaWeb
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.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
|
|
@@ -40,7 +40,7 @@ Requires-Dist: pyramid>=2
|
|
|
40
40
|
Requires-Dist: sqlalchemy-utils
|
|
41
41
|
Requires-Dist: waitress
|
|
42
42
|
Requires-Dist: webhelpers2
|
|
43
|
-
Requires-Dist: wuttjamaican[db]>=0.28.
|
|
43
|
+
Requires-Dist: wuttjamaican[db]>=0.28.1
|
|
44
44
|
Requires-Dist: zope-sqlalchemy>=1.5
|
|
45
45
|
Provides-Extra: continuum
|
|
46
46
|
Requires-Dist: wutta-continuum>=0.3.0; extra == 'continuum'
|
|
@@ -53,6 +53,7 @@ Requires-Dist: pylint; extra == 'tests'
|
|
|
53
53
|
Requires-Dist: pytest; extra == 'tests'
|
|
54
54
|
Requires-Dist: pytest-cov; extra == 'tests'
|
|
55
55
|
Requires-Dist: tox; extra == 'tests'
|
|
56
|
+
Requires-Dist: webtest; extra == 'tests'
|
|
56
57
|
Description-Content-Type: text/markdown
|
|
57
58
|
|
|
58
59
|
|
|
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "WuttaWeb"
|
|
9
|
-
version = "0.
|
|
9
|
+
version = "0.27.1"
|
|
10
10
|
description = "Web App for Wutta Framework"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
|
@@ -45,7 +45,7 @@ dependencies = [
|
|
|
45
45
|
"SQLAlchemy-Utils",
|
|
46
46
|
"waitress",
|
|
47
47
|
"WebHelpers2",
|
|
48
|
-
"WuttJamaican[db]>=0.28.
|
|
48
|
+
"WuttJamaican[db]>=0.28.1",
|
|
49
49
|
"zope.sqlalchemy>=1.5",
|
|
50
50
|
]
|
|
51
51
|
|
|
@@ -53,7 +53,7 @@ dependencies = [
|
|
|
53
53
|
[project.optional-dependencies]
|
|
54
54
|
continuum = ["Wutta-Continuum>=0.3.0"]
|
|
55
55
|
docs = ["Sphinx", "furo", "sphinxcontrib-programoutput"]
|
|
56
|
-
tests = ["pylint", "pytest", "pytest-cov", "tox"]
|
|
56
|
+
tests = ["pylint", "pytest", "pytest-cov", "tox", "WebTest"]
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
[project.entry-points."fanstatic.libraries"]
|
|
@@ -164,6 +164,11 @@ def make_pyramid_config(settings):
|
|
|
164
164
|
)
|
|
165
165
|
pyramid_config.add_directive("add_wutta_permission", "wuttaweb.auth.add_permission")
|
|
166
166
|
|
|
167
|
+
# add some more config magic
|
|
168
|
+
pyramid_config.add_directive(
|
|
169
|
+
"add_wutta_master_view", "wuttaweb.conf.add_master_view"
|
|
170
|
+
)
|
|
171
|
+
|
|
167
172
|
return pyramid_config
|
|
168
173
|
|
|
169
174
|
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
## -*- coding: utf-8; mode: python; -*-
|
|
2
|
+
# -*- coding: utf-8; -*-
|
|
3
|
+
"""
|
|
4
|
+
Master view for ${model_title_plural}
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
% if model_option == "model_class":
|
|
8
|
+
from ${model_module} import ${model_name}
|
|
9
|
+
% endif
|
|
10
|
+
|
|
11
|
+
from wuttaweb.views import MasterView
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ${class_name}(MasterView):
|
|
15
|
+
"""
|
|
16
|
+
Master view for ${model_title_plural}
|
|
17
|
+
"""
|
|
18
|
+
% if model_option == "model_class":
|
|
19
|
+
model_class = ${model_name}
|
|
20
|
+
% else:
|
|
21
|
+
model_name = "${model_name}"
|
|
22
|
+
% endif
|
|
23
|
+
model_title = "${model_title}"
|
|
24
|
+
model_title_plural = "${model_title_plural}"
|
|
25
|
+
|
|
26
|
+
route_prefix = "${route_prefix}"
|
|
27
|
+
% if permission_prefix != route_prefix:
|
|
28
|
+
permission_prefix = "${permission_prefix}"
|
|
29
|
+
% endif
|
|
30
|
+
url_prefix = "${url_prefix}"
|
|
31
|
+
% if template_prefix != url_prefix:
|
|
32
|
+
template_prefix = "${template_prefix}"
|
|
33
|
+
% endif
|
|
34
|
+
|
|
35
|
+
% if not listable:
|
|
36
|
+
listable = False
|
|
37
|
+
% endif
|
|
38
|
+
creatable = ${creatable}
|
|
39
|
+
% if not viewable:
|
|
40
|
+
viewable = ${viewable}
|
|
41
|
+
% endif
|
|
42
|
+
editable = ${editable}
|
|
43
|
+
deletable = ${deletable}
|
|
44
|
+
|
|
45
|
+
% if listable and model_option == "model_name":
|
|
46
|
+
filterable = False
|
|
47
|
+
sort_on_backend = False
|
|
48
|
+
paginate_on_backend = False
|
|
49
|
+
% endif
|
|
50
|
+
|
|
51
|
+
% if grid_columns:
|
|
52
|
+
grid_columns = [
|
|
53
|
+
% for field in grid_columns:
|
|
54
|
+
"${field}",
|
|
55
|
+
% endfor
|
|
56
|
+
]
|
|
57
|
+
% elif model_option == "model_name":
|
|
58
|
+
# TODO: must specify grid columns before the list view will work:
|
|
59
|
+
# grid_columns = [
|
|
60
|
+
# "foo",
|
|
61
|
+
# "bar",
|
|
62
|
+
# ]
|
|
63
|
+
% endif
|
|
64
|
+
|
|
65
|
+
% if form_fields:
|
|
66
|
+
form_fields = [
|
|
67
|
+
% for field in form_fields:
|
|
68
|
+
"${field}",
|
|
69
|
+
% endfor
|
|
70
|
+
]
|
|
71
|
+
% elif model_option == "model_name":
|
|
72
|
+
# TODO: must specify form fields before create/view/edit/delete will work:
|
|
73
|
+
# form_fields = [
|
|
74
|
+
# "foo",
|
|
75
|
+
# "bar",
|
|
76
|
+
# ]
|
|
77
|
+
% endif
|
|
78
|
+
|
|
79
|
+
% if listable and model_option == "model_name":
|
|
80
|
+
def get_grid_data(self, columns=None, session=None):
|
|
81
|
+
data = []
|
|
82
|
+
|
|
83
|
+
# TODO: you should return whatever data is needed for the grid.
|
|
84
|
+
# it is expected to be a list of dicts, with keys corresponding
|
|
85
|
+
# to grid columns.
|
|
86
|
+
#
|
|
87
|
+
# data = [
|
|
88
|
+
# {"foo": 1, "bar": "abc"},
|
|
89
|
+
# {"foo": 2, "bar": "def"},
|
|
90
|
+
# ]
|
|
91
|
+
|
|
92
|
+
return data
|
|
93
|
+
% endif
|
|
94
|
+
|
|
95
|
+
% if listable:
|
|
96
|
+
def configure_grid(self, grid):
|
|
97
|
+
g = grid
|
|
98
|
+
super().configure_grid(g)
|
|
99
|
+
|
|
100
|
+
# TODO: tweak grid however you need here
|
|
101
|
+
#
|
|
102
|
+
# g.set_label("foo", "FOO")
|
|
103
|
+
# g.set_link("foo")
|
|
104
|
+
# g.set_renderer("foo", self.render_special_field)
|
|
105
|
+
% endif
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def defaults(config, **kwargs):
|
|
109
|
+
base = globals()
|
|
110
|
+
|
|
111
|
+
${class_name} = kwargs.get('${class_name}', base['${class_name}'])
|
|
112
|
+
${class_name}.defaults(config)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def includeme(config):
|
|
116
|
+
defaults(config)
|
|
@@ -15,16 +15,6 @@ class ${model_name}(model.Base):
|
|
|
15
15
|
${description}
|
|
16
16
|
"""
|
|
17
17
|
__tablename__ = "${table_name}"
|
|
18
|
-
% if any([c["data_type"]["type"] == "_fk_uuid_" for c in columns]):
|
|
19
|
-
__table_args__ = (
|
|
20
|
-
% for column in columns:
|
|
21
|
-
% if column["data_type"]["type"] == "_fk_uuid_":
|
|
22
|
-
sa.ForeignKeyConstraint(["${column['name']}"], ["${column['data_type']['reference']}.uuid"],
|
|
23
|
-
name="${table_name}_fk_${column['data_type']['reference']}"),
|
|
24
|
-
% endif
|
|
25
|
-
% endfor
|
|
26
|
-
)
|
|
27
|
-
% endif
|
|
28
18
|
% if versioned:
|
|
29
19
|
% if all([c["versioned"] for c in columns]):
|
|
30
20
|
__versioned__ = {}
|
|
@@ -48,17 +38,23 @@ class ${model_name}(model.Base):
|
|
|
48
38
|
|
|
49
39
|
% if column["name"] == "uuid":
|
|
50
40
|
uuid = model.uuid_column()
|
|
51
|
-
%
|
|
52
|
-
${column["name"]} =
|
|
53
|
-
|
|
54
|
-
""
|
|
55
|
-
% if column["data_type"]["type"] == "_fk_uuid_" and column["relationship"]:
|
|
41
|
+
% elif column["data_type"]["type"] == "_fk_uuid_":
|
|
42
|
+
${column["name"]} = model.uuid_fk_column("${column['data_type']['reference']}.uuid",
|
|
43
|
+
nullable=${column["nullable"]})
|
|
44
|
+
% if column["relationship"]:
|
|
56
45
|
${column["relationship"]["name"]} = orm.relationship(
|
|
57
46
|
"${column['relationship']['reference_model']}",
|
|
58
47
|
doc="""
|
|
59
48
|
${column["description"] or ""}
|
|
60
49
|
""")
|
|
61
50
|
% endif
|
|
51
|
+
% else:
|
|
52
|
+
${column["name"]} = sa.Column(
|
|
53
|
+
${column["formatted_data_type"]},
|
|
54
|
+
nullable=${column["nullable"]},
|
|
55
|
+
doc="""
|
|
56
|
+
${column["description"] or ""}
|
|
57
|
+
""")
|
|
62
58
|
% endif
|
|
63
59
|
% endfor
|
|
64
60
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# -*- coding: utf-8; -*-
|
|
2
|
+
################################################################################
|
|
3
|
+
#
|
|
4
|
+
# wuttaweb -- Web App for Wutta Framework
|
|
5
|
+
# Copyright © 2024-2025 Lance Edgar
|
|
6
|
+
#
|
|
7
|
+
# This file is part of Wutta Framework.
|
|
8
|
+
#
|
|
9
|
+
# Wutta Framework is free software: you can redistribute it and/or modify it
|
|
10
|
+
# under the terms of the GNU General Public License as published by the Free
|
|
11
|
+
# Software Foundation, either version 3 of the License, or (at your option) any
|
|
12
|
+
# later version.
|
|
13
|
+
#
|
|
14
|
+
# Wutta Framework is distributed in the hope that it will be useful, but
|
|
15
|
+
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
17
|
+
# more details.
|
|
18
|
+
#
|
|
19
|
+
# You should have received a copy of the GNU General Public License along with
|
|
20
|
+
# Wutta Framework. If not, see <http://www.gnu.org/licenses/>.
|
|
21
|
+
#
|
|
22
|
+
################################################################################
|
|
23
|
+
"""
|
|
24
|
+
Config Extension
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
from wuttjamaican.conf import WuttaConfigExtension
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class WuttaWebConfigExtension(WuttaConfigExtension):
|
|
31
|
+
"""
|
|
32
|
+
Config extension for WuttaWeb.
|
|
33
|
+
|
|
34
|
+
This sets the default plugin used for SQLAlchemy-Continuum, to
|
|
35
|
+
:class:`~wuttaweb.db.continuum.WuttaWebContinuumPlugin`. Which is
|
|
36
|
+
only relevant if Wutta-Continuum is installed and enabled. For
|
|
37
|
+
more info see :doc:`wutta-continuum:index`.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
key = "wuttaweb"
|
|
41
|
+
|
|
42
|
+
def configure(self, config): # pylint: disable=empty-docstring
|
|
43
|
+
""" """
|
|
44
|
+
config.setdefault(
|
|
45
|
+
"wutta_continuum.wutta_plugin_spec",
|
|
46
|
+
"wuttaweb.db.continuum:WuttaWebContinuumPlugin",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def add_master_view(config, master):
|
|
51
|
+
"""
|
|
52
|
+
Pyramid directive to add the given ``MasterView`` subclass to the
|
|
53
|
+
app's registry.
|
|
54
|
+
|
|
55
|
+
This allows the app to dynamically present certain options for
|
|
56
|
+
admin features etc.
|
|
57
|
+
|
|
58
|
+
This is normally called automatically for all master views, within
|
|
59
|
+
the :meth:`~wuttaweb.views.master.MasterView.defaults()` method.
|
|
60
|
+
|
|
61
|
+
Should you need to call this yourself, do not call it directly but
|
|
62
|
+
instead make a similar call via the Pyramid config object::
|
|
63
|
+
|
|
64
|
+
pyramid_config.add_wutta_master_view(PoserWidgetView)
|
|
65
|
+
|
|
66
|
+
:param config: Reference to the Pyramid config object.
|
|
67
|
+
|
|
68
|
+
:param master: Reference to a
|
|
69
|
+
:class:`~wuttaweb.views.master.MasterView` subclass.
|
|
70
|
+
|
|
71
|
+
This function is involved in app startup; once that phase is
|
|
72
|
+
complete you can inspect the master views like so::
|
|
73
|
+
|
|
74
|
+
master_views = request.registry.settings["wuttaweb_master_views"]
|
|
75
|
+
|
|
76
|
+
# find master views for given model class
|
|
77
|
+
user_views = master_views.get(model.User, [])
|
|
78
|
+
|
|
79
|
+
# some master views are registered by model name instead (if no class)
|
|
80
|
+
email_views = master_views.get("email_setting", [])
|
|
81
|
+
"""
|
|
82
|
+
key = master.get_model_class() or master.get_model_name()
|
|
83
|
+
|
|
84
|
+
def action():
|
|
85
|
+
master_views = config.get_settings().get("wuttaweb_master_views", {})
|
|
86
|
+
master_views.setdefault(key, []).append(master)
|
|
87
|
+
config.add_settings({"wuttaweb_master_views": master_views})
|
|
88
|
+
|
|
89
|
+
config.action(None, action)
|
|
@@ -48,11 +48,15 @@ else:
|
|
|
48
48
|
request = get_current_request()
|
|
49
49
|
if request:
|
|
50
50
|
return request.client_addr
|
|
51
|
-
|
|
51
|
+
|
|
52
|
+
# nb. no request presumably means running as cli
|
|
53
|
+
return super().get_remote_addr(uow, session)
|
|
52
54
|
|
|
53
55
|
def get_user_id(self, uow, session): # pylint: disable=empty-docstring
|
|
54
56
|
""" """
|
|
55
57
|
request = get_current_request()
|
|
56
|
-
if request
|
|
57
|
-
return request.user.uuid
|
|
58
|
-
|
|
58
|
+
if request:
|
|
59
|
+
return request.user.uuid if request.user else None
|
|
60
|
+
|
|
61
|
+
# nb. no request presumably means running as cli
|
|
62
|
+
return super().get_user_id(uow, session)
|
|
@@ -274,7 +274,7 @@ class WuttaDateTimeWidget(DateTimeInputWidget):
|
|
|
274
274
|
if not cstruct:
|
|
275
275
|
return ""
|
|
276
276
|
dt = datetime.datetime.fromisoformat(cstruct)
|
|
277
|
-
return self.app.render_datetime(dt)
|
|
277
|
+
return self.app.render_datetime(dt, html=True)
|
|
278
278
|
|
|
279
279
|
return super().serialize(field, cstruct, **kw)
|
|
280
280
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
################################################################################
|
|
3
3
|
#
|
|
4
4
|
# wuttaweb -- Web App for Wutta Framework
|
|
5
|
-
# Copyright © 2024-
|
|
5
|
+
# Copyright © 2024-2026 Lance Edgar
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Wutta Framework.
|
|
8
8
|
#
|
|
@@ -30,6 +30,12 @@ import logging
|
|
|
30
30
|
import warnings
|
|
31
31
|
from collections import namedtuple, OrderedDict
|
|
32
32
|
|
|
33
|
+
try:
|
|
34
|
+
from enum import EnumType
|
|
35
|
+
except ImportError: # pragma: no cover
|
|
36
|
+
# nb. python < 3.11
|
|
37
|
+
from enum import EnumMeta as EnumType
|
|
38
|
+
|
|
33
39
|
import sqlalchemy as sa
|
|
34
40
|
from sqlalchemy import orm
|
|
35
41
|
|
|
@@ -763,7 +769,7 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
|
|
|
763
769
|
|
|
764
770
|
:param key: Name of column.
|
|
765
771
|
|
|
766
|
-
:param enum: Instance of :class:`python:enum.Enum
|
|
772
|
+
:param enum: Instance of :class:`python:enum.Enum`, or a dict.
|
|
767
773
|
"""
|
|
768
774
|
self.enums[key] = enum
|
|
769
775
|
self.set_renderer(key, self.render_enum, enum=enum)
|
|
@@ -2041,7 +2047,7 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
|
|
|
2041
2047
|
grid.set_renderer('foo', 'datetime')
|
|
2042
2048
|
"""
|
|
2043
2049
|
dt = getattr(obj, key)
|
|
2044
|
-
return self.app.render_datetime(dt)
|
|
2050
|
+
return self.app.render_datetime(dt, html=True)
|
|
2045
2051
|
|
|
2046
2052
|
def render_enum(self, obj, key, value, enum=None):
|
|
2047
2053
|
"""
|
|
@@ -2050,7 +2056,7 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
|
|
|
2050
2056
|
See also :meth:`set_enum()`.
|
|
2051
2057
|
|
|
2052
2058
|
:param enum: Enum class for the field. This should be an
|
|
2053
|
-
instance of :class:`~python:enum.Enum
|
|
2059
|
+
instance of :class:`~python:enum.Enum` or else a dict.
|
|
2054
2060
|
|
|
2055
2061
|
To use this feature for your grid::
|
|
2056
2062
|
|
|
@@ -2061,12 +2067,26 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
|
|
|
2061
2067
|
TWO = 2
|
|
2062
2068
|
THREE = 3
|
|
2063
2069
|
|
|
2064
|
-
grid.set_enum(
|
|
2070
|
+
grid.set_enum("my_enum_field", MyEnum)
|
|
2071
|
+
|
|
2072
|
+
Or, perhaps more common::
|
|
2073
|
+
|
|
2074
|
+
myenum = {
|
|
2075
|
+
1: "ONE",
|
|
2076
|
+
2: "TWO",
|
|
2077
|
+
3: "THREE",
|
|
2078
|
+
}
|
|
2079
|
+
|
|
2080
|
+
grid.set_enum("my_enum_field", myenum)
|
|
2065
2081
|
"""
|
|
2066
2082
|
if enum:
|
|
2067
|
-
|
|
2068
|
-
if
|
|
2069
|
-
|
|
2083
|
+
|
|
2084
|
+
if isinstance(enum, EnumType):
|
|
2085
|
+
if raw_value := obj[key]:
|
|
2086
|
+
return raw_value.value
|
|
2087
|
+
|
|
2088
|
+
if isinstance(enum, dict):
|
|
2089
|
+
return enum.get(value, value)
|
|
2070
2090
|
|
|
2071
2091
|
return value
|
|
2072
2092
|
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
<b-field horizontal label="Node Title">
|
|
20
20
|
<span>${app.get_node_title()}</span>
|
|
21
21
|
</b-field>
|
|
22
|
+
<b-field horizontal label="DB Backend">
|
|
23
|
+
<span>${config.appdb_engine.dialect.name}</span>
|
|
24
|
+
</b-field>
|
|
22
25
|
<b-field horizontal label="Time Zone">
|
|
23
26
|
<span>${app.get_timezone_name()}</span>
|
|
24
27
|
</b-field>
|
|
@@ -33,23 +36,7 @@
|
|
|
33
36
|
</nav>
|
|
34
37
|
|
|
35
38
|
<div class="buttons">
|
|
36
|
-
|
|
37
|
-
% if request.has_perm("app_tables.list"):
|
|
38
|
-
<wutta-button type="is-primary"
|
|
39
|
-
tag="a" href="${url('app_tables')}"
|
|
40
|
-
icon-left="table"
|
|
41
|
-
label="App Tables"
|
|
42
|
-
once />
|
|
43
|
-
% endif
|
|
44
|
-
|
|
45
|
-
% if request.has_perm("alembic.dashboard"):
|
|
46
|
-
<wutta-button type="is-primary"
|
|
47
|
-
tag="a" href="${url('alembic.dashboard')}"
|
|
48
|
-
icon-left="forward"
|
|
49
|
-
label="Alembic Dashboard"
|
|
50
|
-
once />
|
|
51
|
-
% endif
|
|
52
|
-
|
|
39
|
+
${self.middle_buttons()}
|
|
53
40
|
</div>
|
|
54
41
|
|
|
55
42
|
<nav class="panel">
|
|
@@ -112,6 +99,32 @@
|
|
|
112
99
|
|
|
113
100
|
</%def>
|
|
114
101
|
|
|
102
|
+
<%def name="middle_buttons()">
|
|
103
|
+
% if request.has_perm("master_views.list"):
|
|
104
|
+
<wutta-button type="is-primary"
|
|
105
|
+
tag="a" href="${url('master_views')}"
|
|
106
|
+
icon-left="eye"
|
|
107
|
+
label="Master Views"
|
|
108
|
+
once />
|
|
109
|
+
% endif
|
|
110
|
+
|
|
111
|
+
% if request.has_perm("app_tables.list"):
|
|
112
|
+
<wutta-button type="is-primary"
|
|
113
|
+
tag="a" href="${url('app_tables')}"
|
|
114
|
+
icon-left="table"
|
|
115
|
+
label="App Tables"
|
|
116
|
+
once />
|
|
117
|
+
% endif
|
|
118
|
+
|
|
119
|
+
% if request.has_perm("alembic.dashboard"):
|
|
120
|
+
<wutta-button type="is-primary"
|
|
121
|
+
tag="a" href="${url('alembic.dashboard')}"
|
|
122
|
+
icon-left="forward"
|
|
123
|
+
label="Alembic Dashboard"
|
|
124
|
+
once />
|
|
125
|
+
% endif
|
|
126
|
+
</%def>
|
|
127
|
+
|
|
115
128
|
<%def name="modify_vue_vars()">
|
|
116
129
|
${parent.modify_vue_vars()}
|
|
117
130
|
<script>
|
|
@@ -124,6 +137,3 @@
|
|
|
124
137
|
|
|
125
138
|
</script>
|
|
126
139
|
</%def>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
${parent.body()}
|