WuttaWeb 0.25.0__tar.gz → 0.26.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 (242) hide show
  1. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/CHANGELOG.md +30 -0
  2. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/PKG-INFO +4 -3
  3. wuttaweb-0.26.0/docs/api/wuttaweb.views.alembic.rst +6 -0
  4. wuttaweb-0.26.0/docs/api/wuttaweb.views.tables.rst +6 -0
  5. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/conf.py +1 -0
  6. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/index.rst +2 -0
  7. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/pyproject.toml +4 -3
  8. wuttaweb-0.26.0/src/wuttaweb/code-templates/new-table.mako +68 -0
  9. wuttaweb-0.26.0/src/wuttaweb/diffs.py +199 -0
  10. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/forms/base.py +175 -24
  11. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/forms/schema.py +21 -9
  12. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/forms/widgets.py +74 -1
  13. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/grids/base.py +15 -7
  14. wuttaweb-0.26.0/src/wuttaweb/templates/alembic/dashboard.mako +234 -0
  15. wuttaweb-0.26.0/src/wuttaweb/templates/alembic/migrations/configure.mako +31 -0
  16. wuttaweb-0.26.0/src/wuttaweb/templates/alembic/migrations/create.mako +70 -0
  17. wuttaweb-0.26.0/src/wuttaweb/templates/alembic/migrations/index.mako +25 -0
  18. wuttaweb-0.26.0/src/wuttaweb/templates/alembic/migrations/view.mako +17 -0
  19. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/appinfo/index.mako +20 -0
  20. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/checkbox.pt +4 -2
  21. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/form.mako +8 -6
  22. wuttaweb-0.26.0/src/wuttaweb/templates/forms/vue_buttons.mako +43 -0
  23. wuttaweb-0.26.0/src/wuttaweb/templates/forms/vue_fields.mako +4 -0
  24. wuttaweb-0.26.0/src/wuttaweb/templates/forms/vue_template.mako +54 -0
  25. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/view_version.mako +4 -0
  26. wuttaweb-0.26.0/src/wuttaweb/templates/tables/app/create.mako +1035 -0
  27. wuttaweb-0.26.0/src/wuttaweb/templates/tables/app/index.mako +25 -0
  28. wuttaweb-0.26.0/src/wuttaweb/templates/upgrades/index.mako +14 -0
  29. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/wutta-components.mako +67 -0
  30. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/testing.py +5 -3
  31. wuttaweb-0.26.0/src/wuttaweb/views/alembic.py +565 -0
  32. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/batch.py +2 -2
  33. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/common.py +3 -3
  34. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/email.py +17 -5
  35. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/essential.py +23 -1
  36. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/master.py +278 -147
  37. wuttaweb-0.26.0/src/wuttaweb/views/tables.py +406 -0
  38. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/users.py +1 -0
  39. wuttaweb-0.26.0/tests/forms/main_template.mako +9 -0
  40. wuttaweb-0.26.0/tests/forms/main_template_with_fields.mako +11 -0
  41. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/forms/test_base.py +43 -29
  42. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/forms/test_schema.py +7 -0
  43. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/forms/test_widgets.py +127 -0
  44. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/grids/test_base.py +25 -0
  45. wuttaweb-0.26.0/tests/test_diffs.py +132 -0
  46. wuttaweb-0.26.0/tests/views/test_alembic.py +460 -0
  47. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_master.py +128 -49
  48. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_settings.py +6 -3
  49. wuttaweb-0.26.0/tests/views/test_tables.py +326 -0
  50. wuttaweb-0.25.0/src/wuttaweb/diffs.py +0 -224
  51. wuttaweb-0.25.0/src/wuttaweb/templates/forms/vue_template.mako +0 -99
  52. wuttaweb-0.25.0/tests/test_diffs.py +0 -222
  53. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/.gitignore +0 -0
  54. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/.hgignore +0 -0
  55. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/.pylintrc +0 -0
  56. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/COPYING.txt +0 -0
  57. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/README.md +0 -0
  58. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/Makefile +0 -0
  59. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/_static/.keepme +0 -0
  60. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.app.rst +0 -0
  61. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.auth.rst +0 -0
  62. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.cli.rst +0 -0
  63. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.cli.webapp.rst +0 -0
  64. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.conf.rst +0 -0
  65. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.db.continuum.rst +0 -0
  66. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.db.rst +0 -0
  67. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.db.sess.rst +0 -0
  68. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.diffs.rst +0 -0
  69. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.emails.rst +0 -0
  70. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.forms.base.rst +0 -0
  71. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.forms.rst +0 -0
  72. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.forms.schema.rst +0 -0
  73. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.forms.widgets.rst +0 -0
  74. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.grids.base.rst +0 -0
  75. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.grids.filters.rst +0 -0
  76. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.grids.rst +0 -0
  77. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.handler.rst +0 -0
  78. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.helpers.rst +0 -0
  79. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.menus.rst +0 -0
  80. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.progress.rst +0 -0
  81. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.rst +0 -0
  82. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.static.rst +0 -0
  83. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.subscribers.rst +0 -0
  84. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.util.rst +0 -0
  85. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.auth.rst +0 -0
  86. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.base.rst +0 -0
  87. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.batch.rst +0 -0
  88. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.common.rst +0 -0
  89. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.email.rst +0 -0
  90. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.essential.rst +0 -0
  91. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.master.rst +0 -0
  92. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.people.rst +0 -0
  93. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.progress.rst +0 -0
  94. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.reports.rst +0 -0
  95. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.roles.rst +0 -0
  96. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.rst +0 -0
  97. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.settings.rst +0 -0
  98. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.upgrades.rst +0 -0
  99. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/api/wuttaweb.views.users.rst +0 -0
  100. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/glossary.rst +0 -0
  101. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/make.bat +0 -0
  102. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/narr/cli/builtin.rst +0 -0
  103. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/narr/cli/index.rst +0 -0
  104. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/narr/templates/base.rst +0 -0
  105. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/narr/templates/index.rst +0 -0
  106. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/narr/templates/lookup.rst +0 -0
  107. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/docs/narr/templates/overview.rst +0 -0
  108. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/__init__.py +0 -0
  109. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/_version.py +0 -0
  110. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/app.py +0 -0
  111. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/auth.py +0 -0
  112. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/cli/__init__.py +0 -0
  113. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/cli/webapp.py +0 -0
  114. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/conf.py +0 -0
  115. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/db/__init__.py +0 -0
  116. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/db/continuum.py +0 -0
  117. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/db/sess.py +0 -0
  118. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
  119. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
  120. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/emails.py +0 -0
  121. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/forms/__init__.py +0 -0
  122. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/grids/__init__.py +0 -0
  123. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/grids/filters.py +0 -0
  124. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/handler.py +0 -0
  125. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/helpers.py +0 -0
  126. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/menus.py +0 -0
  127. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/progress.py +0 -0
  128. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/static/__init__.py +0 -0
  129. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/static/img/favicon.ico +0 -0
  130. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/static/img/logo.png +0 -0
  131. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/static/img/testing.png +0 -0
  132. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/subscribers.py +0 -0
  133. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
  134. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/auth/change_password.mako +0 -0
  135. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/auth/login.mako +0 -0
  136. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/base.mako +0 -0
  137. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/base_meta.mako +0 -0
  138. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/batch/view.mako +0 -0
  139. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/configure.mako +0 -0
  140. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
  141. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
  142. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/dateinput.pt +0 -0
  143. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/datetimeinput.pt +0 -0
  144. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
  145. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/password.pt +0 -0
  146. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/permissions.pt +0 -0
  147. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
  148. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
  149. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
  150. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
  151. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
  152. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
  153. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
  154. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/select.pt +0 -0
  155. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/textarea.pt +0 -0
  156. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/textinput.pt +0 -0
  157. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/deform/wutta_checked_password.pt +0 -0
  158. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/diff.mako +0 -0
  159. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/email/settings/view.mako +0 -0
  160. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/forbidden.mako +0 -0
  161. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/grids/table_element.mako +0 -0
  162. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
  163. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/home.mako +0 -0
  164. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/configure.mako +0 -0
  165. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/create.mako +0 -0
  166. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/create_row.mako +0 -0
  167. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/delete.mako +0 -0
  168. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/edit.mako +0 -0
  169. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/form.mako +0 -0
  170. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/index.mako +0 -0
  171. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/view.mako +0 -0
  172. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/master/view_versions.mako +0 -0
  173. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/notfound.mako +0 -0
  174. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/page.mako +0 -0
  175. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/people/view_profile.mako +0 -0
  176. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/progress.mako +0 -0
  177. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/reports/view.mako +0 -0
  178. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/setup.mako +0 -0
  179. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/themes/butterfly/base.mako +0 -0
  180. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/themes/butterfly/buefy-components.mako +0 -0
  181. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/themes/butterfly/buefy-plugin.mako +0 -0
  182. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/themes/butterfly/http-plugin.mako +0 -0
  183. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/upgrade.mako +0 -0
  184. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
  185. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/upgrades/view.mako +0 -0
  186. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/templates/users/view.mako +0 -0
  187. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/util.py +0 -0
  188. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/__init__.py +0 -0
  189. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/auth.py +0 -0
  190. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/base.py +0 -0
  191. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/people.py +0 -0
  192. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/progress.py +0 -0
  193. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/reports.py +0 -0
  194. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/roles.py +0 -0
  195. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/settings.py +0 -0
  196. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/src/wuttaweb/views/upgrades.py +0 -0
  197. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tasks.py +0 -0
  198. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/__init__.py +0 -0
  199. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/cli/__init__.py +0 -0
  200. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/cli/test_webapp.py +0 -0
  201. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/db/__init__.py +0 -0
  202. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/db/test_continuum.py +0 -0
  203. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/grids/__init__.py +0 -0
  204. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/grids/test_filters.py +0 -0
  205. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
  206. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
  207. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_oruga.js +0 -0
  208. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_oruga_bulma.css +0 -0
  209. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_oruga_bulma.js +0 -0
  210. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_vue.js +0 -0
  211. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/bb_vue_fontawesome.js +0 -0
  212. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/buefy.css +0 -0
  213. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/buefy.js +0 -0
  214. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/fontawesome.js +0 -0
  215. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/vue.js +0 -0
  216. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/libcache/vue_resource.js +0 -0
  217. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_app.py +0 -0
  218. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_auth.py +0 -0
  219. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_emails.py +0 -0
  220. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_handler.py +0 -0
  221. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_helpers.py +0 -0
  222. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_menus.py +0 -0
  223. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_progress.py +0 -0
  224. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_static.py +0 -0
  225. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_subscribers.py +0 -0
  226. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/test_util.py +0 -0
  227. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/util.py +0 -0
  228. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/__init__.py +0 -0
  229. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test___init__.py +0 -0
  230. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_auth.py +0 -0
  231. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_base.py +0 -0
  232. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_batch.py +0 -0
  233. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_common.py +0 -0
  234. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_email.py +0 -0
  235. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_essential.py +0 -0
  236. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_people.py +0 -0
  237. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_progress.py +0 -0
  238. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_reports.py +0 -0
  239. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_roles.py +0 -0
  240. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_upgrades.py +0 -0
  241. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tests/views/test_users.py +0 -0
  242. {wuttaweb-0.25.0 → wuttaweb-0.26.0}/tox.ini +0 -0
