WuttaWeb 0.21.5__tar.gz → 0.23.0__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.
Files changed (213) hide show
  1. wuttaweb-0.23.0/.hgignore +3 -0
  2. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/CHANGELOG.md +29 -0
  3. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/PKG-INFO +2 -2
  4. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/pyproject.toml +2 -2
  5. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/app.py +35 -1
  6. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/forms/widgets.py +16 -1
  7. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/grids/base.py +32 -3
  8. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/subscribers.py +88 -1
  9. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/appinfo/configure.mako +17 -5
  10. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/base.mako +44 -8
  11. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/checked_password.pt +2 -0
  12. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/dateinput.pt +2 -1
  13. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/datetimeinput.pt +2 -0
  14. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/moneyinput.pt +1 -0
  15. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/password.pt +1 -0
  16. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/textarea.pt +1 -0
  17. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/textinput.pt +1 -0
  18. wuttaweb-0.23.0/src/wuttaweb/templates/deform/wutta_checked_password.pt +8 -0
  19. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/forms/vue_template.mako +2 -0
  20. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/grids/table_element.mako +20 -1
  21. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/grids/vue_template.mako +2 -0
  22. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/page.mako +1 -1
  23. wuttaweb-0.23.0/src/wuttaweb/templates/themes/butterfly/base.mako +78 -0
  24. wuttaweb-0.23.0/src/wuttaweb/templates/themes/butterfly/buefy-components.mako +802 -0
  25. wuttaweb-0.23.0/src/wuttaweb/templates/themes/butterfly/buefy-plugin.mako +32 -0
  26. wuttaweb-0.23.0/src/wuttaweb/templates/themes/butterfly/http-plugin.mako +100 -0
  27. wuttaweb-0.23.0/src/wuttaweb/templates/users/view.mako +126 -0
  28. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/wutta-components.mako +66 -7
  29. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/util.py +165 -8
  30. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/auth.py +7 -2
  31. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/common.py +23 -1
  32. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/settings.py +3 -1
  33. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/users.py +128 -0
  34. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/forms/test_base.py +5 -1
  35. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/grids/test_base.py +44 -0
  36. wuttaweb-0.23.0/tests/test_app.py +195 -0
  37. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_subscribers.py +48 -2
  38. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_util.py +104 -15
  39. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_common.py +30 -0
  40. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_users.py +118 -0
  41. wuttaweb-0.21.5/tests/test_app.py +0 -131
  42. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/.gitignore +0 -0
  43. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/COPYING.txt +0 -0
  44. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/README.md +0 -0
  45. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/Makefile +0 -0
  46. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/_static/.keepme +0 -0
  47. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.app.rst +0 -0
  48. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.auth.rst +0 -0
  49. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.cli.rst +0 -0
  50. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.cli.webapp.rst +0 -0
  51. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.conf.rst +0 -0
  52. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.db.continuum.rst +0 -0
  53. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.db.rst +0 -0
  54. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.db.sess.rst +0 -0
  55. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.emails.rst +0 -0
  56. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.forms.base.rst +0 -0
  57. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.forms.rst +0 -0
  58. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.forms.schema.rst +0 -0
  59. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.forms.widgets.rst +0 -0
  60. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.grids.base.rst +0 -0
  61. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.grids.filters.rst +0 -0
  62. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.grids.rst +0 -0
  63. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.handler.rst +0 -0
  64. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.helpers.rst +0 -0
  65. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.menus.rst +0 -0
  66. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.progress.rst +0 -0
  67. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.rst +0 -0
  68. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.static.rst +0 -0
  69. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.subscribers.rst +0 -0
  70. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.util.rst +0 -0
  71. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.auth.rst +0 -0
  72. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.base.rst +0 -0
  73. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.batch.rst +0 -0
  74. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.common.rst +0 -0
  75. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.email.rst +0 -0
  76. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.essential.rst +0 -0
  77. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.master.rst +0 -0
  78. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.people.rst +0 -0
  79. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.progress.rst +0 -0
  80. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.reports.rst +0 -0
  81. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.roles.rst +0 -0
  82. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.rst +0 -0
  83. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.settings.rst +0 -0
  84. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.upgrades.rst +0 -0
  85. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/api/wuttaweb.views.users.rst +0 -0
  86. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/conf.py +0 -0
  87. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/glossary.rst +0 -0
  88. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/index.rst +0 -0
  89. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/make.bat +0 -0
  90. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/narr/cli/builtin.rst +0 -0
  91. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/narr/cli/index.rst +0 -0
  92. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/narr/templates/base.rst +0 -0
  93. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/narr/templates/index.rst +0 -0
  94. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/narr/templates/lookup.rst +0 -0
  95. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/docs/narr/templates/overview.rst +0 -0
  96. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/__init__.py +0 -0
  97. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/_version.py +0 -0
  98. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/auth.py +0 -0
  99. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/cli/__init__.py +0 -0
  100. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/cli/webapp.py +0 -0
  101. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/conf.py +0 -0
  102. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/db/__init__.py +0 -0
  103. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/db/continuum.py +0 -0
  104. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/db/sess.py +0 -0
  105. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
  106. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
  107. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/emails.py +0 -0
  108. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/forms/__init__.py +0 -0
  109. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/forms/base.py +0 -0
  110. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/forms/schema.py +0 -0
  111. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/grids/__init__.py +0 -0
  112. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/grids/filters.py +0 -0
  113. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/handler.py +0 -0
  114. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/helpers.py +0 -0
  115. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/menus.py +0 -0
  116. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/progress.py +0 -0
  117. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/static/__init__.py +0 -0
  118. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/static/img/favicon.ico +0 -0
  119. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/static/img/logo.png +0 -0
  120. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/static/img/testing.png +0 -0
  121. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/appinfo/index.mako +0 -0
  122. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/auth/change_password.mako +0 -0
  123. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/auth/login.mako +0 -0
  124. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/base_meta.mako +0 -0
  125. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/batch/view.mako +0 -0
  126. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/configure.mako +0 -0
  127. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
  128. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
  129. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/permissions.pt +0 -0
  130. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
  131. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
  132. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
  133. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
  134. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
  135. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
  136. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
  137. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/deform/select.pt +0 -0
  138. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/email/settings/view.mako +0 -0
  139. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/forbidden.mako +0 -0
  140. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/form.mako +0 -0
  141. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/home.mako +0 -0
  142. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/configure.mako +0 -0
  143. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/create.mako +0 -0
  144. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/delete.mako +0 -0
  145. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/edit.mako +0 -0
  146. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/form.mako +0 -0
  147. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/index.mako +0 -0
  148. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/master/view.mako +0 -0
  149. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/notfound.mako +0 -0
  150. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/people/view_profile.mako +0 -0
  151. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/progress.mako +0 -0
  152. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/reports/view.mako +0 -0
  153. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/setup.mako +0 -0
  154. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/upgrade.mako +0 -0
  155. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
  156. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/templates/upgrades/view.mako +0 -0
  157. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/testing.py +0 -0
  158. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/__init__.py +0 -0
  159. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/base.py +0 -0
  160. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/batch.py +0 -0
  161. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/email.py +0 -0
  162. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/essential.py +0 -0
  163. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/master.py +0 -0
  164. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/people.py +0 -0
  165. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/progress.py +0 -0
  166. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/reports.py +0 -0
  167. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/roles.py +0 -0
  168. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/src/wuttaweb/views/upgrades.py +0 -0
  169. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tasks.py +0 -0
  170. {wuttaweb-0.21.5/tests/views → wuttaweb-0.23.0/tests}/__init__.py +0 -0
  171. {wuttaweb-0.21.5/tests/grids → wuttaweb-0.23.0/tests/cli}/__init__.py +0 -0
  172. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/cli/test_webapp.py +0 -0
  173. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/db/__init__.py +0 -0
  174. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/db/test_continuum.py +0 -0
  175. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/forms/test_schema.py +0 -0
  176. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/forms/test_widgets.py +0 -0
  177. {wuttaweb-0.21.5/tests/cli → wuttaweb-0.23.0/tests/grids}/__init__.py +0 -0
  178. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/grids/test_filters.py +0 -0
  179. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
  180. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
  181. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_oruga.js +0 -0
  182. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_oruga_bulma.css +0 -0
  183. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_oruga_bulma.js +0 -0
  184. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_vue.js +0 -0
  185. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/bb_vue_fontawesome.js +0 -0
  186. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/buefy.css +0 -0
  187. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/buefy.js +0 -0
  188. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/fontawesome.js +0 -0
  189. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/vue.js +0 -0
  190. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/libcache/vue_resource.js +0 -0
  191. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_auth.py +0 -0
  192. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_emails.py +0 -0
  193. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_handler.py +0 -0
  194. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_helpers.py +0 -0
  195. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_menus.py +0 -0
  196. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_progress.py +0 -0
  197. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/test_static.py +0 -0
  198. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/util.py +0 -0
  199. {wuttaweb-0.21.5/tests → wuttaweb-0.23.0/tests/views}/__init__.py +0 -0
  200. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test___init__.py +0 -0
  201. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_auth.py +0 -0
  202. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_base.py +0 -0
  203. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_batch.py +0 -0
  204. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_email.py +0 -0
  205. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_essential.py +0 -0
  206. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_master.py +0 -0
  207. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_people.py +0 -0
  208. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_progress.py +0 -0
  209. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_reports.py +0 -0
  210. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_roles.py +0 -0
  211. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_settings.py +0 -0
  212. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tests/views/test_upgrades.py +0 -0
  213. {wuttaweb-0.21.5 → wuttaweb-0.23.0}/tox.ini +0 -0
