WuttaWeb 0.23.1__tar.gz → 0.24.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 (222) hide show
  1. wuttaweb-0.24.0/.pylintrc +4 -0
  2. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/CHANGELOG.md +25 -0
  3. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/PKG-INFO +3 -3
  4. wuttaweb-0.24.0/docs/api/wuttaweb.diffs.rst +6 -0
  5. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/index.rst +1 -0
  6. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/pyproject.toml +9 -3
  7. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/db/sess.py +2 -2
  8. wuttaweb-0.24.0/src/wuttaweb/diffs.py +224 -0
  9. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/forms/schema.py +3 -0
  10. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/forms/widgets.py +3 -0
  11. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/grids/base.py +4 -2
  12. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/handler.py +1 -1
  13. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/subscribers.py +12 -0
  14. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/base.mako +32 -3
  15. wuttaweb-0.24.0/src/wuttaweb/templates/diff.mako +15 -0
  16. wuttaweb-0.24.0/src/wuttaweb/templates/master/create_row.mako +4 -0
  17. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/view.mako +12 -0
  18. wuttaweb-0.24.0/src/wuttaweb/templates/master/view_version.mako +35 -0
  19. wuttaweb-0.24.0/src/wuttaweb/templates/master/view_versions.mako +20 -0
  20. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/wutta-components.mako +0 -2
  21. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/testing.py +67 -1
  22. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/batch.py +87 -5
  23. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/master.py +716 -17
  24. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/upgrades.py +1 -2
  25. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tasks.py +2 -1
  26. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/forms/test_schema.py +2 -1
  27. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/grids/test_filters.py +0 -4
  28. wuttaweb-0.24.0/tests/test_diffs.py +222 -0
  29. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_handler.py +3 -3
  30. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_subscribers.py +13 -0
  31. wuttaweb-0.24.0/tests/util.py +15 -0
  32. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_batch.py +132 -39
  33. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_master.py +453 -7
  34. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tox.ini +7 -2
  35. wuttaweb-0.23.1/.pylintrc +0 -8
  36. wuttaweb-0.23.1/tests/util.py +0 -43
  37. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/.gitignore +0 -0
  38. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/.hgignore +0 -0
  39. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/COPYING.txt +0 -0
  40. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/README.md +0 -0
  41. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/Makefile +0 -0
  42. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/_static/.keepme +0 -0
  43. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.app.rst +0 -0
  44. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.auth.rst +0 -0
  45. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.cli.rst +0 -0
  46. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.cli.webapp.rst +0 -0
  47. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.conf.rst +0 -0
  48. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.db.continuum.rst +0 -0
  49. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.db.rst +0 -0
  50. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.db.sess.rst +0 -0
  51. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.emails.rst +0 -0
  52. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.forms.base.rst +0 -0
  53. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.forms.rst +0 -0
  54. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.forms.schema.rst +0 -0
  55. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.forms.widgets.rst +0 -0
  56. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.grids.base.rst +0 -0
  57. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.grids.filters.rst +0 -0
  58. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.grids.rst +0 -0
  59. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.handler.rst +0 -0
  60. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.helpers.rst +0 -0
  61. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.menus.rst +0 -0
  62. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.progress.rst +0 -0
  63. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.rst +0 -0
  64. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.static.rst +0 -0
  65. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.subscribers.rst +0 -0
  66. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.util.rst +0 -0
  67. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.auth.rst +0 -0
  68. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.base.rst +0 -0
  69. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.batch.rst +0 -0
  70. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.common.rst +0 -0
  71. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.email.rst +0 -0
  72. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.essential.rst +0 -0
  73. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.master.rst +0 -0
  74. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.people.rst +0 -0
  75. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.progress.rst +0 -0
  76. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.reports.rst +0 -0
  77. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.roles.rst +0 -0
  78. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.rst +0 -0
  79. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.settings.rst +0 -0
  80. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.upgrades.rst +0 -0
  81. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/api/wuttaweb.views.users.rst +0 -0
  82. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/conf.py +0 -0
  83. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/glossary.rst +0 -0
  84. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/make.bat +0 -0
  85. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/narr/cli/builtin.rst +0 -0
  86. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/narr/cli/index.rst +0 -0
  87. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/narr/templates/base.rst +0 -0
  88. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/narr/templates/index.rst +0 -0
  89. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/narr/templates/lookup.rst +0 -0
  90. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/docs/narr/templates/overview.rst +0 -0
  91. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/__init__.py +0 -0
  92. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/_version.py +0 -0
  93. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/app.py +0 -0
  94. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/auth.py +0 -0
  95. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/cli/__init__.py +0 -0
  96. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/cli/webapp.py +0 -0
  97. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/conf.py +0 -0
  98. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/db/__init__.py +0 -0
  99. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/db/continuum.py +0 -0
  100. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/email-templates/feedback.html.mako +0 -0
  101. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/email-templates/feedback.txt.mako +0 -0
  102. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/emails.py +0 -0
  103. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/forms/__init__.py +0 -0
  104. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/forms/base.py +0 -0
  105. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/grids/__init__.py +0 -0
  106. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/grids/filters.py +0 -0
  107. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/helpers.py +0 -0
  108. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/menus.py +0 -0
  109. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/progress.py +0 -0
  110. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/static/__init__.py +0 -0
  111. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/static/img/favicon.ico +0 -0
  112. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/static/img/logo.png +0 -0
  113. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/static/img/testing.png +0 -0
  114. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/appinfo/configure.mako +0 -0
  115. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/appinfo/index.mako +0 -0
  116. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/auth/change_password.mako +0 -0
  117. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/auth/login.mako +0 -0
  118. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/base_meta.mako +0 -0
  119. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/batch/view.mako +0 -0
  120. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/configure.mako +0 -0
  121. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
  122. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
  123. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
  124. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/dateinput.pt +0 -0
  125. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/datetimeinput.pt +0 -0
  126. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/moneyinput.pt +0 -0
  127. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/password.pt +0 -0
  128. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/permissions.pt +0 -0
  129. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/checkbox.pt +0 -0
  130. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/email_recips.pt +0 -0
  131. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/filedownload.pt +0 -0
  132. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
  133. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
  134. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
  135. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/readonly/rolerefs.pt +0 -0
  136. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/select.pt +0 -0
  137. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/textarea.pt +0 -0
  138. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/textinput.pt +0 -0
  139. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/deform/wutta_checked_password.pt +0 -0
  140. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/email/settings/view.mako +0 -0
  141. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/forbidden.mako +0 -0
  142. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/form.mako +0 -0
  143. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
  144. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/grids/table_element.mako +0 -0
  145. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/grids/vue_template.mako +0 -0
  146. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/home.mako +0 -0
  147. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/configure.mako +0 -0
  148. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/create.mako +0 -0
  149. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/delete.mako +0 -0
  150. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/edit.mako +0 -0
  151. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/form.mako +0 -0
  152. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/master/index.mako +0 -0
  153. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/notfound.mako +0 -0
  154. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/page.mako +0 -0
  155. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/people/view_profile.mako +0 -0
  156. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/progress.mako +0 -0
  157. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/reports/view.mako +0 -0
  158. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/setup.mako +0 -0
  159. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/themes/butterfly/base.mako +0 -0
  160. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/themes/butterfly/buefy-components.mako +0 -0
  161. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/themes/butterfly/buefy-plugin.mako +0 -0
  162. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/themes/butterfly/http-plugin.mako +0 -0
  163. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/upgrade.mako +0 -0
  164. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/upgrades/configure.mako +0 -0
  165. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/upgrades/view.mako +0 -0
  166. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/templates/users/view.mako +0 -0
  167. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/util.py +0 -0
  168. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/__init__.py +0 -0
  169. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/auth.py +0 -0
  170. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/base.py +0 -0
  171. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/common.py +0 -0
  172. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/email.py +0 -0
  173. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/essential.py +0 -0
  174. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/people.py +0 -0
  175. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/progress.py +0 -0
  176. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/reports.py +0 -0
  177. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/roles.py +0 -0
  178. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/settings.py +0 -0
  179. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/src/wuttaweb/views/users.py +0 -0
  180. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/__init__.py +0 -0
  181. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/cli/__init__.py +0 -0
  182. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/cli/test_webapp.py +0 -0
  183. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/db/__init__.py +0 -0
  184. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/db/test_continuum.py +0 -0
  185. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/forms/test_base.py +0 -0
  186. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/forms/test_widgets.py +0 -0
  187. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/grids/__init__.py +0 -0
  188. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/grids/test_base.py +0 -0
  189. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
  190. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
  191. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_oruga.js +0 -0
  192. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_oruga_bulma.css +0 -0
  193. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_oruga_bulma.js +0 -0
  194. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_vue.js +0 -0
  195. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/bb_vue_fontawesome.js +0 -0
  196. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/buefy.css +0 -0
  197. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/buefy.js +0 -0
  198. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/fontawesome.js +0 -0
  199. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/vue.js +0 -0
  200. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/libcache/vue_resource.js +0 -0
  201. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_app.py +0 -0
  202. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_auth.py +0 -0
  203. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_emails.py +0 -0
  204. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_helpers.py +0 -0
  205. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_menus.py +0 -0
  206. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_progress.py +0 -0
  207. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_static.py +0 -0
  208. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/test_util.py +0 -0
  209. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/__init__.py +0 -0
  210. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test___init__.py +0 -0
  211. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_auth.py +0 -0
  212. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_base.py +0 -0
  213. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_common.py +0 -0
  214. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_email.py +0 -0
  215. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_essential.py +0 -0
  216. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_people.py +0 -0
  217. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_progress.py +0 -0
  218. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_reports.py +0 -0
  219. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_roles.py +0 -0
  220. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_settings.py +0 -0
  221. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_upgrades.py +0 -0
  222. {wuttaweb-0.23.1 → wuttaweb-0.24.0}/tests/views/test_users.py +0 -0