@@ -5,6 +5,36 @@ All notable changes to wuttaweb will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## v0.26.0 (2025-12-28)
9
+
10
+ ### Feat
11
+
12
+ - add "wizard" for creating new table/model/revision
13
+ - add support for Create Alembic Migration
14
+ - add CopyableTextWidget and `<wutta-copyable-text>` component
15
+ - overhaul how form vue template is rendered
16
+ - add basic views for Alembic Migrations, Dashboard
17
+ - add basic Table views
18
+
19
+ ### Fix
20
+
21
+ - let checkbox widget show static text instead of Yes/No
22
+ - rename form-saving methods etc. for consistency in MasterView
23
+ - temporarily avoid make_uuid()
24
+ - remove password filter option for Users grid
25
+ - use smarter default for `grid.sort_multiple` based on model class
26
+
27
+ ## v0.25.1 (2025-12-20)
28
+
29
+ ### Fix
30
+
31
+ - add `WebDiff` class now that `Diff` lives in wuttjamaican
32
+ - expose fallback key for email settings
33
+ - expose transaction comment for version history
34
+ - show display text for related objects, in version diff
35
+ - discard non-declared field values for grid vue data
36
+ - prevent error in DateTime schema type if no widget/request set
37
+
8
38
  ## v0.25.0 (2025-12-17)