@@ -0,0 +1,3 @@
1
+ syntax:glob
2
+ *.pyc
3
+ *~
@@ -5,6 +5,35 @@ 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.23.0 (2025-08-09)
9
+
10
+ ### Feat
11
+
12
+ - add tools to manage user API tokens
13
+
14
+ ### Fix
15
+
16
+ - add default sorter, tools for basic table-element grid
17
+ - add custom password+confirmation widget for Vue3 + Oruga
18
+ - fix butterfly wrapper for b-notification component
19
+ - add butterfly wrapper for b-timepicker component
20
+ - style tweaks for butterfly/oruga; mostly expand fields
21
+ - fix b-datepicker component wrapper per oruga 0.9.0
22
+ - fix b-button component wrapper per oruga 0.9.0
23
+ - update butterfly component for b-autocomplete, per oruga 0.11.4
24
+ - update default versions for Vue3 + Oruga + FontAwesome
25
+
26
+ ## v0.22.0 (2025-06-29)
27
+
28
+ ### Feat
29
+
30
+ - add basic theme system
31
+
32
+ ### Fix
33
+
34
+ - improve styles for testing watermark background image
35
+ - fix timezone offset bug for datepicker
36
+
8
37
  ## v0.21.5 (2025-02-21)
9
38
 
10
39
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: WuttaWeb
3
- Version: 0.21.5
3
+ Version: 0.23.0
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.4
42
+ Requires-Dist: wuttjamaican[db]>=0.22.0
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.21.5"
9
+ version = "0.23.0"
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.4",
47
+ "WuttJamaican[db]>=0.22.0",
48
48
  "zope.sqlalchemy>=1.5",