@@ -0,0 +1,4 @@
1
+ # -*- mode: conf; -*-
2
+
3
+ [MESSAGES CONTROL]
4
+ disable=fixme
@@ -5,6 +5,31 @@ 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.24.0 (2025-12-15)
9
+
10
+ ### Feat
11
+
12
+ - basic support for displaying version history
13
+
14
+ ### Fix
15
+
16
+ - use UTC when updating timestamp in DB
17
+ - workaround error when 'fanstatic.needed' missing from environ
18
+ - workaround error when 'fanstatic.needed' missing from environ
19
+ - address pylint warnings
20
+ - add basic `create_row()` support, esp. for batch views
21
+ - update dependencies for wuttjamaican, wutta-continuum
22
+ - make master view auto-detect continuum versioning for model class
23
+ - fix 'invalid-name' for pylint
24
+
25
+ ## v0.23.2 (2025-10-19)
26
+
27
+ ### Fix
28
+
29
+ - require latest wuttjamaican
30
+ - remove unused statement in WuttaFilter component
31
+ - explicitly disable 'duplicate-code' false alarm
32
+
8
33
  ## v0.23.1 (2025-09-01)
9
34
 
10
35
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: WuttaWeb
3
- Version: 0.23.1
3
+ Version: 0.24.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,10 +39,10 @@ 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.23.1
42
+ Requires-Dist: wuttjamaican[db]>=0.25.0
43
43
  Requires-Dist: zope-sqlalchemy>=1.5