9
39
 
10
40
  ### Feat
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: WuttaWeb
3
- Version: 0.25.0
3
+ Version: 0.26.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
@@ -37,12 +37,13 @@ Requires-Dist: pyramid-fanstatic
37
37
  Requires-Dist: pyramid-mako
38
38
  Requires-Dist: pyramid-tm
39
39
  Requires-Dist: pyramid>=2
40
+ Requires-Dist: sqlalchemy-utils
40
41
  Requires-Dist: waitress
41
42
  Requires-Dist: webhelpers2
42
- Requires-Dist: wuttjamaican[db]>=0.26.0
43
+ Requires-Dist: wuttjamaican[db]>=0.28.0
43
44
  Requires-Dist: zope-sqlalchemy>=1.5
44
45
  Provides-Extra: continuum
45
- Requires-Dist: wutta-continuum>=0.2.2; extra == 'continuum'
46
+ Requires-Dist: wutta-continuum>=0.3.0; extra == 'continuum'
46
47
  Provides-Extra: docs
47
48
  Requires-Dist: furo; extra == 'docs'
48
49
  Requires-Dist: sphinx; extra == 'docs'
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb.views.alembic``
3
+ ==========================
4
+
5
+ .. automodule:: wuttaweb.views.alembic
6
+ :members:
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb.views.tables``
3
+ =========================
4
+
5
+ .. automodule:: wuttaweb.views.tables
6
+ :members:
@@ -28,6 +28,7 @@ templates_path = ["_templates"]
28
28
  exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