49
49
  ]
50
50
 
@@ -2,7 +2,7 @@
2
2
  ################################################################################
3
3
  #
4
4
  # wuttaweb -- Web App for Wutta Framework
5
- # Copyright © 2024 Lance Edgar
5
+ # Copyright © 2024-2025 Lance Edgar
6
6
  #
7
7
  # This file is part of Wutta Framework.
8
8
  #
@@ -35,6 +35,7 @@ from pyramid.config import Configurator
35
35
 
36
36
  import wuttaweb.db
37
37
  from wuttaweb.auth import WuttaSecurityPolicy
38
+ from wuttaweb.util import get_effective_theme, get_theme_template_path
38
39
 
39
40
 
40
41
  log = logging.getLogger(__name__)
@@ -132,6 +133,9 @@ def make_pyramid_config(settings):
132
133
  settings.setdefault('pyramid_deform.template_search_path',
133
134
  'wuttaweb:templates/deform')
134
135
 
136
+ # update settings per current theme
137
+ establish_theme(settings)
138
+
135
139
  pyramid_config = Configurator(settings=settings)
136
140
 
137
141
  # configure user authorization / authentication
@@ -248,3 +252,33 @@ def make_asgi_app(main_app=None, config=None):
248
252
  """
249
253
  wsgi_app = make_wsgi_app(main_app, config=config)
250
254
  return WsgiToAsgi(wsgi_app)
255
+
256
+
257
+ def establish_theme(settings):
258
+ """
259
+ Establishes initial theme on app startup. This mostly involves
260
+ updating the given ``settings`` dict.
261
+
262
+ This function is called automatically from within
263
+ :func:`make_pyramid_config()`.
264
+
265
+ It will first call :func:`~wuttaweb.util.get_effective_theme()` to
266
+ read the current theme from the :term:`settings table`, and store
267
+ this within ``settings['wuttaweb.theme']``.
268
+
269
+ It then calls :func:`~wuttaweb.util.get_theme_template_path()` and
270
+ will update ``settings['mako.directories']`` such that the theme's
271
+ template path is listed first.
272
+ """
273
+ config = settings['wutta_config']
274
+
275
+ theme = get_effective_theme(config)
276
+ settings['wuttaweb.theme'] = theme
277
+
278
+ directories = settings['mako.directories']
279
+ if isinstance(directories, str):
280
+ directories = config.parse_list(directories)
281
+
282
+ path = get_theme_template_path(config)
283
+ directories.insert(0, path)
284
+ settings['mako.directories'] = directories
@@ -2,7 +2,7 @@
2
2
  ################################################################################
3
3
  #
4
4
  # wuttaweb -- Web App for Wutta Framework
5
- # Copyright © 2024 Lance Edgar
5
+ # Copyright © 2024-2025 Lance Edgar
6
6
  #
7
7
  # This file is part of Wutta Framework.
8
8
  #
@@ -153,6 +153,21 @@ class WuttaCheckboxChoiceWidget(CheckboxChoiceWidget):
153
153
  self.app = self.config.get_app()
154
154
 
155
155
 
156
+ class WuttaCheckedPasswordWidget(PasswordWidget):
157
+ """
158
+ Custom widget for password+confirmation field.
159
+
160
+ This widget is used only for Vue 3 + Oruga, but is *not* used for
161
+ Vue 2 + Buefy.
162
+
163
+ This is a subclass of :class:`deform:deform.widget.PasswordWidget`
164
+ and uses these Deform templates:
165
+
166
+ * ``wutta_checked_password``
167
+ """
168
+ template = 'wutta_checked_password'
169
+
170
+
156
171
  class WuttaDateWidget(DateInputWidget):
157
172
  """