44
44
  Provides-Extra: continuum
45
- Requires-Dist: wutta-continuum; extra == 'continuum'
45
+ Requires-Dist: wutta-continuum>=0.2.2; extra == 'continuum'
46
46
  Provides-Extra: docs
47
47
  Requires-Dist: furo; extra == 'docs'
48
48
  Requires-Dist: sphinx; extra == 'docs'
@@ -0,0 +1,6 @@
1
+
2
+ ``wuttaweb.diffs``
3
+ ==================
4
+
5
+ .. automodule:: wuttaweb.diffs
6
+ :members:
@@ -41,6 +41,7 @@ the narrative docs are pretty scant. That will eventually change.
41
41
  api/wuttaweb.db
42
42
  api/wuttaweb.db.continuum
43
43
  api/wuttaweb.db.sess
44
+ api/wuttaweb.diffs
44
45
  api/wuttaweb.emails
45
46
  api/wuttaweb.forms
46
47
  api/wuttaweb.forms.base
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "WuttaWeb"
9
- version = "0.23.1"
9
+ version = "0.24.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,13 +44,13 @@ dependencies = [
44
44
  "pyramid_tm",
45
45
  "waitress",
46
46
  "WebHelpers2",
47
- "WuttJamaican[db]>=0.23.1",
47
+ "WuttJamaican[db]>=0.25.0",
48
48
  "zope.sqlalchemy>=1.5",
49
49
  ]
50
50
 
51
51
 
52
52
  [project.optional-dependencies]
53
- continuum = ["Wutta-Continuum"]
53
+ continuum = ["Wutta-Continuum>=0.2.2"]
54
54
  docs = ["Sphinx", "furo", "sphinxcontrib-programoutput"]