29
29
 
30
30
  intersphinx_mapping = {
31
+ "alembic": ("https://alembic.sqlalchemy.org/en/latest/", None),
31
32
  "colander": ("https://docs.pylonsproject.org/projects/colander/en/latest/", None),
32
33
  "deform": ("https://docs.pylonsproject.org/projects/deform/en/latest/", None),
33
34
  "fanstatic": ("https://www.fanstatic.org/en/latest/", None),
@@ -58,6 +58,7 @@ the narrative docs are pretty scant. That will eventually change.
58
58
  api/wuttaweb.subscribers
59
59
  api/wuttaweb.util
60
60
  api/wuttaweb.views
61
+ api/wuttaweb.views.alembic
61
62
  api/wuttaweb.views.auth
62
63
  api/wuttaweb.views.base
63
64
  api/wuttaweb.views.batch
@@ -70,6 +71,7 @@ the narrative docs are pretty scant. That will eventually change.
70
71
  api/wuttaweb.views.reports
71
72
  api/wuttaweb.views.roles
72
73
  api/wuttaweb.views.settings
74
+ api/wuttaweb.views.tables
73
75
  api/wuttaweb.views.upgrades
74
76
  api/wuttaweb.views.users
75
77
 
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "WuttaWeb"
9
- version = "0.25.0"
9
+ version = "0.26.0"
10
10
  description = "Web App for Wutta Framework"
11
11
  readme = "README.md"
12
12
  authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
@@ -42,15 +42,16 @@ dependencies = [
42
42
  "pyramid_fanstatic",
43
43
  "pyramid_mako",
44
44
  "pyramid_tm",
45
+ "SQLAlchemy-Utils",
45
46
  "waitress",
46
47
  "WebHelpers2",
47
- "WuttJamaican[db]>=0.26.0",
48
+ "WuttJamaican[db]>=0.28.0",
48
49
  "zope.sqlalchemy>=1.5",
49
50
  ]
50
51
 
51
52
 
52
53
  [project.optional-dependencies]
53
- continuum = ["Wutta-Continuum>=0.2.2"]
54
+ continuum = ["Wutta-Continuum>=0.3.0"]
54
55
  docs = ["Sphinx", "furo", "sphinxcontrib-programoutput"]
55
56
  tests = ["pylint", "pytest", "pytest-cov", "tox"]
56
57
 
@@ -0,0 +1,68 @@
1
+ ## -*- coding: utf-8; mode: python; -*-
2
+ # -*- coding: utf-8; -*-
3
+ """
4
+ Model definition for ${model_title_plural}
5
+ """
6
+
7
+ import sqlalchemy as sa
8
+ from sqlalchemy import orm
9
+
10
+ from wuttjamaican.db import model
11
+
12
+
13
+ class ${model_name}(model.Base):
14
+ """
15
+ ${description}
16
+ """
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
+ % if versioned:
29
+ % if all([c["versioned"] for c in columns]):
30
+ __versioned__ = {}
31
+ % else:
32
+ __versioned__ = {
33
+ "exclude": [
34
+ % for column in columns:
35
+ % if not column["versioned"]:
36
+ "${column['name']}",
37
+ % endif
38
+ % endfor
39
+ ],
40
+ }
41
+ % endif
42
+ % endif
43
+ __wutta_hint__ = {
44
+ "model_title": "${model_title}",
45
+ "model_title_plural": "${model_title_plural}",
46
+ }
47
+ % for column in columns:
48
+
49
+ % if column["name"] == "uuid":
50
+ uuid = model.uuid_column()
51
+ % else:
52
+ ${column["name"]} = sa.Column(${column["formatted_data_type"]}, nullable=${column["nullable"]}, doc="""
53
+ ${column["description"] or ""}
54
+ """)
55
+ % if column["data_type"]["type"] == "_fk_uuid_" and column["relationship"]:
56
+ ${column["relationship"]["name"]} = orm.relationship(
57
+ "${column['relationship']['reference_model']}",
58
+ doc="""
59
+ ${column["description"] or ""}
60
+ """)
61
+ % endif
62
+ % endif
63
+ % endfor
64
+
65
+ # TODO: you usually should define the __str__() method
66
+
67
+ # def __str__(self):
68
+ # return self.name or ""
@@ -0,0 +1,199 @@
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
+ Tools for displaying simple data diffs
25
+ """
26
+
27
+ import sqlalchemy as sa
28
+
29
+ from pyramid.renderers import render
30
+ from webhelpers2.html import HTML
31
+
32
+ from wuttjamaican.diffs import Diff
33
+
34
+
35
+ class WebDiff(Diff):
36
+ """
37
+ Simple diff class for the web app.
38
+
39
+ This is based on the
40
+ :class:`~wuttjamaican:wuttjamaican.diffs.Diff` class; it just
41
+ tweaks :meth:`render_html()` to use the web template lookup
42
+ engine.
43
+ """
44
+
45
+ cell_padding = None
46
+
47
+ def render_html(self, template="/diff.mako", **kwargs):
48
+ """
49
+ Render the diff as HTML table.
50
+
51
+ :param template: Name of template to render, if you need to
52
+ override the default.
53
+
54
+ :param \\**kwargs: Remaining kwargs are passed as context to
55
+ the template renderer.
56
+
57
+ :returns: HTML literal string
58
+ """
59
+ context = kwargs
60
+ context["diff"] = self
61
+ html = render(template, context)
62
+ return HTML.literal(html)
63
+
64
+
65
+ class VersionDiff(WebDiff):
66
+ """
67
+ Special diff class for use with version history views. While
68
+ based on :class:`WebDiff`, this class uses a different signature
69
+ for the constructor.
70
+
71
+ :param config: The app :term:`config object`.
72
+
73
+ :param version: Reference to a Continuum version record object.
74
+
75
+ :param \\**kwargs: Remaining kwargs are passed as-is to the
76
+ :class:`WebDiff` constructor.
77
+ """
78
+
79
+ def __init__(self, config, version, **kwargs):
80
+ import sqlalchemy_continuum as continuum # pylint: disable=import-outside-toplevel
81
+ from wutta_continuum.util import ( # pylint: disable=import-outside-toplevel
82
+ render_operation_type,
83
+ )
84
+
85
+ self.version = version
86
+ self.model_class = continuum.parent_class(type(self.version))
87
+ self.mapper = sa.inspect(self.model_class)
88
+ self.version_mapper = sa.inspect(type(self.version))
89
+ self.title = kwargs.pop("title", self.model_class.__name__)
90
+
91
+ self.operation_title = render_operation_type(self.version.operation_type)
92
+
93
+ if "nature" not in kwargs:
94
+ if (
95
+ version.previous
96
+ and version.operation_type == continuum.Operation.DELETE
97
+ ):
98
+ kwargs["nature"] = "delete"
99
+ elif version.previous:
100
+ kwargs["nature"] = "update"
101
+ else:
102
+ kwargs["nature"] = "create"
103
+
104
+ if "fields" not in kwargs:
105
+ kwargs["fields"] = self.get_default_fields()
106
+
107
+ old_data = {}
108
+ new_data = {}
109
+ for field in kwargs["fields"]:
110
+ if version.previous:
111
+ old_data[field] = getattr(version.previous, field)
112
+ new_data[field] = getattr(version, field)
113
+
114
+ super().__init__(config, old_data, new_data, **kwargs)
115
+
116
+ def get_default_fields(self): # pylint: disable=missing-function-docstring
117
+ fields = sorted(self.version_mapper.columns.keys())
118
+
119
+ unwanted = [
120
+ "transaction_id",
121
+ "end_transaction_id",
122
+ "operation_type",
123
+ ]
124
+
125
+ return [field for field in fields if field not in unwanted]
126
+
127
+ def render_version_value(self, version, field, value):
128
+ """
129
+ Render the cell value HTML for a given version + field.
130
+
131
+ This method is used to render both sides of the diff (old +
132
+ new values). It will just render the field value using a
133
+ monospace font by default. However:
134
+
135
+ If the field is involved in a mapper relationship (i.e. it is
136
+ the "foreign key" to a related table), the logic here will
137
+ also (try to) traverse that show display text for the related
138
+ object (if found).
139
+
140
+ :param version: Reference to the Continuum version object.
141
+
142
+ :param field: Name of the field, as string.
143
+
144
+ :param value: Raw value for the field, as obtained from the
145
+ version object.
146
+
147
+ :returns: Rendered cell value as HTML literal
148
+ """
149
+ # first render normal span; this is our fallback but also may
150
+ # be embedded within a more complex result.
151
+ text = HTML.tag("span", c=[repr(value)], style="font-family: monospace;")
152
+
153
+ # loop thru all mapped relationship props
154
+ for prop in self.mapper.relationships:
155
+
156
+ # we only want singletons
157
+ if prop.uselist:
158
+ continue
159
+
160
+ # loop thru columns for prop
161
+ # nb. there should always be just one colum for a
162
+ # singleton prop, but technically a list is used, so no
163
+ # harm in looping i assume..
164
+ for col in prop.local_columns:
165
+
166
+ # we only want the matching column
167
+ if col.name != field:
168
+ continue
169
+
170
+ # grab "related version" reference via prop key. this
171
+ # would be like a UserVersion for instance.
172
+ if ref := getattr(version, prop.key):
173
+
174
+ # grab "related object" reference. this would be
175
+ # like a User for instance.
176
+ if ref := getattr(ref, "version_parent", None):
177
+
178
+ # render text w/ related object as bold string
179
+ style = (
180
+ "margin-left: 2rem; font-style: italic; font-weight: bold;"
181
+ )
182
+ return HTML.tag(
183
+ "span",
184
+ c=[text, HTML.tag("span", c=[str(ref)], style=style)],
185
+ )
186
+
187
+ return text
188
+
189
+ def render_old_value(self, field):
190
+ if self.nature == "create":
191
+ return ""
192
+ value = self.old_value(field)
193
+ return self.render_version_value(self.version.previous, field, value)
194
+
195
+ def render_new_value(self, field):
196
+ if self.nature == "delete":
197
+ return ""
198
+ value = self.new_value(field)
199
+ return self.render_version_value(self.version, field, value)