158
173
  Custom widget for :class:`python:datetime.date` fields.
@@ -2041,9 +2041,9 @@ class Grid:
2041
2041
  """
2042
2042
  Render a simple Vue table element for the grid.
2043
2043
 
2044
- This is what you want for a "simple" grid which does require a
2045
- unique Vue component, but can instead use the standard table
2046
- component.
2044
+ This is what you want for a "simple" grid which does not
2045
+ require a unique Vue component, but can instead use the
2046
+ standard table component.
2047
2047
 
2048
2048
  This returns something like:
2049
2049
 
@@ -2227,6 +2227,35 @@ class Grid:
2227
2227
  'order': sorter['dir']})
2228
2228
  return sorters
2229
2229
 
2230
+ def get_vue_first_sorter(self):
2231
+ """
2232
+ Returns the first active sorter, if applicable.
2233
+
2234
+ This method is used to declare the initial sort for a simple
2235
+ table component, i.e. for use with the ``table-element.mako``
2236
+ template. It generally is assumed that frontend sorting is in
2237
+ use, as opposed to backend sorting, although it should work
2238
+ for either scenario.
2239
+
2240
+ This checks :attr:`active_sorters` and if set, will use the
2241
+ first sorter from that. Note that ``active_sorters`` will
2242
+ *not* be set unless :meth:`load_settings()` has been called.
2243
+
2244
+ Otherwise this will use the first sorter from
2245
+ :attr:`sort_defaults` which is defined in constructor.
2246
+
2247
+ :returns: The first sorter in format ``[sortkey, sortdir]``,
2248
+ or ``None``.
2249
+ """
2250
+ if hasattr(self, 'active_sorters'):
2251
+ if self.active_sorters:
2252
+ sorter = self.active_sorters[0]
2253
+ return [sorter['key'], sorter['dir']]
2254
+
2255
+ elif self.sort_defaults:
2256
+ sorter = self.sort_defaults[0]
2257
+ return [sorter.sortkey, sorter.sortdir]
2258
+
2230
2259
  def get_vue_filters(self):
2231
2260
  """
