wagtail 6.0.2__py3-none-any.whl → 6.1rc1__py3-none-any.whl

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 (355) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/admin/checks.py +51 -0
  3. wagtail/admin/compare.py +1 -1
  4. wagtail/admin/filters.py +70 -1
  5. wagtail/admin/forms/account.py +1 -1
  6. wagtail/admin/forms/collections.py +15 -0
  7. wagtail/admin/forms/pages.py +49 -0
  8. wagtail/admin/locale/de/LC_MESSAGES/django.mo +0 -0
  9. wagtail/admin/locale/de/LC_MESSAGES/django.po +5 -5
  10. wagtail/admin/locale/en/LC_MESSAGES/django.po +474 -385
  11. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +3 -3
  12. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  13. wagtail/admin/locale/pt_PT/LC_MESSAGES/django.po +73 -2
  14. wagtail/admin/locale/ro/LC_MESSAGES/django.mo +0 -0
  15. wagtail/admin/locale/ro/LC_MESSAGES/django.po +3 -3
  16. wagtail/admin/panels/comment_panel.py +1 -1
  17. wagtail/admin/panels/field_panel.py +1 -1
  18. wagtail/admin/rich_text/converters/editor_html.py +3 -1
  19. wagtail/admin/rich_text/editors/draftail/__init__.py +28 -2
  20. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  21. wagtail/admin/static/wagtailadmin/css/panels/draftail.css +1 -1
  22. wagtail/admin/static/wagtailadmin/images/favicon.ico +0 -0
  23. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  24. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  25. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  26. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  27. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  28. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  29. wagtail/admin/static/wagtailadmin/js/core.js.LICENSE.txt +1 -1
  30. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  31. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  32. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
  33. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  34. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  37. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  38. wagtail/admin/static/wagtailadmin/js/preview-panel.js +1 -1
  39. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  40. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  42. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  44. wagtail/admin/static/wagtailadmin/js/telepath/telepath.js +1 -1
  45. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  46. wagtail/admin/static/wagtailadmin/js/userbar.js +1 -1
  47. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  48. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +4 -4
  49. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  50. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  51. wagtail/admin/staticfiles.py +1 -0
  52. wagtail/admin/templates/wagtailadmin/base.html +1 -0
  53. wagtail/admin/templates/wagtailadmin/collection_privacy/set_privacy.html +3 -1
  54. wagtail/admin/templates/wagtailadmin/collections/index_results.html +10 -0
  55. wagtail/admin/templates/wagtailadmin/generic/base.html +1 -9
  56. wagtail/admin/templates/wagtailadmin/generic/form.html +3 -2
  57. wagtail/admin/templates/wagtailadmin/generic/history/action_cell.html +27 -0
  58. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +3 -3
  59. wagtail/admin/templates/wagtailadmin/icons/keyboard.svg +1 -0
  60. wagtail/admin/templates/wagtailadmin/page_privacy/set_privacy.html +3 -1
  61. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -14
  62. wagtail/admin/templates/wagtailadmin/pages/action_menu/save_draft.html +3 -1
  63. wagtail/admin/templates/wagtailadmin/pages/choose_parent.html +17 -0
  64. wagtail/admin/templates/wagtailadmin/pages/explorable_index.html +8 -0
  65. wagtail/admin/templates/wagtailadmin/pages/history.html +1 -61
  66. wagtail/admin/templates/wagtailadmin/pages/index.html +1 -3
  67. wagtail/admin/templates/wagtailadmin/pages/listing/_locked_indicator.html +2 -2
  68. wagtail/admin/templates/wagtailadmin/pages/listing/_page_title_column_header.html +25 -27
  69. wagtail/admin/templates/wagtailadmin/pages/page_listing_header.html +2 -1
  70. wagtail/admin/templates/wagtailadmin/panels/multi_field_panel_child.html +1 -1
  71. wagtail/admin/templates/wagtailadmin/panels/publishing/schedule_publishing_panel.html +3 -1
  72. wagtail/admin/templates/wagtailadmin/panels/tabbed_interface.html +1 -1
  73. wagtail/admin/templates/wagtailadmin/shared/active_filters.html +2 -1
  74. wagtail/admin/templates/wagtailadmin/shared/breadcrumbs.html +8 -0
  75. wagtail/admin/templates/wagtailadmin/shared/forms/single_checkbox.html +1 -1
  76. wagtail/admin/templates/wagtailadmin/shared/headers/page_edit_header.html +1 -1
  77. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +21 -9
  78. wagtail/admin/templates/wagtailadmin/shared/human_readable_date.html +1 -1
  79. wagtail/admin/templates/wagtailadmin/shared/keyboard_shortcuts_dialog.html +29 -0
  80. wagtail/admin/templates/wagtailadmin/shared/side_panel_toggle.html +2 -1
  81. wagtail/admin/templates/wagtailadmin/skeleton.html +2 -1
  82. wagtail/admin/templates/wagtailadmin/tables/related_objects_cell.html +9 -0
  83. wagtail/admin/templates/wagtailadmin/tables/title_cell.html +9 -7
  84. wagtail/admin/templates/wagtailadmin/widgets/draftail_rich_text_area.html +1 -1
  85. wagtail/admin/templates/wagtailadmin/workflows/create.html +6 -23
  86. wagtail/admin/templates/wagtailadmin/workflows/create_task.html +6 -15
  87. wagtail/admin/templates/wagtailadmin/workflows/edit.html +6 -23
  88. wagtail/admin/templates/wagtailadmin/workflows/edit_task.html +6 -13
  89. wagtail/admin/templates/wagtailadmin/workflows/includes/task_usage_cell.html +4 -4
  90. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_tasks_cell.html +18 -0
  91. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_title_cell.html +7 -0
  92. wagtail/admin/templates/wagtailadmin/workflows/includes/workflow_used_by_cell.html +25 -0
  93. wagtail/admin/templates/wagtailadmin/workflows/index.html +0 -99
  94. wagtail/admin/templates/wagtailadmin/workflows/index_results.html +10 -0
  95. wagtail/admin/templates/wagtailadmin/workflows/task_index.html +0 -30
  96. wagtail/admin/templates/wagtailadmin/workflows/task_index_results.html +10 -0
  97. wagtail/admin/templates/wagtailadmin/workflows/usage.html +1 -1
  98. wagtail/admin/templatetags/wagtailadmin_tags.py +116 -39
  99. wagtail/admin/tests/pages/test_create_page.py +10 -4
  100. wagtail/admin/tests/pages/test_custom_listing.py +37 -0
  101. wagtail/admin/tests/pages/test_edit_page.py +6 -6
  102. wagtail/admin/tests/pages/test_explorer_view.py +19 -18
  103. wagtail/admin/tests/pages/test_move_page.py +1 -1
  104. wagtail/admin/tests/pages/test_page_usage.py +50 -2
  105. wagtail/admin/tests/pages/test_parent_page_chooser_view.py +119 -0
  106. wagtail/admin/tests/pages/test_preview.py +18 -4
  107. wagtail/admin/tests/test_account_management.py +20 -1
  108. wagtail/admin/tests/test_audit_log.py +172 -5
  109. wagtail/admin/tests/test_checks.py +92 -0
  110. wagtail/admin/tests/test_collections_views.py +19 -5
  111. wagtail/admin/tests/test_compare.py +6 -6
  112. wagtail/admin/tests/test_dashboard.py +404 -0
  113. wagtail/admin/tests/test_dbwhitelister.py +4 -5
  114. wagtail/admin/tests/test_edit_handlers.py +2 -2
  115. wagtail/admin/tests/test_keyboard_shortcuts.py +84 -0
  116. wagtail/admin/tests/test_page_chooser.py +31 -18
  117. wagtail/admin/tests/test_privacy.py +36 -2
  118. wagtail/admin/tests/test_rich_text.py +168 -23
  119. wagtail/admin/tests/test_templatetags.py +411 -43
  120. wagtail/admin/tests/test_views.py +4 -2
  121. wagtail/admin/tests/test_workflows.py +531 -9
  122. wagtail/admin/tests/tests.py +3 -1
  123. wagtail/admin/tests/ui/test_tables.py +48 -1
  124. wagtail/admin/tests/viewsets/test_model_viewset.py +126 -29
  125. wagtail/admin/ui/side_panels.py +3 -1
  126. wagtail/admin/ui/tables/__init__.py +13 -1
  127. wagtail/admin/ui/tables/pages.py +17 -6
  128. wagtail/admin/urls/__init__.py +8 -3
  129. wagtail/admin/urls/pages.py +5 -0
  130. wagtail/admin/urls/workflows.py +10 -0
  131. wagtail/admin/views/chooser.py +20 -24
  132. wagtail/admin/views/collections.py +17 -1
  133. wagtail/admin/views/generic/base.py +31 -4
  134. wagtail/admin/views/generic/history.py +220 -51
  135. wagtail/admin/views/generic/mixins.py +7 -4
  136. wagtail/admin/views/generic/models.py +54 -38
  137. wagtail/admin/views/generic/multiple_upload.py +17 -8
  138. wagtail/admin/views/generic/usage.py +17 -11
  139. wagtail/admin/views/home.py +15 -12
  140. wagtail/admin/views/mixins.py +30 -0
  141. wagtail/admin/views/pages/choose_parent.py +73 -0
  142. wagtail/admin/views/pages/history.py +54 -66
  143. wagtail/admin/views/pages/listing.py +187 -106
  144. wagtail/admin/views/pages/usage.py +6 -1
  145. wagtail/admin/views/pages/utils.py +70 -1
  146. wagtail/admin/views/workflows.py +150 -21
  147. wagtail/admin/viewsets/model.py +2 -2
  148. wagtail/admin/viewsets/pages.py +77 -0
  149. wagtail/admin/wagtail_hooks.py +40 -2
  150. wagtail/admin/widgets/button.py +10 -9
  151. wagtail/api/v2/filters.py +1 -1
  152. wagtail/api/v2/tests/test_pages.py +1 -1
  153. wagtail/blocks/base.py +18 -9
  154. wagtail/blocks/field_block.py +9 -7
  155. wagtail/blocks/list_block.py +16 -6
  156. wagtail/blocks/static_block.py +3 -0
  157. wagtail/blocks/stream_block.py +58 -23
  158. wagtail/blocks/struct_block.py +15 -9
  159. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +39 -47
  160. wagtail/contrib/forms/models.py +5 -5
  161. wagtail/contrib/forms/templates/wagtailforms/list_submissions.html +44 -33
  162. wagtail/contrib/forms/templates/wagtailforms/submissions_index.html +2 -63
  163. wagtail/contrib/forms/tests/test_models.py +26 -0
  164. wagtail/contrib/forms/urls.py +6 -0
  165. wagtail/contrib/forms/views.py +52 -49
  166. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.mo +0 -0
  167. wagtail/contrib/redirects/locale/ca/LC_MESSAGES/django.po +3 -3
  168. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +34 -42
  169. wagtail/contrib/redirects/signal_handlers.py +1 -1
  170. wagtail/contrib/redirects/templates/wagtailredirects/index.html +1 -36
  171. wagtail/contrib/redirects/templates/wagtailredirects/index_results.html +18 -0
  172. wagtail/contrib/redirects/templates/wagtailredirects/redirect_target_cell.html +8 -0
  173. wagtail/contrib/redirects/tests/test_import_command.py +1 -1
  174. wagtail/contrib/redirects/tests/test_redirects.py +79 -8
  175. wagtail/contrib/redirects/urls.py +2 -1
  176. wagtail/contrib/redirects/views.py +85 -55
  177. wagtail/contrib/search_promotions/admin_urls.py +2 -1
  178. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +41 -64
  179. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index.html +1 -16
  180. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/index_results.html +11 -0
  181. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/list.html +0 -51
  182. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/results.html +3 -16
  183. wagtail/contrib/search_promotions/templates/wagtailsearchpromotions/search_promotion_column.html +15 -0
  184. wagtail/contrib/search_promotions/tests.py +122 -9
  185. wagtail/contrib/search_promotions/views.py +66 -65
  186. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +3 -3
  187. wagtail/contrib/settings/registry.py +10 -5
  188. wagtail/contrib/settings/tests/generic/test_admin.py +9 -0
  189. wagtail/contrib/settings/tests/site_specific/test_admin.py +10 -1
  190. wagtail/contrib/settings/tests/site_specific/test_model.py +3 -3
  191. wagtail/contrib/settings/tests/site_specific/test_templates.py +1 -1
  192. wagtail/contrib/settings/views.py +3 -1
  193. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +1 -1
  194. wagtail/contrib/simple_translation/tests/test_wagtail_hooks.py +2 -2
  195. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  196. wagtail/contrib/table_block/blocks.py +1 -1
  197. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  198. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  199. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +1 -1
  200. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  201. wagtail/coreutils.py +3 -2
  202. wagtail/documents/admin_urls.py +2 -2
  203. wagtail/documents/locale/en/LC_MESSAGES/django.po +22 -22
  204. wagtail/documents/migrations/0013_delete_uploadeddocument.py +16 -0
  205. wagtail/documents/models.py +1 -20
  206. wagtail/documents/rich_text/__init__.py +11 -7
  207. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  208. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  209. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  210. wagtail/documents/templates/wagtaildocs/documents/index.html +0 -16
  211. wagtail/documents/tests/test_admin_views.py +155 -23
  212. wagtail/documents/tests/test_collection_privacy.py +55 -1
  213. wagtail/documents/tests/test_rich_text.py +14 -0
  214. wagtail/documents/views/documents.py +25 -22
  215. wagtail/documents/views/multiple.py +6 -7
  216. wagtail/documents/views/serve.py +16 -1
  217. wagtail/documents/wagtail_hooks.py +20 -15
  218. wagtail/embeds/blocks.py +5 -0
  219. wagtail/embeds/locale/en/LC_MESSAGES/django.po +2 -2
  220. wagtail/embeds/rich_text/__init__.py +1 -1
  221. wagtail/embeds/tests/test_rich_text.py +14 -0
  222. wagtail/embeds/wagtail_hooks.py +4 -14
  223. wagtail/fields.py +3 -48
  224. wagtail/images/admin_urls.py +2 -2
  225. wagtail/images/check_files/wagtail.jpg +0 -0
  226. wagtail/images/check_files/wagtail.png +0 -0
  227. wagtail/images/fields.py +2 -0
  228. wagtail/images/image_operations.py +1 -1
  229. wagtail/images/locale/en/LC_MESSAGES/django.po +33 -45
  230. wagtail/images/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  231. wagtail/images/locale/pt_PT/LC_MESSAGES/django.po +4 -0
  232. wagtail/images/migrations/0026_delete_uploadedimage.py +16 -0
  233. wagtail/images/models.py +49 -43
  234. wagtail/images/rich_text/__init__.py +18 -8
  235. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  236. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  237. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  238. wagtail/images/templates/wagtailimages/images/image_listing_header.html +6 -0
  239. wagtail/images/templates/wagtailimages/images/index.html +11 -51
  240. wagtail/images/tests/test_admin_views.py +119 -62
  241. wagtail/images/tests/test_image_operations.py +10 -0
  242. wagtail/images/tests/test_models.py +35 -33
  243. wagtail/images/tests/test_rich_text.py +14 -0
  244. wagtail/images/tests/utils.py +1 -1
  245. wagtail/images/views/images.py +35 -64
  246. wagtail/images/views/multiple.py +6 -7
  247. wagtail/images/wagtail_hooks.py +4 -14
  248. wagtail/locale/en/LC_MESSAGES/django.po +150 -136
  249. wagtail/locales/locale/en/LC_MESSAGES/django.po +1 -1
  250. wagtail/locales/tests.py +18 -3
  251. wagtail/locales/views.py +0 -1
  252. wagtail/management/commands/rebuild_references_index.py +3 -1
  253. wagtail/migrations/0092_alter_collectionviewrestriction_password_and_more.py +33 -0
  254. wagtail/migrations/0093_uploadedfile.py +53 -0
  255. wagtail/models/__init__.py +147 -32
  256. wagtail/models/i18n.py +1 -1
  257. wagtail/models/{collections.py → media.py} +33 -2
  258. wagtail/models/reference_index.py +1 -1
  259. wagtail/models/view_restrictions.py +10 -3
  260. wagtail/project_template/project_name/settings/base.py +6 -0
  261. wagtail/project_template/requirements.txt +1 -1
  262. wagtail/rich_text/__init__.py +25 -8
  263. wagtail/rich_text/pages.py +19 -8
  264. wagtail/rich_text/rewriters.py +140 -68
  265. wagtail/search/backends/database/mysql/mysql.py +3 -3
  266. wagtail/search/backends/database/postgres/postgres.py +3 -3
  267. wagtail/search/backends/database/sqlite/sqlite.py +2 -2
  268. wagtail/search/backends/elasticsearch7.py +4 -0
  269. wagtail/search/locale/en/LC_MESSAGES/django.po +3 -3
  270. wagtail/search/tests/test_postgres_backend.py +50 -0
  271. wagtail/sites/locale/en/LC_MESSAGES/django.po +8 -8
  272. wagtail/sites/tests.py +35 -9
  273. wagtail/sites/views.py +3 -1
  274. wagtail/snippets/locale/de/LC_MESSAGES/django.mo +0 -0
  275. wagtail/snippets/locale/de/LC_MESSAGES/django.po +5 -6
  276. wagtail/snippets/locale/en/LC_MESSAGES/django.po +16 -56
  277. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  278. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  279. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/publish.html +3 -1
  280. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/save.html +3 -1
  281. wagtail/snippets/templates/wagtailsnippets/snippets/create.html +1 -1
  282. wagtail/snippets/templates/wagtailsnippets/snippets/edit.html +1 -1
  283. wagtail/snippets/tests/test_preview.py +13 -2
  284. wagtail/snippets/tests/test_snippets.py +41 -16
  285. wagtail/snippets/tests/test_viewset.py +63 -18
  286. wagtail/snippets/tests/test_workflows.py +12 -0
  287. wagtail/snippets/views/snippets.py +1 -40
  288. wagtail/templatetags/wagtailcore_tags.py +1 -1
  289. wagtail/test/demosite/models.py +1 -1
  290. wagtail/test/middleware.py +14 -1
  291. wagtail/test/testapp/fixtures/test.json +20 -0
  292. wagtail/test/testapp/migrations/0001_squashed_0073_revisablechildmodel_secret_text.py +8 -8
  293. wagtail/test/testapp/migrations/0023_snippetchoosermodel_full_featured.py +1 -0
  294. wagtail/test/testapp/migrations/0034_custompermissionmodel.py +44 -0
  295. wagtail/test/testapp/migrations/0035_modelwithcustommanager.py +30 -0
  296. wagtail/test/testapp/migrations/0036_complexdefaultstreampage.py +28 -0
  297. wagtail/test/testapp/models.py +79 -2
  298. wagtail/test/testapp/templates/tests/custom_docs_password_required.html +10 -0
  299. wagtail/test/testapp/templates/tests/custom_page_password_required.html +10 -0
  300. wagtail/test/testapp/views.py +24 -2
  301. wagtail/test/testapp/wagtail_hooks.py +19 -0
  302. wagtail/test/utils/wagtail_tests.py +2 -2
  303. wagtail/tests/test_blocks.py +262 -1
  304. wagtail/tests/test_migrations.py +1 -1
  305. wagtail/tests/test_page_model.py +77 -0
  306. wagtail/tests/test_page_privacy.py +18 -1
  307. wagtail/tests/test_rich_text.py +95 -5
  308. wagtail/tests/test_streamfield.py +43 -0
  309. wagtail/tests/test_utils.py +8 -2
  310. wagtail/tests/test_views.py +52 -1
  311. wagtail/tests/test_whitelist.py +7 -7
  312. wagtail/users/forms.py +3 -1
  313. wagtail/users/locale/en/LC_MESSAGES/django.po +124 -96
  314. wagtail/users/migrations/0013_userprofile_density.py +23 -0
  315. wagtail/users/models.py +14 -3
  316. wagtail/users/templates/wagtailusers/groups/create.html +1 -7
  317. wagtail/users/templates/wagtailusers/groups/edit.html +1 -13
  318. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +46 -2
  319. wagtail/users/templates/wagtailusers/groups/includes/group_form_js.html +0 -2
  320. wagtail/users/templates/wagtailusers/users/create.html +1 -9
  321. wagtail/users/templates/wagtailusers/users/edit.html +1 -9
  322. wagtail/users/templates/wagtailusers/users/index.html +2 -5
  323. wagtail/users/templates/wagtailusers/users/index_results.html +3 -13
  324. wagtail/users/templates/wagtailusers/users/user_cell.html +9 -0
  325. wagtail/users/templatetags/wagtailusers_tags.py +107 -20
  326. wagtail/users/tests/test_admin_views.py +669 -90
  327. wagtail/users/views/groups.py +58 -61
  328. wagtail/users/views/users.py +211 -92
  329. wagtail/users/wagtail_hooks.py +6 -38
  330. wagtail/users/widgets.py +3 -5
  331. wagtail/utils/text.py +1 -1
  332. wagtail/views.py +5 -9
  333. wagtail/whitelist.py +1 -1
  334. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/METADATA +4 -5
  335. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/RECORD +339 -320
  336. wagtail/admin/static/wagtailadmin/js/page-editor.js +0 -1
  337. wagtail/admin/static/wagtailadmin/js/vendor/mousetrap.min.js +0 -1
  338. wagtail/admin/static/wagtailadmin/js/vendor/urlify.js +0 -1
  339. wagtail/admin/static/wagtailadmin/js/vendor/xregexp.min.js +0 -1
  340. wagtail/admin/templates/wagtailadmin/collections/index.html +0 -34
  341. wagtail/admin/templates/wagtailadmin/pages/revisions/_actions.html +0 -22
  342. wagtail/admin/templates/wagtailadmin/shared/page_breadcrumbs.html +0 -55
  343. wagtail/admin/tests/pages/test_dashboard.py +0 -172
  344. wagtail/contrib/redirects/templates/wagtailredirects/results.html +0 -23
  345. wagtail/documents/templates/wagtaildocs/documents/list.html +0 -2
  346. wagtail/search/tests/test_postgres_stemming.py +0 -40
  347. wagtail/sites/templates/wagtailsites/create.html +0 -6
  348. wagtail/sites/templates/wagtailsites/edit.html +0 -6
  349. wagtail/snippets/templates/wagtailsnippets/snippets/revisions/_actions.html +0 -36
  350. wagtail/users/templates/wagtailusers/users/list.html +0 -62
  351. wagtail/users/urls/users.py +0 -12
  352. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/LICENSE +0 -0
  353. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/WHEEL +0 -0
  354. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/entry_points.txt +0 -0
  355. {wagtail-6.0.2.dist-info → wagtail-6.1rc1.dist-info}/top_level.txt +0 -0