55
55
  tests = ["pylint", "pytest", "pytest-cov", "tox"]
56
56
 
@@ -91,3 +91,9 @@ update_changelog_on_bump = true
91
91
  exclude = [
92
92
  "htmlcov/",
93
93
  ]
94
+
95
+
96
+ [tool.pytest.ini_options]
97
+ markers = [
98
+ "versioned: tests with SQLAlchemy-Continuum versioning feature enabled",
99
+ ]
@@ -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
  #
@@ -61,6 +61,6 @@ from sqlalchemy import orm
61
61
  from zope.sqlalchemy.datamanager import register
62
62
 
63
63
 
64
- Session = orm.scoped_session(orm.sessionmaker())
64
+ Session = orm.scoped_session(orm.sessionmaker()) # pylint: disable=invalid-name
65
65
 
66
66
  register(Session)
@@ -0,0 +1,224 @@
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
+
33
+ class Diff:
34
+ """
35
+ Represent / display a basic "diff" between two data records.
36
+
37
+ You must provide both the "old" and "new" data records, when
38
+ constructing an instance of this class. Then call
39
+ :meth:`render_html()` to display the diff table.
40
+
41
+ :param old_data: Dict of "old" data record.
42
+
43
+ :param new_data: Dict of "new" data record.
44
+
45
+ :param fields: Optional list of field names. If not specified,
46
+ will be derived from the data records.
47
+
48
+ :param nature: What sort of diff is being represented; must be one
49
+ of: ``("create", "update", "delete")``
50
+
51
+ :param old_color: Background color to display for "old/deleted"
52
+ field data, when applicable.
53
+
54
+ :param new_color: Background color to display for "new/created"
55
+ field data, when applicable.
56
+ """
57
+
58
+ def __init__( # pylint: disable=too-many-arguments,too-many-positional-arguments
59
+ self,
60
+ old_data: dict,
61
+ new_data: dict,
62
+ fields: list = None,
63
+ nature="update",
64
+ old_color="#ffebe9",
65
+ new_color="#dafbe1",
66
+ ):
67
+ self.old_data = old_data
68
+ self.new_data = new_data
69
+ self.columns = ["field name", "old value", "new value"]
70
+ self.fields = fields or self.make_fields()
71
+ self.nature = nature
72
+ self.old_color = old_color
73
+ self.new_color = new_color
74
+
75
+ def make_fields(self): # pylint: disable=missing-function-docstring
76
+ return sorted(set(self.old_data) | set(self.new_data), key=lambda x: x.lower())
77
+
78
+ def old_value(self, field): # pylint: disable=missing-function-docstring
79
+ return self.old_data.get(field)
80
+
81
+ def new_value(self, field): # pylint: disable=missing-function-docstring
82
+ return self.new_data.get(field)
83
+
84
+ def values_differ(self, field): # pylint: disable=missing-function-docstring
85
+ return self.new_value(field) != self.old_value(field)
86
+
87
+ def render_html(self, template="/diff.mako", **kwargs):
88
+ """
89
+ Render the diff as HTML table.
90
+
91
+ :param template: Name of template to render, if you need to
92
+ override the default.
93
+
94
+ :param \\**kwargs: Remaining kwargs are passed as context to
95
+ the template renderer.
96
+
97
+ :returns: HTML literal string
98
+ """
99
+ context = kwargs
100
+ context["diff"] = self
101
+ return HTML.literal(render(template, context))
102
+
103
+ def render_field_row(self, field): # pylint: disable=missing-function-docstring
104
+ is_diff = self.values_differ(field)
105
+
106
+ td_field = HTML.tag("td", class_="field", c=field)
107
+
108
+ td_old_value = HTML.tag(
109
+ "td",
110
+ c=self.render_old_value(field),
111
+ **self.get_old_value_attrs(is_diff),
112
+ )
113
+
114
+ td_new_value = HTML.tag(
115
+ "td",
116
+ c=self.render_new_value(field),
117
+ **self.get_new_value_attrs(is_diff),
118
+ )
119
+
120
+ return HTML.tag("tr", c=[td_field, td_old_value, td_new_value])
121
+
122
+ def render_old_value(self, field): # pylint: disable=missing-function-docstring
123
+ value = self.old_value(field)
124
+ return repr(value)
125
+
126
+ def render_new_value(self, field): # pylint: disable=missing-function-docstring
127
+ value = self.new_value(field)
128
+ return repr(value)
129
+
130
+ def get_old_value_attrs( # pylint: disable=missing-function-docstring
131
+ self, is_diff
132
+ ):
133
+ attrs = {}
134
+ if self.nature == "update" and is_diff:
135
+ attrs["style"] = f"background-color: {self.old_color};"
136
+ elif self.nature == "delete":
137
+ attrs["style"] = f"background-color: {self.old_color};"
138
+ return attrs
139
+
140
+ def get_new_value_attrs( # pylint: disable=missing-function-docstring
141
+ self, is_diff
142
+ ):
143
+ attrs = {}
144
+ if self.nature == "create":
145
+ attrs["style"] = f"background-color: {self.new_color};"
146
+ elif self.nature == "update" and is_diff:
147
+ attrs["style"] = f"background-color: {self.new_color};"
148
+ return attrs
149
+
150
+
151
+ class VersionDiff(Diff):
152
+ """
153
+ Special diff class, for use with version history views. Note that
154
+ while based on :class:`Diff`, this class uses a different
155
+ signature for the constructor.
156
+
157
+ :param version: Reference to a Continuum version record (object).
158
+
159
+ :param \\**kwargs: Remaining kwargs are passed as-is to the
160
+ :class:`Diff` constructor.
161
+ """
162
+
163
+ def __init__(self, version, **kwargs):
164
+ import sqlalchemy_continuum as continuum # pylint: disable=import-outside-toplevel
165
+ from wutta_continuum.util import ( # pylint: disable=import-outside-toplevel
166
+ render_operation_type,
167
+ )
168
+
169
+ self.version = version
170
+ self.model_class = continuum.parent_class(type(self.version))
171
+ self.mapper = sa.inspect(self.model_class)
172
+ self.version_mapper = sa.inspect(type(self.version))
173
+ self.title = kwargs.pop("title", self.model_class.__name__)
174
+
175
+ self.operation_title = render_operation_type(self.version.operation_type)
176
+
177
+ if "nature" not in kwargs:
178
+ if (
179
+ version.previous
180
+ and version.operation_type == continuum.Operation.DELETE
181
+ ):
182
+ kwargs["nature"] = "delete"
183
+ elif version.previous:
184
+ kwargs["nature"] = "update"
185
+ else:
186
+ kwargs["nature"] = "create"
187
+
188
+ if "fields" not in kwargs:
189
+ kwargs["fields"] = self.get_default_fields()
190
+
191
+ old_data = {}
192
+ new_data = {}
193
+ for field in kwargs["fields"]:
194
+ if version.previous:
195
+ old_data[field] = getattr(version.previous, field)
196
+ new_data[field] = getattr(version, field)
197
+
198
+ super().__init__(old_data, new_data, **kwargs)
199
+
200
+ def get_default_fields(self): # pylint: disable=missing-function-docstring
201
+ fields = sorted(self.version_mapper.columns.keys())
202
+
203
+ unwanted = [
204
+ "transaction_id",
205
+ "end_transaction_id",
206
+ "operation_type",
207
+ ]
208
+
209
+ return [field for field in fields if field not in unwanted]
210
+
211
+ def render_version_value(self, value): # pylint: disable=missing-function-docstring
212
+ return HTML.tag("span", c=[repr(value)], style="font-family: monospace;")
213
+
214
+ def render_old_value(self, field):
215
+ if self.nature == "create":
216
+ return ""
217
+ value = self.old_value(field)
218
+ return self.render_version_value(value)
219
+
220
+ def render_new_value(self, field):
221
+ if self.nature == "delete":
222
+ return ""
223
+ value = self.new_value(field)
224
+ return self.render_version_value(value)
@@ -634,6 +634,7 @@ class FileDownload(colander.String):
634
634
  name/size is shown with no hyperlink.