2232
2261
  Returns a list of Vue-compatible filter definitions.
@@ -2,7 +2,7 @@
2
2
  ################################################################################
3
3
  #
4
4
  # wuttaweb -- Web App for Wutta Framework
5
- # Copyright © 2024 Lance Edgar
5
+ # Copyright © 2024-2025 Lance Edgar
6
6
  #
7
7
  # This file is part of Wutta Framework.
8
8
  #
@@ -38,11 +38,13 @@ hooks contained here, depending on the circumstance.
38
38
  import functools
39
39
  import json
40
40
  import logging
41
+ from collections import OrderedDict
41
42
 
42
43
  from pyramid import threadlocal
43
44
 
44
45
  from wuttaweb import helpers
45
46
  from wuttaweb.db import Session
47
+ from wuttaweb.util import get_available_themes
46
48
 
47
49
 
48
50
  log = logging.getLogger(__name__)
@@ -79,6 +81,43 @@ def new_request(event):
79
81
  Flag indicating whether the frontend should be displayed using
80
82
  Vue 3 + Oruga (if ``True``), or else Vue 2 + Buefy (if
81
83
  ``False``). This flag is ``False`` by default.
84
+
85
+ .. function:: request.register_component(tagname, classname)
86
+
87
+ Request method which registers a Vue component for use within
88
+ the app templates.
89
+
90
+ :param tagname: Component tag name as string.
91
+
92
+ :param classname: Component class name as string.
93
+
94
+ This is meant to be analogous to the ``Vue.component()`` call
95
+ which is part of Vue 2. It is good practice to always call
96
+ both at the same time/place:
97
+
98
+ .. code-block:: mako
99
+
100
+ ## define component template
101
+ <script type="text/x-template" id="my-example-template">
102
+ <div>my example</div>
103
+ </script>
104
+
105
+ <script>
106
+
107
+ ## define component logic
108
+ const MyExample = {
109
+ template: 'my-example-template'
110
+ }
111
+
112
+ ## register the component both ways here..
113
+
114
+ ## this is for Vue 2 - note the lack of quotes for classname
115
+ Vue.component('my-example', MyExample)
116
+
117
+ ## this is for Vue 3 - note the classname must be quoted
118
+ <% request.register_component('my-example', 'MyExample') %>
119
+
120
+ </script>
82
121
  """
83
122
  request = event.request
84
123
  config = request.registry.settings['wutta_config']
@@ -104,10 +143,34 @@ def new_request(event):
104
143
  if spec:
105
144
  func = app.load_object(spec)
106
145
  return func(request)
146
+
147
+ theme = request.registry.settings.get('wuttaweb.theme')
148
+ if theme == 'butterfly':
149
+ return True
107
150
  return False
108
151
 
109
152
  request.set_property(use_oruga, reify=True)
110
153
 
154
+ def register_component(tagname, classname):
155
+ """
156
+ Register a Vue 3 component, so the base template knows to
157
+ declare it for use within the app (page).
158
+ """
159
+ if not hasattr(request, '_wuttaweb_registered_components'):
160
+ request._wuttaweb_registered_components = OrderedDict()
161
+
162
+ if tagname in request._wuttaweb_registered_components:
163
+ log.warning("component with tagname '%s' already registered "
164
+ "with class '%s' but we are replacing that "
165
+ "with class '%s'",
166
+ tagname,
167
+ request._wuttaweb_registered_components[tagname],
168
+ classname)
169
+
170
+ request._wuttaweb_registered_components[tagname] = classname
171
+
172
+ request.register_component = register_component
173
+
111
174
 
112
175
  def default_user_getter(request, db_session=None):
113
176
  """
@@ -290,6 +353,23 @@ def before_render(event):
290
353
 
291
354
  Reference to the request method,
292
355
  :meth:`~pyramid:pyramid.request.Request.route_url()`.