@@ -88,7 +88,7 @@ msgid "Wagtail snippets"
88
88
  msgstr "Wagtail Schnipsel"
89
89
 
90
90
  msgid "Delete selected snippets"
91
- msgstr "Ausgewählte Schnipsel löschen"
91
+ msgstr "Ausgewählte Elemente löschen"
92
92
 
93
93
  #, python-format
94
94
  msgid "%(model_name)s '%(object)s' deleted."
@@ -116,8 +116,7 @@ msgstr[1] "%(usage_count)s mal benutzt"
116
116
  #, python-format
117
117
  msgid "Are you sure you want to delete this %(snippet_type_name)s?"
118
118
  msgstr ""
119
- "Sind Sie sicher, dass Sie das „%(snippet_type_name)s Schnipsel löschen "
120
- "wollen?"
119
+ "Sind Sie sicher, dass Sie das „%(snippet_type_name)s“-Objekt löschen wollen?"
121
120
 
122
121
  #, python-format
123
122
  msgid "Are you sure you want to delete %(count)s %(snippet_type_name)s?"
@@ -144,7 +143,7 @@ msgstr "Nein, nicht löschen"
144
143
  #, python-format
145
144
  msgid "Sorry, no snippets match \"<em>%(search_query)s</em>\""
146
145
  msgstr ""