635
635
  """
636
636
 
637
+ # pylint: disable=duplicate-code
637
638
  def __init__(self, request, *args, **kwargs):
638
639
  self.url = kwargs.pop("url", None)
639
640
  super().__init__(*args, **kwargs)
@@ -641,6 +642,8 @@ class FileDownload(colander.String):
641
642
  self.config = self.request.wutta_config
642
643
  self.app = self.config.get_app()
643
644
 
645
+ # pylint: enable=duplicate-code
646
+
644
647
  def widget_maker(self, **kwargs): # pylint: disable=empty-docstring
645
648
  """ """
646
649
  kwargs.setdefault("url", self.url)
@@ -321,6 +321,7 @@ class FileDownloadWidget(Widget): # pylint: disable=abstract-method
321
321
 
322
322
  readonly_template = "readonly/filedownload"
323
323
 
324
+ # pylint: disable=duplicate-code
324
325
  def __init__(self, request, *args, **kwargs):
325
326
  self.url = kwargs.pop("url", None)
326
327
  super().__init__(*args, **kwargs)
@@ -328,6 +329,8 @@ class FileDownloadWidget(Widget): # pylint: disable=abstract-method
328
329
  self.config = self.request.wutta_config
329
330
  self.app = self.config.get_app()
330
331
 
332
+ # pylint: enable=duplicate-code
333
+
331
334
  def serialize(self, field, cstruct, **kw): # pylint: disable=empty-docstring
332
335
  """ """
333
336
  # nb. readonly is the only way this rolls
@@ -84,7 +84,8 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
84
84
  .. attribute:: vue_tagname
85
85
 
86
86
  String name for Vue component tag. By default this is
87
- ``'wutta-grid'``. See also :meth:`render_vue_tag()`.
87
+ ``'wutta-grid'``. See also :meth:`render_vue_tag()`
88
+ and :attr:`vue_component`.
88
89
 
89
90
  .. attribute:: model_class
90
91
 
@@ -841,8 +842,9 @@ class Grid: # pylint: disable=too-many-instance-attributes,too-many-public-meth
841
842
  def set_tools(self, tools):
842
843
  """