356
+
357
+ .. data:: 'theme'
358
+
359
+ String name of the current theme. This will be ``'default'``
360
+ unless a custom theme is in effect.
361
+
362
+ .. data:: 'expose_theme_picker'
363
+
364
+ Boolean indicating whether the theme picker should *ever* be
365
+ exposed. For a user to see it, this flag must be true *and*
366
+ the user must have permission to change theme.
367
+
368
+ .. data:: 'available_themes'
369
+
370
+ List of theme names from which user may choose, if they are
371
+ allowed to change theme. Only set/relevant if
372
+ ``expose_theme_picker`` is true (see above).
293
373
  """
294
374
  request = event.get('request') or threadlocal.get_current_request()
295
375
  config = request.wutta_config
@@ -311,6 +391,13 @@ def before_render(event):
311
391
  menus = web.get_menu_handler()
312
392
  context['menus'] = menus.do_make_menus(request)
313
393
 
394
+ # theme
395
+ context['theme'] = request.registry.settings.get('wuttaweb.theme', 'default')
396
+ context['expose_theme_picker'] = config.get_bool('wuttaweb.themes.expose_picker',
397
+ default=False)
398
+ if context['expose_theme_picker']:
399
+ context['available_themes'] = get_available_themes(config)
400
+
314
401
 
315
402
  def includeme(config):
316
403
  config.add_subscriber(new_request, 'pyramid.events.NewRequest')
@@ -39,6 +39,13 @@
39
39
  @input="settingsNeedSaved = true">
40
40
  Production Mode
41
41
  </b-checkbox>
42
+ <span style="width: 1rem;" />
43
+ <b-checkbox name="wuttaweb.themes.expose_picker"
44
+ v-model="simpleSettings['wuttaweb.themes.expose_picker']"
45
+ native-value="true"
46
+ @input="settingsNeedSaved = true">
47
+ Expose Theme Picker
48
+ </b-checkbox>
42
49
  </b-field>
43
50
 
44
51
  <b-field label="Menu Handler">
@@ -105,31 +112,36 @@
105
112
  <b-field label="Default Sender">
106
113
  <b-input name="${app.appname}.email.default.sender"
107
114
  v-model="simpleSettings['${app.appname}.email.default.sender']"
108
- @input="settingsNeedSaved = true" />
115
+ @input="settingsNeedSaved = true"
116
+ expanded />
109
117
  </b-field>
110
118
 
111
119
  <b-field label="Default Recipient(s)">
112
120
  <b-input name="${app.appname}.email.default.to"
113
121
  v-model="simpleSettings['${app.appname}.email.default.to']"
114
- @input="settingsNeedSaved = true" />
122
+ @input="settingsNeedSaved = true"
123
+ expanded />
115
124
  </b-field>
116
125
 
117
126
  <b-field label="Default Subject (optional)">
118
127
  <b-input name="${app.appname}.email.default.subject"
119
128
  v-model="simpleSettings['${app.appname}.email.default.subject']"
120
- @input="settingsNeedSaved = true" />
129
+ @input="settingsNeedSaved = true"
130
+ expanded />
121
131
  </b-field>
122
132
 
123
133
  <b-field label="Feedback Recipient(s) (optional)">
124
134
  <b-input name="${app.appname}.email.feedback.to"
125
135
  v-model="simpleSettings['${app.appname}.email.feedback.to']"
126
- @input="settingsNeedSaved = true" />
136
+ @input="settingsNeedSaved = true"
137
+ expanded />
127
138
  </b-field>
128
139
 
129
140
  <b-field label="Feedback Subject (optional)">
130
141
  <b-input name="${app.appname}.email.feedback.subject"
131
142
  v-model="simpleSettings['${app.appname}.email.feedback.subject']"
132
- @input="settingsNeedSaved = true" />
143
+ @input="settingsNeedSaved = true"
144
+ expanded />
133
145
  </b-field>
134
146
 
135
147
  </div>
@@ -130,7 +130,7 @@
130
130
  }
131
131
 
132
132
  % if not request.wutta_config.production():
133
- html, .navbar, .footer {
133
+ html, body, .navbar, .footer {
134
134
  background-image: url(${request.static_url('wuttaweb:static/img/testing.png')});
135
135
  }
136
136
  % endif
@@ -440,7 +440,27 @@
440
440
  </div>
441
441
  </%def>
442
442
 
443
- <%def name="render_theme_picker()"></%def>
443
+ <%def name="render_theme_picker()">
444
+ % if expose_theme_picker and request.has_perm('common.change_theme'):
445
+ <div class="level-item">
446
+ ${h.form(url('change_theme'), method='POST', ref='themePickerForm')}
447
+ ${h.csrf_token(request)}
448
+ <input type="hidden" name="referrer" :value="referrer" />
449
+ <div style="display: flex; align-items: center; gap: 0.5rem;">
450
+ <span>Theme:</span>
451
+ <${b}-select name="theme"
452
+ v-model="globalTheme"
453
+ @input="changeTheme()">
454
+ % for name in available_themes:
455
+ <option value="${name}">${name}</option>
456
+ % endfor
457
+ </${b}-select>
458
+ </div>
459
+ ${h.end_form()}
460
+ </div>
461
+ % endif
462
+
463
+ </%def>
444
464
 
445
465
  <%def name="render_feedback_button()">
446
466
  % if request.has_perm('common.feedback'):
@@ -459,8 +479,8 @@
459
479
  Feedback
460
480
  </b-button>
461
481
 
462
- <b-modal has-modal-card
463
- :active.sync="showDialog">
482
+ <${b}-modal has-modal-card
483
+ :active.sync="showDialog">
464
484
  <div class="modal-card">
465
485
 
466
486
  <header class="modal-card-head">
@@ -478,23 +498,26 @@
478
498
  % if request.user:
479
499
  disabled
480
500
  % endif
481
- />
501
+ expanded />
482
502
  </b-field>
483
503
 
484
504
  <b-field label="Referring URL">
485
505
  <b-input v-model="referrer"
486
- disabled="true" />
506
+ disabled="true"
507
+ expanded />
487
508
  </b-field>
488
509
 
489
510
  <b-field label="Message"
490
511
  :type="message && message.trim() ? null : 'is-danger'">
491
512
  <b-input type="textarea"
492
513
  v-model="message"
493
- ref="textarea" />
514
+ ref="textarea"
515
+ expanded />
494
516
  </b-field>
495
517
  </section>
496
518
 
497
519
  <footer class="modal-card-foot">
520
+ <div style="display: flex; gap: 0.5rem;">
498
521
  <b-button @click="showDialog = false">
499
522
  Cancel
500
523
  </b-button>
@@ -505,9 +528,10 @@
505
528
  :disabled="submitDisabled">
506
529
  {{ sendingFeedback ? "Working, please wait..." : "Send Message" }}
507
530
  </b-button>
531
+ </div>
508
532
  </footer>
509
533
  </div>
510
- </b-modal>
534
+ </${b}-modal>
511
535
 
512
536
  </div>
513
537
  </script>
@@ -631,6 +655,12 @@
631
655
  },
632
656
 
633
657
  % endif
658
+
659
+ % if expose_theme_picker and request.has_perm('common.change_theme'):
660
+ changeTheme() {
661
+ this.$refs.themePickerForm.submit()
662
+ },
663
+ % endif
634
664
  },
635
665
  }
636
666
 
@@ -638,6 +668,10 @@
638
668
  contentTitleHTML: ${json.dumps(capture(self.content_title))|n},
639
669
  referrer: location.href,
640
670
  mountedHooks: [],
671
+
672
+ % if expose_theme_picker and request.has_perm('common.change_theme'):
673
+ globalTheme: ${json.dumps(theme or None)|n},
674
+ % endif
641
675
  }
642
676
 
643
677
  ## declare nested menu visibility toggle flags
@@ -774,11 +808,13 @@
774
808
  <script>
775
809
  WholePage.data = function() { return WholePageData }
776
810
  Vue.component('whole-page', WholePage)
811
+ <% request.register_component('whole-page', 'WholePage') %>
777
812
  </script>
778
813
  % if request.has_perm('common.feedback'):
779
814
  <script>
780
815
  WuttaFeedbackForm.data = function() { return WuttaFeedbackFormData }
781
816
  Vue.component('wutta-feedback-form', WuttaFeedbackForm)
817
+ <% request.register_component('wutta-feedback-form', 'WuttaFeedbackForm') %>
782
818
  </script>
783
819
  % endif
784
820
  </%def>
@@ -5,10 +5,12 @@
5
5
  <b-input name="${name}"
6
6
  value="${field.widget.redisplay and cstruct or ''}"
7
7
  type="password"
8
+ expanded
8
9
  placeholder="Password" />
9
10
  <b-input name="${name}-confirm"
10
11
  value="${field.widget.redisplay and confirm or ''}"
11
12
  type="password"
13
+ expanded
12
14
  placeholder="Confirm Password" />
13
15
  ${field.end_mapping()}
14
16
  </div>
@@ -1,6 +1,7 @@
1
1
  <div>
2
2
  ${field.start_mapping()}
3
3
  <wutta-datepicker name="date"
4
- value="${cstruct}" />
4
+ value="${cstruct}"
5
+ expanded />
5
6
  ${field.end_mapping()}
6
7
  </div>
@@ -2,9 +2,11 @@
2
2
  ${field.start_mapping()}
3
3
  <wutta-datepicker name="date"
4
4
  style="flex-grow: 1;"
5
+ expanded
5
6
  value="${date}" />
6
7
  <wutta-timepicker name="time"
7
8
  style="flex-grow: 1;"
9
+ expanded
8
10
  value="${time}" />
9
11
  ${field.end_mapping()}
10
12
  </div>
@@ -3,5 +3,6 @@
3
3
  vmodel vmodel|'modelData.'+oid;">
4
4
  <b-input name="${name}"
5
5
  v-model="${vmodel}"
6
+ expanded
6
7
  tal:attributes="attributes|field.widget.attributes|{};" />
7
8
  </tal:omit>
@@ -5,5 +5,6 @@
5
5
  <b-input name="${name}"
6
6
  v-model="${vmodel}"
7
7
  type="password"
8
+ expanded
8
9
  tal:attributes="attributes|field.widget.attributes|{};" />
9
10
  </div>
@@ -7,5 +7,6 @@
7
7
  <b-input name="${name}"
8
8
  v-model="${vmodel}"
9
9
  type="textarea"
10
+ expanded
10
11
  tal:attributes="attributes|field.widget.attributes|{};" />
11
12
  </div>
@@ -4,5 +4,6 @@
4
4
  vmodel vmodel|'modelData.'+oid;">
5
5
  <b-input name="${name}"
6
6
  v-model="${vmodel}"
7
+ expanded
7
8
  tal:attributes="attributes|field.widget.attributes|{};" />
8
9
  </div>
@@ -0,0 +1,8 @@
1
+ <div tal:omit-tag
2
+ tal:define="name name|field.name;
3
+ oid oid|field.oid;
4
+ vmodel vmodel|'modelData.'+oid;">
5
+ <wutta-checked-password name="${name}"
6
+ v-model="${vmodel}"
7
+ tal:attributes="attributes|field.widget.attributes|{};" />
8
+ </div>
@@ -95,3 +95,5 @@
95
95
  }
96
96
 
97
97
  </script>
98
+
99
+ <% request.register_component(form.vue_tagname, form.vue_component) %>
@@ -1,5 +1,22 @@
1
1
  ## -*- coding: utf-8; -*-
2
- <${b}-table :data="gridContext['${grid.key}'].data">
2
+ <div>
3
+
4
+ % if grid.tools:
5
+ <div class="table-tools-wrapper">
6
+ % for html in grid.tools.values():
7
+ ${html}
8
+ % endfor
9
+ </div>
10
+ % endif
11
+
12
+ <${b}-table :data="gridContext['${grid.key}'].data"
13
+
14
+ ## sorting
15
+ % if grid.sortable:
16
+ :default-sort="${grid.get_vue_first_sorter() or 'null'}"
17
+ % endif
18
+
19
+ icon-pack="fas">
3
20
 
4
21
  % for column in grid.get_vue_columns():
5
22
  % if not column['hidden']:
@@ -52,3 +69,5 @@
52
69
  </template>
53
70
 
54
71
  </${b}-table>
72
+
73
+ </div>
@@ -739,3 +739,5 @@
739
739
  }
740
740
 
741
741
  </script>
742
+
743
+ <% request.register_component(grid.vue_tagname, grid.vue_component) %>
@@ -50,6 +50,6 @@
50
50
  <script>
51
51
  ThisPage.data = function() { return ThisPageData }
52
52
  Vue.component('this-page', ThisPage)
53
- ## <% request.register_component('this-page', 'ThisPage') %>
53
+ <% request.register_component('this-page', 'ThisPage') %>
54
54
  </script>
55
55
  </%def>