147
- "Es gibt leider keine Schnipsel zum Suchbegriff \"<em>%(search_query)s</em>\""
146
+ "Es gibt leider keine Objekte zum Suchbegriff \"<em>%(search_query)s</em>\""
148
147
 
149
148
  #, python-format
150
149
  msgid ""
@@ -152,7 +151,7 @@ msgid ""
152
151
  "href=\"%(wagtailsnippets_create_snippet_url)s\" target=\"_blank\" "
153
152
  "rel=\"noreferrer\">create one now</a>?"
154
153
  msgstr ""
155
- "Sie haben keine „%(snippet_type_name)s“-Schnipsel erstellt. Warum nicht <a "
154
+ "Sie haben keine „%(snippet_type_name)s“-Objekte erstellt. Warum nicht <a "
156
155
  "href=\"%(wagtailsnippets_create_snippet_url)s\" target=\"_blank\" "
157
156
  "rel=\"noreferrer\">ein neues erstellen</a>?"
158
157
 
@@ -178,7 +177,7 @@ msgid "Actions"
178
177
  msgstr "Aktionen"
179
178
 
180
179
  msgid "Select all snippets in listing"
181
- msgstr "Alle Schnipsel in der Aufzählung auswählen"
180
+ msgstr "Alle Elemente in der Aufzählung auswählen"
182
181
 