843
844
  Set the :attr:`tools` attribute using the given tools collection.
844
-
845
845
  This will normalize the list/dict to desired internal format.
846
+
847
+ See also :meth:`add_tool()`.
846
848
  """
847
849
  if tools and isinstance(tools, list):
848
850
  if not any(isinstance(t, (tuple, list)) for t in tools):
@@ -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
  #
@@ -41,6 +41,7 @@ import logging
41
41
  from collections import OrderedDict
42
42
 
43
43
  from pyramid import threadlocal
44
+ from pyramid.httpexceptions import HTTPFound
44
45
 
45
46
  from wuttaweb import helpers
46
47
  from wuttaweb.db import Session
@@ -123,6 +124,17 @@ def new_request(event):
123
124
  config = request.registry.settings["wutta_config"]
124
125
  app = config.get_app()
125
126
 
127
+ # nb. in rare circumstances i have received unhandled error email,
128
+ # which somehow was triggered by 'fanstatic.needed' being missing
129
+ # from the environ. not sure why that would happen, but it seems
130
+ # to when crawlers request a non-existent filename under the
131
+ # fanstatic path. there isn't a great way to handle it since
132
+ # e.g. can't show the normal error page if JS resources won't
133
+ # load, so we try a hail-mary redirect..
134
+ # (nb. also we skip this if environ is empty, i.e. for tests)
135
+ if request.environ and "fanstatic.needed" not in request.environ:
136
+ raise HTTPFound(location=request.route_url("home"))
137
+
126
138
  request.wutta_config = config
127
139
 
128
140
  def get_referrer(default=None):
@@ -152,6 +152,8 @@
152
152
  font-size: 2rem;
153
153
  font-weight: bold;
154
154
  margin-bottom: 0 !important;
155
+ display: flex;
156
+ gap: 0.6rem;
155
157
  }
156
158
 
157
159
  #content-title h1 {
@@ -242,7 +244,9 @@
242
244
  ## nb. this is the index title proper
243
245
  <div class="level-left">
244
246
  <div id="header-index-title" class="level-item">
245
- % if index_title:
247
+ % if index_title_rendered is not Undefined and index_title_rendered:
248
+ <h1 class="title">${index_title_rendered}</h1>
249
+ % elif index_title:
246
250
  % if index_url:
247
251
  <h1 class="title">${h.link_to(index_title, index_url)}</h1>
248
252
  % else:
@@ -279,7 +283,7 @@
279
283
  class="has-background-primary">
280
284
  <div style="display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem;">
281
285
 
282
- <div style="width: 60%; display: flex; gap: 0.5rem;">
286
+ <div style="width: 60%; display: flex; gap: 1rem;">
283
287
 
284
288
  <h1 class="title has-text-white"
285
289
  v-html="contentTitleHTML">
@@ -781,7 +785,32 @@
781
785
  % endif
782
786
  </%def>
783
787
 
784
- <%def name="render_prevnext_header_buttons()"></%def>
788
+ <%def name="render_prevnext_header_buttons()">
789
+ % if show_prev_next is not Undefined and show_prev_next:
790
+ <b-button tag="a"
791
+ % if prev_url:
792
+ href="${prev_url}"
793
+ % else:
794
+ href="#"
795
+ disabled
796
+ % endif
797
+ icon-pack="fas"
798
+ icon-left="arrow-left">
799
+ Older
800
+ </b-button>
801
+ <b-button tag="a"
802
+ % if next_url:
803
+ href="${next_url}"
804
+ % else:
805
+ href="#"
806
+ disabled
807
+ % endif
808
+ icon-pack="fas"
809
+ icon-left="arrow-right">
810
+ Newer
811
+ </b-button>
812
+ % endif
813
+ </%def>
785
814
 
786
815
  ##############################
787
816
  ## vue components + app
@@ -0,0 +1,15 @@
1
+ ## -*- coding: utf-8; -*-
2
+ <table class="table is-fullwidth is-bordered is-narrow">
3
+ <thead>
4
+ <tr>
5
+ % for column in diff.columns:
6
+ <th>${column}</th>
7
+ % endfor
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ % for field in diff.fields:
12
+ ${diff.render_field_row(field)}
13
+ % endfor
14
+ </tbody>
15
+ </table>
@@ -0,0 +1,4 @@
1
+ ## -*- coding: utf-8; -*-
2
+ <%inherit file="/master/form.mako" />
3
+
4
+ <%def name="title()">New ${row_model_title}</%def>
@@ -5,6 +5,18 @@
5
5
 
6
6
  <%def name="content_title()">${instance_title}</%def>
7
7
 
8
+ <%def name="render_instance_header_title_extras()">
9
+ ${parent.render_instance_header_title_extras()}
10
+ % if master.should_expose_versions():
11
+ <b-button tag="a"
12
+ href="${master.get_action_url('versions', instance)}"
13
+ icon-pack="fas"
14
+ icon-left="history">
15
+ View History
16
+ </b-button>
17
+ % endif
18
+ </%def>
19
+
8
20
  <%def name="page_layout()">
9
21
 
10
22
  % if master.has_rows:
@@ -0,0 +1,35 @@
1
+ ## -*- coding: utf-8; -*-
2
+ <%inherit file="/master/form.mako" />
3
+
4
+ <%def name="title()">${index_title} » ${instance_title} » changes @ TXN ${transaction.id}</%def>
5
+
6
+ <%def name="content_title()">changes @ TXN ${transaction.id}</%def>
7
+
8
+ <%def name="page_content()">
9
+ <div class="wutta-form-wrapper">
10
+
11
+ <b-field label="Changed" horizontal>
12
+ <span>${changed}</span>
13
+ </b-field>
14
+
15
+ <b-field label="Changed by" horizontal>
16
+ <span>${transaction.user or ""}</span>
17
+ </b-field>
18
+
19
+ <b-field label="IP Address" horizontal>
20
+ <span>${transaction.remote_addr or ""}</span>
21
+ </b-field>
22
+
23
+ <b-field label="TXN ID" horizontal>
24
+ <span>${transaction.id}</span>
25
+ </b-field>
26
+
27
+ </div>
28
+
29
+ <div style="padding: 2rem;">
30
+ % for diff in version_diffs:
31
+ <h4 class="is-size-4 block">${diff.title} (${diff.operation_title})</h4>
32
+ ${diff.render_html()}
33
+ % endfor
34
+ </div>
35
+ </%def>
@@ -0,0 +1,20 @@
1
+ ## -*- coding: utf-8; -*-
2
+ <%inherit file="/page.mako" />
3
+
4
+ <%def name="title()">${index_title} » ${instance_title} » history</%def>
5
+
6
+ <%def name="content_title()">Version History</%def>
7
+
8
+ <%def name="page_content()">
9
+ ${grid.render_vue_tag()}
10
+ </%def>
11
+
12
+ <%def name="render_vue_templates()">
13
+ ${parent.render_vue_templates()}
14
+ ${grid.render_vue_template()}
15
+ </%def>
16
+
17
+ <%def name="make_vue_components()">
18
+ ${parent.make_vue_components()}
19
+ ${grid.render_vue_finalize()}
20
+ </%def>