183
182
  msgid "Live version"
184
183
  msgstr "Live-Version"
@@ -8,7 +8,7 @@ msgid ""
8
8
  msgstr ""
9
9
  "Project-Id-Version: PACKAGE VERSION\n"
10
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2024-01-24 13:51+0000\n"
11
+ "POT-Creation-Date: 2024-04-18 17:28+0100\n"
12
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -19,7 +19,7 @@ msgstr ""
19
19
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
20
20
 
21
21
  #: action_menu.py:70
22
- #: templates/wagtailsnippets/snippets/action_menu/publish.html:13
22
+ #: templates/wagtailsnippets/snippets/action_menu/publish.html:15
23
23
  msgid "Publish"
24
24
  msgstr ""
25
25
 
@@ -54,7 +54,7 @@ msgid "Delete"
54
54
  msgstr ""
55
55
 
56
56
  #: action_menu.py:239
57
- #: templates/wagtailsnippets/snippets/action_menu/save.html:25
57
+ #: templates/wagtailsnippets/snippets/action_menu/save.html:27
58
58
  msgid "Save"
59
59
  msgstr ""
60
60
 
@@ -145,27 +145,27 @@ msgid ""
145
145
  "rel=\"noreferrer\">create one now</a>?"
146
146
  msgstr ""
147
147
 
148
- #: templates/wagtailsnippets/snippets/action_menu/publish.html:9
148
+ #: templates/wagtailsnippets/snippets/action_menu/publish.html:11
149
149
  msgid "Publishing…"
150
150
  msgstr ""
151
151
 
152
- #: templates/wagtailsnippets/snippets/action_menu/publish.html:13
152
+ #: templates/wagtailsnippets/snippets/action_menu/publish.html:15
153
153
  msgid "Publish this version"
154
154
  msgstr ""
155
155
 
156
- #: templates/wagtailsnippets/snippets/action_menu/save.html:7
156
+ #: templates/wagtailsnippets/snippets/action_menu/save.html:9
157
157
  msgid "Saving…"
158
158
  msgstr ""
159
159
 
160
- #: templates/wagtailsnippets/snippets/action_menu/save.html:18
160
+ #: templates/wagtailsnippets/snippets/action_menu/save.html:20
161
161
  msgid "Replace current draft"
162
162
  msgstr ""
163
163
 
164
- #: templates/wagtailsnippets/snippets/action_menu/save.html:20
164
+ #: templates/wagtailsnippets/snippets/action_menu/save.html:22
165
165
  msgid "Replace current revision"
166
166
  msgstr ""
167
167
 
168
- #: templates/wagtailsnippets/snippets/action_menu/save.html:23
168
+ #: templates/wagtailsnippets/snippets/action_menu/save.html:25
169
169
  msgid "Save draft"
170
170
  msgstr ""
171
171
 
@@ -178,79 +178,39 @@ msgstr ""
178
178
  msgid "Select all snippets in listing"
179
179
  msgstr ""
180
180
 
181
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:9
182
- msgid "Live version"
183
- msgstr ""
184
-
185
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:10
186
- msgid "Current draft"
187
- msgstr ""
188
-
189
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:15
190
- msgid "Preview"
191
- msgstr ""
192
-
193
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:18
194
- msgid "Edit"
195
- msgstr ""
196
-
197
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:20
198
- msgid "Review this version"
199
- msgstr ""
200
-
201
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:23
202
- msgid "Compare with previous version"
203
- msgstr ""
204
-
205
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:26
206
- msgid "Compare with current version"
207
- msgstr ""
208
-
209
- #: templates/wagtailsnippets/snippets/revisions/_actions.html:29
210
- msgid "Cancel scheduled publish"
211
- msgstr ""
212
-
213
181
  #: views/chooser.py:21
214
182
  msgid "Choose"
215
183
  msgstr ""
216
184
 
217
- #: views/snippets.py:79 views/snippets.py:106 views/snippets.py:952
185
+ #: views/snippets.py:77 views/snippets.py:104 views/snippets.py:913
218
186
  #: wagtail_hooks.py:44
219
187
  msgid "Snippets"
220
188
  msgstr ""
221
189
 
222
- #: views/snippets.py:119
190
+ #: views/snippets.py:117
223
191
  msgid "Name"
224
192
  msgstr ""
225
193
 
226
- #: views/snippets.py:125
194
+ #: views/snippets.py:123
227
195
  msgid "Instances"
228
196
  msgstr ""
229
197
 
230
- #: views/snippets.py:216
198
+ #: views/snippets.py:214
231
199
  #, python-format
232
200
  msgid "More options for '%(title)s'"
233
201
  msgstr ""
234
202
 
235
- #: views/snippets.py:400
236
- msgid "Action"
237
- msgstr ""
238
-
239
- #: views/snippets.py:403
240
- msgid "Date"
241
- msgstr ""
242
-
243
- #: views/snippets.py:428
203
+ #: views/snippets.py:389
244
204
  #, python-format
245
205
  msgid "Edit this %(model_name)s"
246
206
  msgstr ""
247
207
 
248
- #: views/snippets.py:434
208
+ #: views/snippets.py:395
249
209
  #, python-format
250
210
  msgid "%(model_name)s history"
251
211
  msgstr ""
252
212
 
253
- #: views/snippets.py:951
213
+ #: views/snippets.py:912
254
214
  msgid "Home"
255
215
  msgstr ""
256
216
 
@@ -1 +1 @@
1
- (()=>{"use strict";var e,r={1981:(e,r,t)=>{var o=t(6024),a=t(211);class n extends o.sf{getURLParams(e){const r=super.getURLParams(e);return wagtailConfig.ACTIVE_CONTENT_LOCALE&&(r.locale=wagtailConfig.ACTIVE_CONTENT_LOCALE),r}}class i extends a.I{titleStateKey="string";chooserModalClass=n}class l extends a.G{widgetClass=i;chooserModalClass=n}window.telepath.register("wagtail.snippets.widgets.SnippetChooser",l)},5311:e=>{e.exports=jQuery}},t={};function o(e){var a=t[e];if(void 0!==a)return a.exports;var n=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(n.exports,n,n.exports,o),n.loaded=!0,n.exports}o.m=r,e=[],o.O=(r,t,a,n)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){for(var[t,a,n]=e[u],l=!0,s=0;s<t.length;s++)(!1&n||i>=n)&&Object.keys(o.O).every((e=>o.O[e](t[s])))?t.splice(s--,1):(l=!1,n<i&&(i=n));if(l){e.splice(u--,1);var d=a();void 0!==d&&(r=d)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,a,n]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.j=383,(()=>{var e={383:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var a,n,[i,l,s]=t,d=0;if(i.some((r=>0!==e[r]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(s)var u=s(o)}for(r&&r(t);d<i.length;d++)n=i[d],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(u)},t=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var a=o.O(void 0,[751],(()=>o(1981)));a=o.O(a)})();
1
+ (()=>{"use strict";var e,r={8039:(e,r,t)=>{var o=t(2614),a=t(9465);class n extends o.ZZ{getURLParams(e){const r=super.getURLParams(e);return wagtailConfig.ACTIVE_CONTENT_LOCALE&&(r.locale=wagtailConfig.ACTIVE_CONTENT_LOCALE),r}}class i extends a.y{titleStateKey="string";chooserModalClass=n}class l extends a._{widgetClass=i;chooserModalClass=n}window.telepath.register("wagtail.snippets.widgets.SnippetChooser",l)},1669:e=>{e.exports=jQuery}},t={};function o(e){var a=t[e];if(void 0!==a)return a.exports;var n=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(n.exports,n,n.exports,o),n.loaded=!0,n.exports}o.m=r,e=[],o.O=(r,t,a,n)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){for(var[t,a,n]=e[u],l=!0,s=0;s<t.length;s++)(!1&n||i>=n)&&Object.keys(o.O).every((e=>o.O[e](t[s])))?t.splice(s--,1):(l=!1,n<i&&(i=n));if(l){e.splice(u--,1);var d=a();void 0!==d&&(r=d)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,a,n]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.j=474,(()=>{var e={474:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var a,n,[i,l,s]=t,d=0;if(i.some((r=>0!==e[r]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(s)var u=s(o)}for(r&&r(t);d<i.length;d++)n=i[d],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(u)},t=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var a=o.O(void 0,[321],(()=>o(8039)));a=o.O(a)})();
@@ -1 +1 @@
1
- (()=>{"use strict";var e,r={1183:(e,r,t)=>{var o=t(6024),a=t(211);class n extends o.sf{getURLParams(e){const r=super.getURLParams(e);return wagtailConfig.ACTIVE_CONTENT_LOCALE&&(r.locale=wagtailConfig.ACTIVE_CONTENT_LOCALE),r}}class i extends a.I{titleStateKey="string";chooserModalClass=n}window.SnippetChooser=i},5311:e=>{e.exports=jQuery}},t={};function o(e){var a=t[e];if(void 0!==a)return a.exports;var n=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(n.exports,n,n.exports,o),n.loaded=!0,n.exports}o.m=r,e=[],o.O=(r,t,a,n)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){for(var[t,a,n]=e[u],l=!0,s=0;s<t.length;s++)(!1&n||i>=n)&&Object.keys(o.O).every((e=>o.O[e](t[s])))?t.splice(s--,1):(l=!1,n<i&&(i=n));if(l){e.splice(u--,1);var d=a();void 0!==d&&(r=d)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,a,n]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.j=602,(()=>{var e={602:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var a,n,[i,l,s]=t,d=0;if(i.some((r=>0!==e[r]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(s)var u=s(o)}for(r&&r(t);d<i.length;d++)n=i[d],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(u)},t=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var a=o.O(void 0,[751],(()=>o(1183)));a=o.O(a)})();
1
+ (()=>{"use strict";var e,r={9987:(e,r,t)=>{var o=t(2614),a=t(9465);class n extends o.ZZ{getURLParams(e){const r=super.getURLParams(e);return wagtailConfig.ACTIVE_CONTENT_LOCALE&&(r.locale=wagtailConfig.ACTIVE_CONTENT_LOCALE),r}}class i extends a.y{titleStateKey="string";chooserModalClass=n}window.SnippetChooser=i},1669:e=>{e.exports=jQuery}},t={};function o(e){var a=t[e];if(void 0!==a)return a.exports;var n=t[e]={id:e,loaded:!1,exports:{}};return r[e].call(n.exports,n,n.exports,o),n.loaded=!0,n.exports}o.m=r,e=[],o.O=(r,t,a,n)=>{if(!t){var i=1/0;for(u=0;u<e.length;u++){for(var[t,a,n]=e[u],l=!0,s=0;s<t.length;s++)(!1&n||i>=n)&&Object.keys(o.O).every((e=>o.O[e](t[s])))?t.splice(s--,1):(l=!1,n<i&&(i=n));if(l){e.splice(u--,1);var d=a();void 0!==d&&(r=d)}}return r}n=n||0;for(var u=e.length;u>0&&e[u-1][2]>n;u--)e[u]=e[u-1];e[u]=[t,a,n]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.j=686,(()=>{var e={686:0};o.O.j=r=>0===e[r];var r=(r,t)=>{var a,n,[i,l,s]=t,d=0;if(i.some((r=>0!==e[r]))){for(a in l)o.o(l,a)&&(o.m[a]=l[a]);if(s)var u=s(o)}for(r&&r(t);d<i.length;d++)n=i[d],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(u)},t=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})();var a=o.O(void 0,[321],(()=>o(9987)));a=o.O(a)})();
@@ -4,8 +4,10 @@
4
4
  name="{{ name }}"
5
5
  value="{{ name }}"
6
6
  class="button action-save button-longrunning{% if is_revision %} warning{% endif %}"
7
- data-controller="w-progress"
7
+ data-controller="w-progress w-kbd"
8
8
  data-action="w-progress#activate"
9
+ data-w-kbd-key-value="mod+s"
10
+ data-w-kbd-scope-value="global"
9
11
  data-w-progress-active-value="{% trans 'Publishing…' %}"
10
12
  >
11
13
  {% icon name=icon_name classname="button-longrunning__icon" %}
@@ -2,8 +2,10 @@
2
2
  <button
3
3
  type="submit"
4
4
  class="button action-save button-longrunning{% if is_revision %} warning{% endif %}"
5
- data-controller="w-progress"
5
+ data-controller="w-progress w-kbd"
6
6
  data-action="w-progress#activate"
7
+ data-w-kbd-key-value="mod+s"
8
+ data-w-kbd-scope-value="global"
7
9
  data-w-progress-active-value="{% trans 'Saving…' %}"
8
10
  >
9
11
  {% if draftstate_enabled %}
@@ -7,7 +7,7 @@
7
7
  context variables from the view. As a result, we can't reuse the include from the generic
8
8
  template and have to copy it here without the `only` keyword.
9
9
  {% endcomment %}
10
- {% include 'wagtailadmin/shared/headers/slim_header.html' with breadcrumbs_items=breadcrumbs_items side_panels=side_panels history_url=history_url %}
10
+ {% include 'wagtailadmin/shared/headers/slim_header.html' with breadcrumbs_items=breadcrumbs_items side_panels=side_panels history_url=history_url buttons=header_buttons %}
11
11
  {% endblock %}
12
12
 
13
13
  {% block actions %}
@@ -8,7 +8,7 @@
8
8
  context variables from the view. As a result, we can't reuse the include from the generic
9
9
  template and have to copy it here without the `only` keyword.
10
10
  {% endcomment %}
11
- {% include 'wagtailadmin/shared/headers/slim_header.html' with breadcrumbs_items=breadcrumbs_items side_panels=side_panels history_url=history_url %}
11
+ {% include 'wagtailadmin/shared/headers/slim_header.html' with breadcrumbs_items=breadcrumbs_items side_panels=side_panels history_url=history_url buttons=header_buttons %}
12
12
  {% endblock %}
13
13
 
14
14
  {% block actions %}
@@ -297,10 +297,16 @@ class TestEnablePreview(WagtailTestUtils, TestCase):
297
297
  self.assertEqual(response.status_code, 200)
298
298
 
299
299
  # Should show the preview panel
300
- self.assertContains(response, 'data-side-panel-toggle="preview"')
301
300
  self.assertContains(response, 'data-side-panel="preview"')
302
301
  self.assertContains(response, 'data-action="%s"' % preview_url)
303
302
 
303
+ # Should have the preview side panel toggle button
304
+ soup = self.get_soup(response.content)
305
+ toggle_button = soup.find("button", {"data-side-panel-toggle": "preview"})
306
+ self.assertIsNotNone(toggle_button)
307
+ self.assertEqual("w-tooltip w-kbd", toggle_button["data-controller"])
308
+ self.assertEqual("mod+p", toggle_button["data-w-kbd-key-value"])
309
+
304
310
  # Should show the iframe
305
311
  self.assertContains(
306
312
  response,
@@ -471,9 +477,14 @@ class TestDisablePreviewWithEmptyModes(WagtailTestUtils, TestCase):
471
477
  preview_url = self.get_url(
472
478
  "revisions_view", args=(self.snippet.pk, latest_revision.id)
473
479
  )
474
- self.assertNotContains(response, "Preview")
480
+
475
481
  self.assertNotContains(response, preview_url)
476
482
 
483
+ soup = self.get_soup(response.content)
484
+
485
+ preview_link = soup.find("a", {"href": preview_url})
486
+ self.assertIsNone(preview_link)
487
+
477
488
 
478
489
  class TestDisablePreviewWithoutMixin(TestDisablePreviewWithEmptyModes):
479
490
  """
@@ -1095,7 +1095,7 @@ class TestCreateDraftStateSnippet(WagtailTestUtils, TestCase):
1095
1095
  # The publish button should have name="action-publish"
1096
1096
  self.assertContains(
1097
1097
  response,
1098
- '<button\n type="submit"\n name="action-publish"\n value="action-publish"\n class="button action-save button-longrunning"\n data-controller="w-progress"\n data-action="w-progress#activate"\n',
1098
+ '<button\n type="submit"\n name="action-publish"\n value="action-publish"\n class="button action-save button-longrunning"\n data-controller="w-progress w-kbd"\n data-action="w-progress#activate"\n data-w-kbd-key-value="mod+s"\n',
1099
1099
  )
1100
1100
  # The status side panel should be rendered so that the
1101
1101
  # publishing schedule can be configured
@@ -1598,13 +1598,13 @@ class TestSnippetEditView(BaseTestSnippetEditView):
1598
1598
  expected_url = "/admin/snippets/tests/advert/edit/%d/" % self.test_snippet.pk
1599
1599
  self.assertEqual(url_finder.get_edit_url(self.test_snippet), expected_url)
1600
1600
 
1601
- def test_non_existant_model(self):
1601
+ def test_non_existent_model(self):
1602
1602
  response = self.client.get(
1603
1603
  f"/admin/snippets/tests/foo/edit/{quote(self.test_snippet.pk)}/"
1604
1604
  )
1605
1605
  self.assertEqual(response.status_code, 404)
1606
1606
 
1607
- def test_nonexistant_id(self):
1607
+ def test_nonexistent_id(self):
1608
1608
  response = self.client.get(
1609
1609
  reverse("wagtailsnippets_tests_advert:edit", args=[999999])
1610
1610
  )
@@ -1906,7 +1906,7 @@ class TestEditDraftStateSnippet(BaseTestSnippetEditView):
1906
1906
  # The publish button should have name="action-publish"
1907
1907
  self.assertContains(
1908
1908
  response,
1909
- '<button\n type="submit"\n name="action-publish"\n value="action-publish"\n class="button action-save button-longrunning"\n data-controller="w-progress"\n data-action="w-progress#activate"\n',
1909
+ '<button\n type="submit"\n name="action-publish"\n value="action-publish"\n class="button action-save button-longrunning"\n data-controller="w-progress w-kbd"\n data-action="w-progress#activate"\n data-w-kbd-key-value="mod+s"\n',
1910
1910
  )
1911
1911
 
1912
1912
  # The status side panel should show "No publishing schedule set" info
@@ -2407,12 +2407,13 @@ class TestEditDraftStateSnippet(BaseTestSnippetEditView):
2407
2407
  )
2408
2408
  self.assertContains(response, "Unpublish")
2409
2409
 
2410
- # Should use the latest draft content for the title
2411
- self.assertContains(
2412
- response,
2413
- '<h2 class="w-header__title" id="header-title">Draft-enabled Bar, In Draft</h2>',
2414
- html=True,
2415
- )
2410
+ soup = self.get_soup(response.content)
2411
+ h2 = soup.select_one("#header-title")
2412
+ self.assertIsNotNone(h2)
2413
+ icon = h2.select_one("svg use")
2414
+ self.assertIsNotNone(icon)
2415
+ self.assertEqual(icon["href"], "#icon-snippet")
2416
+ self.assertEqual(h2.text.strip(), "Draft-enabled Bar, In Draft")
2416
2417
 
2417
2418
  # Should use the latest draft content for the form
2418
2419
  self.assertTagInHTML(
@@ -4157,7 +4158,7 @@ class TestSnippetHistory(WagtailTestUtils, TestCase):
4157
4158
  def test_simple(self):
4158
4159
  response = self.get(self.non_revisable_snippet)
4159
4160
  self.assertEqual(response.status_code, 200)
4160
- self.assertContains(response, '<td class="title">Created</td>', html=True)
4161
+ self.assertContains(response, "<td>Created</td>", html=True)
4161
4162
  self.assertContains(
4162
4163
  response,
4163
4164
  'data-w-tooltip-content-value="Sept. 30, 2021, 10:01 a.m."',
@@ -4189,7 +4190,7 @@ class TestSnippetHistory(WagtailTestUtils, TestCase):
4189
4190
  edit_url = self.get_url(self.non_revisable_snippet, "edit")
4190
4191
  self.assertNotContains(
4191
4192
  response,
4192
- f'<a href="{edit_url}" class="button button-small button-secondary">Edit</a>',
4193
+ f'<a href="{edit_url}">Edit</a>',
4193
4194
  )
4194
4195
 
4195
4196
  def test_should_show_actions_on_revisable_snippet(self):
@@ -4212,14 +4213,14 @@ class TestSnippetHistory(WagtailTestUtils, TestCase):
4212
4213
  # The latest revision should have an "Edit" action instead of "Review"
4213
4214
  self.assertContains(
4214
4215
  response,
4215
- f'<a href="{edit_url}" class="button button-small button-secondary">Edit</a>',
4216
+ f'<a href="{edit_url}">Edit</a>',
4216
4217
  count=1,
4217
4218
  )
4218
4219
 
4219
4220
  # Any other revision should have a "Review" action
4220
4221
  self.assertContains(
4221
4222
  response,
4222
- f'<a href="{revert_url}" class="button button-small button-secondary">Review this version</a>',
4223
+ f'<a href="{revert_url}">Review this version</a>',
4223
4224
  count=1,
4224
4225
  )
4225
4226
 
@@ -4261,6 +4262,24 @@ class TestSnippetHistory(WagtailTestUtils, TestCase):
4261
4262
  response = self.get(self.revisable_snippet)
4262
4263
  self.assertEqual(response.status_code, 200)
4263
4264
 
4265
+ def test_num_queries(self):
4266
+ snippet = self.revisable_snippet
4267
+
4268
+ # Warm up the cache
4269
+ self.get(snippet)
4270
+
4271
+ with self.assertNumQueries(14):
4272
+ self.get(snippet)
4273
+
4274
+ for i in range(20):
4275
+ revision = snippet.save_revision(user=self.user, log_action=True)
4276
+ if i % 5 == 0:
4277
+ revision.publish(user=self.user, log_action=True)
4278
+
4279
+ # Should have the same number of queries as before (no N+1 queries)
4280
+ with self.assertNumQueries(14):
4281
+ self.get(snippet)
4282
+
4264
4283
 
4265
4284
  class TestSnippetRevisions(WagtailTestUtils, TestCase):
4266
4285
  @property
@@ -4363,7 +4382,7 @@ class TestSnippetRevisions(WagtailTestUtils, TestCase):
4363
4382
  # The publish button should have name="action-publish"
4364
4383
  self.assertContains(
4365
4384
  response,
4366
- '<button\n type="submit"\n name="action-publish"\n value="action-publish"\n class="button action-save button-longrunning warning"\n data-controller="w-progress"\n data-action="w-progress#activate"\n',
4385
+ '<button\n type="submit"\n name="action-publish"\n value="action-publish"\n class="button action-save button-longrunning warning"\n data-controller="w-progress w-kbd"\n data-action="w-progress#activate"\n data-w-kbd-key-value="mod+s"\n',
4367
4386
  )
4368
4387
 
4369
4388
  # Should not show the Unpublish action menu item
@@ -4409,10 +4428,16 @@ class TestSnippetRevisions(WagtailTestUtils, TestCase):
4409
4428
 
4410
4429
  # Should show the preview panel
4411
4430
  preview_url = self.get_url("preview_on_edit")
4412
- self.assertContains(response, 'data-side-panel-toggle="preview"')
4413
4431
  self.assertContains(response, 'data-side-panel="preview"')
4414
4432
  self.assertContains(response, f'data-action="{preview_url}"')
4415
4433
 
4434
+ # Should have the preview side panel toggle button
4435
+ soup = self.get_soup(response.content)
4436
+ toggle_button = soup.find("button", {"data-side-panel-toggle": "preview"})
4437
+ self.assertIsNotNone(toggle_button)
4438
+ self.assertEqual("w-tooltip w-kbd", toggle_button["data-controller"])
4439
+ self.assertEqual("mod+p", toggle_button["data-w-kbd-key-value"])
4440
+
4416
4441
  def test_replace_revision(self):
4417
4442
  get_response = self.get()
4418
4443
  text_from_revision = get_response.context["form"].initial["text"]
@@ -42,6 +42,7 @@ from wagtail.test.testapp.models import (
42
42
  )
43
43
  from wagtail.test.utils import WagtailTestUtils
44
44
  from wagtail.test.utils.template_tests import AdminTemplateTestUtils
45
+ from wagtail.utils.timestamps import render_timestamp
45
46
 
46
47
 
47
48
  class TestIncorrectRegistration(SimpleTestCase):
@@ -69,8 +70,6 @@ class BaseSnippetViewSetTests(WagtailTestUtils, TestCase):
69
70
 
70
71
 
71
72
  class TestCustomIcon(BaseSnippetViewSetTests):
72
- # TODO: decide what to do with this test, since the new designs after
73
- # Universal Listings and unified breadcrumbs/header don't have icons
74
73
  model = FullFeaturedSnippet
75
74
 
76
75
  def setUp(self):
@@ -84,26 +83,28 @@ class TestCustomIcon(BaseSnippetViewSetTests):
84
83
  def test_get_views(self):
85
84
  pk = quote(self.object.pk)
86
85
  views = [
87
- # TODO: Some of these views have been migrated to use the slim_header
88
- # only, so there is no header_icon anymore.
89
- # ("list", []),
90
- # ("add", []),
91
- # ("edit", [pk]),
92
- # ("delete", [pk]),
93
- # ("usage", [pk]),
94
- ("unpublish", [pk]),
95
- ("workflow_history", [pk]),
96
- # ("revisions_revert", [pk, self.revision_1.id]),
97
- ("revisions_compare", [pk, self.revision_1.id, self.revision_2.id]),
98
- ("revisions_unschedule", [pk, self.revision_2.id]),
86
+ ("list", [], "headers/slim_header.html"),
87
+ ("add", [], "headers/slim_header.html"),
88
+ ("edit", [pk], "headers/slim_header.html"),
89
+ ("delete", [pk], "header.html"),
90
+ ("usage", [pk], "headers/slim_header.html"),
91
+ ("unpublish", [pk], "header.html"),
92
+ ("workflow_history", [pk], "header.html"),
93
+ ("revisions_revert", [pk, self.revision_1.id], "headers/slim_header.html"),
94
+ (
95
+ "revisions_compare",
96
+ [pk, self.revision_1.id, self.revision_2.id],
97
+ "header.html",
98
+ ),
99
+ ("revisions_unschedule", [pk, self.revision_2.id], "header.html"),
99
100
  ]
100
- for view_name, args in views:
101
+ for view_name, args, header in views:
101
102
  with self.subTest(view_name=view_name):
102
103
  response = self.client.get(self.get_url(view_name, args))
103
104
  self.assertEqual(response.status_code, 200)
104
105
  self.assertEqual(response.context["header_icon"], "cog")
105
106
  self.assertContains(response, "icon icon-cog", count=1)
106
- self.assertTemplateUsed(response, "wagtailadmin/shared/header.html")
107
+ self.assertTemplateUsed(response, f"wagtailadmin/shared/{header}")
107
108
 
108
109
  def test_get_history(self):
109
110
  response = self.client.get(self.get_url("history", [quote(self.object.pk)]))
@@ -112,6 +113,10 @@ class TestCustomIcon(BaseSnippetViewSetTests):
112
113
  response,
113
114
  "wagtailadmin/shared/headers/slim_header.html",
114
115
  )
116
+ # History view icon is not configurable for consistency with pages
117
+ self.assertEqual(response.context["header_icon"], "history")
118
+ self.assertContains(response, "icon icon-history")
119
+ self.assertNotContains(response, "icon icon-cog")
115
120
  self.assertTemplateNotUsed(response, "wagtailadmin/shared/header.html")
116
121
 
117
122
  def test_get_workflow_history_detail(self):
@@ -715,10 +720,12 @@ class TestListViewWithCustomColumns(BaseSnippetViewSetTests):
715
720
  # One from the country code column, another from the custom foo column
716
721
  self.assertContains(response, sort_country_code_url, count=2)
717
722
 
718
- html = response.content.decode()
723
+ soup = self.get_soup(response.content)
724
+
725
+ headings = soup.select("#listing-results table th")
719
726
 
720
727
  # The bulk actions column plus 6 columns defined in FullFeaturedSnippetViewSet
721
- self.assertTagInHTML("<th>", html, count=7, allow_extra_attrs=True)
728
+ self.assertEqual(len(headings), 7)
722
729
 
723
730
  def test_falsy_value(self):
724
731
  # https://github.com/wagtail/wagtail/issues/10765
@@ -769,6 +776,44 @@ class TestListViewWithCustomColumns(BaseSnippetViewSetTests):
769
776
  )
770
777
 
771
778
 
779
+ class TestRelatedFieldListDisplay(BaseSnippetViewSetTests):
780
+ model = SnippetChooserModel
781
+
782
+ def setUp(self):
783
+ super().setUp()
784
+ url = "https://example.com/free_examples"
785
+ self.advert = Advert.objects.create(url=url, text="Free Examples")
786
+ self.ffs = FullFeaturedSnippet.objects.create(text="royale with cheese")
787
+
788
+ def test_empty_foreignkey(self):
789
+ self.no_ffs_chooser = self.model.objects.create(advert=self.advert)
790
+ response = self.client.get(self.get_url("list"))
791
+ self.assertEqual(response.status_code, 200)
792
+ self.assertContains(response, "Chosen snippet text")
793
+ self.assertContains(response, "<td></td>", html=True)
794
+
795
+ def test_single_level_relation(self):
796
+ self.scm = self.model.objects.create(advert=self.advert, full_featured=self.ffs)
797
+ response = self.client.get(self.get_url("list"))
798
+ self.assertEqual(response.status_code, 200)
799
+ soup = self.get_soup(response.content)
800
+ headers = [
801
+ header.get_text(strip=True)
802
+ for header in soup.select("#listing-results table th")
803
+ ]
804
+ self.assertIn("Chosen snippet text", headers)
805
+ self.assertContains(response, "<td>royale with cheese</td>", html=True)
806
+
807
+ def test_multi_level_relation(self):
808
+ self.scm = self.model.objects.create(advert=self.advert, full_featured=self.ffs)
809
+ dummy_revision = self.ffs.save_revision()
810
+ timestamp = render_timestamp(dummy_revision.created_at)
811
+ response = self.client.get(self.get_url("list"))
812
+ self.assertEqual(response.status_code, 200)
813
+ self.assertContains(response, "Latest revision created at")
814
+ self.assertContains(response, f"<td>{timestamp}</td>", html=True)
815
+
816
+
772
817
  class TestListExport(BaseSnippetViewSetTests):
773
818
  model = FullFeaturedSnippet
774
819
 
@@ -268,6 +268,18 @@ class TestWorkflowHistory(BaseWorkflowsTestCase):
268
268
 
269
269
  self.assertRedirects(response, reverse("wagtailadmin_home"))
270
270
 
271
+ def test_get_history_renders_comment(self):
272
+ self.workflow_state.current_task_state.reject(comment="Can be better")
273
+ # Ensure the comment in the log entry is rendered in the History view.
274
+ # This is the main History view and not the Workflow History view, but
275
+ # we test it here so we can reuse the workflow setup.
276
+ response = self.client.get(self.get_url("history", (quote(self.object.pk),)))
277
+ self.assertContains(
278
+ response,
279
+ "<div>Comment: <em>Can be better</em></div>",
280
+ html=True,
281
+ )
282
+
271
283
 
272
284
  class TestConfirmWorkflowCancellation(BaseWorkflowsTestCase):
273
285
  def setUp(self):
@@ -20,10 +20,8 @@ from wagtail.admin.ui.side_panels import ChecksSidePanel, PreviewSidePanel
20
20
  from wagtail.admin.ui.tables import (
21
21
  BulkActionsCheckboxColumn,
22
22
  Column,
23
- DateColumn,
24
23
  LiveStatusTagColumn,
25
24
  TitleColumn,
26
- UserColumn,
27
25
  )
28
26
  from wagtail.admin.views import generic
29
27
  from wagtail.admin.views.generic import history, lock, workflow
@@ -90,7 +88,7 @@ class ModelIndexView(generic.BaseListingView):
90
88
  return [
91
89
  {
92
90
  "name": capfirst(model._meta.verbose_name_plural),
93
- "count": model.objects.all().count(),
91
+ "count": model._default_manager.all().count(),
94
92
  "model": model,
95
93
  }
96
94
  for model in get_snippet_models()
@@ -363,45 +361,8 @@ class UsageView(generic.UsageView):
363
361
  view_name = "usage"
364
362
 
365
363
 
366
- class ActionColumn(Column):
367
- cell_template_name = "wagtailsnippets/snippets/revisions/_actions.html"
368
-
369
- def __init__(self, *args, object=None, view=None, **kwargs):
370
- super().__init__(*args, **kwargs)
371
- self.object = object
372
- self.view = view
373
-
374
- def get_cell_context_data(self, instance, parent_context):
375
- context = super().get_cell_context_data(instance, parent_context)
376
- context["revision_enabled"] = isinstance(self.object, RevisionMixin)
377
- context["draftstate_enabled"] = isinstance(self.object, DraftStateMixin)
378
- context["preview_enabled"] = isinstance(self.object, PreviewableMixin)
379
- context["can_publish"] = self.view.user_has_permission("publish")
380
- context["object"] = self.object
381
- context["view"] = self.view
382
- return context
383
-
384
-
385
364
  class HistoryView(history.HistoryView):
386
365
  view_name = "history"
387
- revisions_view_url_name = None
388
- revisions_revert_url_name = None
389
- revisions_compare_url_name = None
390
- revisions_unschedule_url_name = None
391
-
392
- @cached_property
393
- def columns(self):
394
- return [
395
- ActionColumn(
396
- "message",
397
- object=self.object,
398
- view=self,
399
- classname="title",
400
- label=_("Action"),
401
- ),
402
- UserColumn("user", blank_display_name="system"),
403
- DateColumn("timestamp", label=_("Date")),
404
- ]
405
366
 
406
367
 
407
368
  class InspectView(generic.InspectView):