wagtail 6.1.3__py3-none-any.whl → 6.2rc1__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 (257) hide show
  1. wagtail/__init__.py +1 -1
  2. wagtail/actions/copy_for_translation.py +15 -1
  3. wagtail/admin/checks.py +20 -30
  4. wagtail/admin/forms/pages.py +10 -0
  5. wagtail/admin/icons.py +43 -0
  6. wagtail/admin/locale/en/LC_MESSAGES/django.po +405 -295
  7. wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -3
  8. wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
  9. wagtail/admin/locale/sl/LC_MESSAGES/django.po +30 -0
  10. wagtail/admin/menu.py +2 -2
  11. wagtail/admin/migrations/0004_editingsession.py +57 -0
  12. wagtail/admin/migrations/0005_editingsession_is_editing.py +18 -0
  13. wagtail/admin/models.py +36 -3
  14. wagtail/admin/rich_text/editors/draftail/__init__.py +2 -20
  15. wagtail/admin/static/wagtailadmin/css/core.css +1 -1
  16. wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
  17. wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
  18. wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
  19. wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
  20. wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
  21. wagtail/admin/static/wagtailadmin/js/core.js +1 -1
  22. wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
  23. wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
  24. wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
  25. wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
  26. wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
  27. wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
  28. wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
  29. wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
  30. wagtail/admin/static/wagtailadmin/js/preview-panel.js +2 -1
  31. wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +11 -0
  32. wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
  33. wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
  34. wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
  35. wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
  36. wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
  37. wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
  38. wagtail/admin/static/wagtailadmin/js/userbar.js +2 -1
  39. wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +11 -0
  40. wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
  41. wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +0 -12
  42. wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
  43. wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
  44. wagtail/admin/templates/wagtailadmin/collection_privacy/ancestor_privacy.html +2 -6
  45. wagtail/admin/templates/wagtailadmin/generic/index_results.html +1 -17
  46. wagtail/admin/templates/wagtailadmin/generic/listing_results.html +20 -1
  47. wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +2 -11
  48. wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +2 -6
  49. wagtail/admin/templates/wagtailadmin/page_privacy/no_privacy.html +2 -0
  50. wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
  51. wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -1
  52. wagtail/admin/templates/wagtailadmin/reports/aging_pages_results.html +54 -0
  53. wagtail/admin/templates/wagtailadmin/reports/base_page_report.html +1 -17
  54. wagtail/admin/templates/wagtailadmin/reports/base_page_report_results.html +10 -0
  55. wagtail/admin/templates/wagtailadmin/reports/base_report.html +1 -40
  56. wagtail/admin/templates/wagtailadmin/reports/base_report_results.html +1 -0
  57. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +21 -27
  58. wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +48 -54
  59. wagtail/admin/templates/wagtailadmin/reports/{locked_pages.html → locked_pages_results.html} +3 -3
  60. wagtail/admin/templates/wagtailadmin/reports/page_types_usage_results.html +10 -0
  61. wagtail/admin/templates/wagtailadmin/reports/site_history_results.html +53 -0
  62. wagtail/admin/templates/wagtailadmin/reports/workflow_results.html +74 -0
  63. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +56 -0
  64. wagtail/admin/templates/wagtailadmin/shared/_workflow_init.html +8 -44
  65. wagtail/admin/templates/wagtailadmin/shared/avatar.html +11 -1
  66. wagtail/admin/templates/wagtailadmin/shared/dialog/dialog.html +5 -4
  67. wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown_button.html +2 -1
  68. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +132 -0
  69. wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +44 -0
  70. wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +7 -1
  71. wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +1 -1
  72. wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +32 -16
  73. wagtail/admin/templates/wagtailadmin/skeleton.html +1 -1
  74. wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +9 -11
  75. wagtail/admin/templatetags/wagtailadmin_tags.py +13 -2
  76. wagtail/admin/tests/formats/en/__init__.py +0 -0
  77. wagtail/admin/tests/formats/en/formats.py +1 -0
  78. wagtail/admin/tests/pages/test_create_page.py +47 -0
  79. wagtail/admin/tests/pages/test_edit_page.py +10 -8
  80. wagtail/admin/tests/pages/test_parent_page_chooser_view.py +45 -1
  81. wagtail/admin/tests/test_checks.py +53 -3
  82. wagtail/admin/tests/test_collections_views.py +62 -1
  83. wagtail/admin/tests/test_edit_handlers.py +37 -0
  84. wagtail/admin/tests/test_editing_sessions.py +1336 -0
  85. wagtail/admin/tests/test_icon_sprite.py +12 -21
  86. wagtail/admin/tests/test_page_chooser.py +309 -7
  87. wagtail/admin/tests/test_privacy.py +82 -0
  88. wagtail/admin/tests/test_reports_views.py +464 -70
  89. wagtail/admin/tests/test_userbar.py +93 -6
  90. wagtail/admin/tests/test_workflows.py +223 -33
  91. wagtail/admin/tests/viewsets/test_model_viewset.py +151 -2
  92. wagtail/admin/ui/editing_sessions.py +57 -0
  93. wagtail/admin/urls/__init__.py +9 -15
  94. wagtail/admin/urls/editing_sessions.py +17 -0
  95. wagtail/admin/urls/reports.py +33 -1
  96. wagtail/admin/userbar.py +77 -20
  97. wagtail/admin/views/chooser.py +49 -22
  98. wagtail/admin/views/collections.py +0 -11
  99. wagtail/admin/views/editing_sessions.py +193 -0
  100. wagtail/admin/views/generic/__init__.py +1 -0
  101. wagtail/admin/views/generic/history.py +9 -3
  102. wagtail/admin/views/generic/mixins.py +44 -3
  103. wagtail/admin/views/generic/models.py +46 -72
  104. wagtail/admin/views/generic/permissions.py +20 -10
  105. wagtail/admin/views/home.py +2 -31
  106. wagtail/admin/views/page_privacy.py +20 -5
  107. wagtail/admin/views/pages/choose_parent.py +62 -0
  108. wagtail/admin/views/pages/edit.py +28 -0
  109. wagtail/admin/views/reports/aging_pages.py +6 -10
  110. wagtail/admin/views/reports/audit_logging.py +13 -42
  111. wagtail/admin/views/reports/base.py +31 -4
  112. wagtail/admin/views/reports/locked_pages.py +5 -8
  113. wagtail/admin/views/reports/page_types_usage.py +6 -10
  114. wagtail/admin/views/reports/workflows.py +36 -12
  115. wagtail/admin/viewsets/base.py +8 -3
  116. wagtail/admin/viewsets/chooser.py +1 -1
  117. wagtail/admin/viewsets/model.py +26 -1
  118. wagtail/admin/wagtail_hooks.py +2 -1
  119. wagtail/api/v2/filters.py +6 -0
  120. wagtail/api/v2/tests/test_documents.py +1 -1
  121. wagtail/api/v2/tests/test_images.py +1 -1
  122. wagtail/api/v2/tests/test_pages.py +11 -1
  123. wagtail/api/v2/utils.py +2 -2
  124. wagtail/blocks/base.py +35 -12
  125. wagtail/blocks/definition_lookup.py +85 -0
  126. wagtail/blocks/list_block.py +12 -0
  127. wagtail/blocks/migrations/migrate_operation.py +2 -0
  128. wagtail/blocks/stream_block.py +19 -0
  129. wagtail/blocks/struct_block.py +19 -0
  130. wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
  131. wagtail/contrib/frontend_cache/backends/__init__.py +5 -0
  132. wagtail/contrib/frontend_cache/backends/azure.py +179 -0
  133. wagtail/contrib/frontend_cache/backends/base.py +28 -0
  134. wagtail/contrib/frontend_cache/backends/cloudflare.py +114 -0
  135. wagtail/contrib/frontend_cache/backends/cloudfront.py +99 -0
  136. wagtail/contrib/frontend_cache/backends/http.py +64 -0
  137. wagtail/contrib/frontend_cache/tests.py +59 -17
  138. wagtail/contrib/frontend_cache/utils.py +26 -8
  139. wagtail/contrib/redirects/filters.py +15 -1
  140. wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +37 -72
  141. wagtail/contrib/redirects/models.py +6 -5
  142. wagtail/contrib/redirects/templates/wagtailredirects/edit.html +1 -38
  143. wagtail/contrib/redirects/tests/test_redirects.py +141 -1
  144. wagtail/contrib/redirects/urls.py +1 -2
  145. wagtail/contrib/redirects/views.py +39 -80
  146. wagtail/contrib/routable_page/models.py +6 -4
  147. wagtail/contrib/routable_page/tests.py +11 -0
  148. wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +1 -1
  149. wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +4 -4
  150. wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +5 -1
  151. wagtail/contrib/simple_translation/models.py +2 -1
  152. wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
  153. wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
  154. wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
  155. wagtail/contrib/typed_table_block/blocks.py +19 -0
  156. wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
  157. wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
  158. wagtail/contrib/typed_table_block/tests.py +38 -0
  159. wagtail/coreutils.py +1 -1
  160. wagtail/documents/__init__.py +1 -1
  161. wagtail/documents/locale/en/LC_MESSAGES/django.po +8 -8
  162. wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
  163. wagtail/documents/locale/sl/LC_MESSAGES/django.po +20 -0
  164. wagtail/documents/models.py +5 -1
  165. wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
  166. wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
  167. wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
  168. wagtail/documents/tests/test_models.py +5 -1
  169. wagtail/embeds/apps.py +2 -0
  170. wagtail/embeds/embeds.py +12 -14
  171. wagtail/embeds/finders/__init__.py +2 -0
  172. wagtail/embeds/finders/facebook.py +17 -33
  173. wagtail/embeds/finders/instagram.py +19 -16
  174. wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
  175. wagtail/embeds/signal_handlers.py +13 -0
  176. wagtail/embeds/tests/test_embeds.py +7 -7
  177. wagtail/fields.py +58 -14
  178. wagtail/images/__init__.py +1 -1
  179. wagtail/images/locale/en/LC_MESSAGES/django.po +34 -34
  180. wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
  181. wagtail/images/locale/sl/LC_MESSAGES/django.po +20 -0
  182. wagtail/images/models.py +2 -0
  183. wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
  184. wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
  185. wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
  186. wagtail/images/templates/wagtailimages/images/edit.html +4 -4
  187. wagtail/images/tests/test_admin_views.py +26 -2
  188. wagtail/images/views/chooser.py +6 -1
  189. wagtail/locale/en/LC_MESSAGES/django.po +84 -80
  190. wagtail/locales/locale/en/LC_MESSAGES/django.po +2 -2
  191. wagtail/locales/tests.py +16 -0
  192. wagtail/locales/wagtail_hooks.py +0 -9
  193. wagtail/migrations/0094_alter_page_locale.py +19 -0
  194. wagtail/models/__init__.py +11 -5
  195. wagtail/models/i18n.py +6 -1
  196. wagtail/project_template/requirements.txt +1 -1
  197. wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
  198. wagtail/signals.py +4 -0
  199. wagtail/sites/locale/en/LC_MESSAGES/django.po +2 -2
  200. wagtail/sites/tests.py +15 -0
  201. wagtail/sites/wagtail_hooks.py +0 -9
  202. wagtail/snippets/locale/en/LC_MESSAGES/django.po +9 -9
  203. wagtail/snippets/permissions.py +5 -3
  204. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
  205. wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
  206. wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -1
  207. wagtail/snippets/tests/test_snippets.py +78 -12
  208. wagtail/snippets/tests/test_viewset.py +22 -0
  209. wagtail/snippets/views/snippets.py +19 -14
  210. wagtail/snippets/wagtail_hooks.py +2 -10
  211. wagtail/templatetags/wagtailcore_tags.py +3 -0
  212. wagtail/test/dummy_external_storage.py +1 -1
  213. wagtail/test/i18n/migrations/0003_alter_clusterabletestmodel_locale_and_more.py +40 -0
  214. wagtail/test/routablepage/models.py +4 -0
  215. wagtail/test/snippets/migrations/0012_alter_translatablesnippet_locale.py +20 -0
  216. wagtail/test/testapp/migrations/0038_sociallink.py +52 -0
  217. wagtail/test/testapp/migrations/0039_alter_eventcategory_locale_and_more.py +45 -0
  218. wagtail/test/testapp/models.py +24 -0
  219. wagtail/test/testapp/views.py +1 -0
  220. wagtail/test/testapp/wagtail_hooks.py +9 -0
  221. wagtail/test/urls_multilang.py +6 -1
  222. wagtail/test/urls_multilang_non_root.py +11 -0
  223. wagtail/tests/streamfield_migrations/test_migrations.py +53 -12
  224. wagtail/tests/test_audit_log.py +72 -2
  225. wagtail/tests/test_blocks.py +103 -0
  226. wagtail/tests/test_signals.py +49 -2
  227. wagtail/tests/test_streamfield.py +153 -0
  228. wagtail/tests/test_utils.py +14 -0
  229. wagtail/tests/tests.py +5 -0
  230. wagtail/users/apps.py +1 -0
  231. wagtail/users/forms.py +7 -0
  232. wagtail/users/locale/en/LC_MESSAGES/django.po +55 -50
  233. wagtail/users/models.py +1 -0
  234. wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +3 -2
  235. wagtail/users/templatetags/wagtailusers_tags.py +9 -0
  236. wagtail/users/tests/__init__.py +7 -1
  237. wagtail/users/tests/test_admin_views.py +117 -32
  238. wagtail/users/views/groups.py +4 -0
  239. wagtail/users/views/users.py +58 -14
  240. wagtail/users/wagtail_hooks.py +7 -123
  241. wagtail/utils/utils.py +1 -0
  242. wagtail/utils/version.py +5 -2
  243. {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/METADATA +3 -3
  244. {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/RECORD +248 -222
  245. wagtail/admin/templates/wagtailadmin/reports/aging_pages.html +0 -58
  246. wagtail/admin/templates/wagtailadmin/reports/page_types_usage.html +0 -18
  247. wagtail/admin/templates/wagtailadmin/reports/site_history.html +0 -57
  248. wagtail/admin/templates/wagtailadmin/reports/workflow.html +0 -81
  249. wagtail/admin/templates/wagtailadmin/reports/workflow_tasks.html +0 -63
  250. wagtail/contrib/frontend_cache/backends.py +0 -400
  251. wagtail/contrib/redirects/templates/wagtailredirects/list.html +0 -43
  252. wagtail/contrib/redirects/templates/wagtailredirects/reports/redirects_report.html +0 -14
  253. wagtail/contrib/redirects/tests/test_reports_view.py +0 -82
  254. {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/LICENSE +0 -0
  255. {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/WHEEL +0 -0
  256. {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/entry_points.txt +0 -0
  257. {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,74 @@
1
+ {% extends 'wagtailadmin/reports/base_report_results.html' %}
2
+ {% load i18n wagtailadmin_tags %}
3
+
4
+ {% block results %}
5
+ <table class="listing">
6
+ <thead>
7
+ <tr>
8
+ <th>
9
+ {% trans 'Workflow' %}
10
+ </th>
11
+ <th>
12
+ {% trans 'Page/Snippet' %}
13
+ </th>
14
+ <th>
15
+ {% trans 'Status' %}
16
+ </th>
17
+ <th>
18
+ {% trans 'Tasks' %}
19
+ </th>
20
+ <th>
21
+ {% trans 'Requested by' %}
22
+ </th>
23
+ <th>
24
+ {% trans 'Started at' %}
25
+ </th>
26
+ </tr>
27
+ </thead>
28
+ <tbody>
29
+ {% for workflow_state in object_list %}
30
+ <tr>
31
+ <td>
32
+ <b>{{ workflow_state.workflow }}</b>
33
+ </td>
34
+ <td>
35
+ <a href="{% admin_edit_url workflow_state.content_object %}">
36
+ {% latest_str workflow_state.content_object %}
37
+ </a>
38
+ {% i18n_enabled as show_locale_labels %}
39
+ {% if show_locale_labels and workflow_state.content_object.locale_id %}
40
+ {% locale_label_from_id workflow_state.content_object.locale_id as locale_label %}
41
+ {% status locale_label classname="w-status--label" %}
42
+ {% endif %}
43
+ </td>
44
+ <td>
45
+ {% admin_url_name workflow_state.content_object 'workflow_history_detail' as workflow_history_detail_url_name %}
46
+ {% url workflow_history_detail_url_name workflow_state.content_object.pk|admin_urlquote workflow_state.pk as status_url %}
47
+ {% status workflow_state.get_status_display url=status_url classname="w-status--primary" %}
48
+ </td>
49
+ <td>
50
+ <h2>{{ workflow_name }}</h2>
51
+ {% trans 'Incomplete task' as incomplete_title %}
52
+ {% for task in workflow_state.all_tasks_with_status %}
53
+ <span data-controller="w-tooltip" data-w-tooltip-content-value="{{ task.name }}: {{ task.status_display }}">
54
+ {% if task.status == 'approved' %}
55
+ {% icon "success" title=task.status_display classname="initial" %}
56
+ {% elif task.status == 'rejected' %}
57
+ {% icon "error" title=task.status_display classname="initial" %}
58
+ {% else %}
59
+ {% icon "radio-empty" title=incomplete_title classname="initial" %}
60
+ {% endif %}
61
+ </span>
62
+ {% endfor %}
63
+ </td>
64
+ <td>{{ workflow_state.requested_by|user_display_name }}</td>
65
+ <td>{{ workflow_state.created_at }}</td>
66
+ </tr>
67
+ {% endfor %}
68
+ </tbody>
69
+ </table>
70
+ {% endblock %}
71
+
72
+ {% block no_results_message %}
73
+ <p>{% trans "No pages/snippets have been submitted for moderation yet" %}</p>
74
+ {% endblock %}
@@ -0,0 +1,56 @@
1
+ {% extends 'wagtailadmin/reports/base_report_results.html' %}
2
+ {% load i18n wagtailadmin_tags %}
3
+
4
+ {% block results %}
5
+ <table class="listing">
6
+ <thead>
7
+ <tr>
8
+ <th>
9
+ {% trans 'Task' %}
10
+ </th>
11
+ <th>
12
+ {% trans 'Page/Snippet' %}
13
+ </th>
14
+ <th>
15
+ {% trans 'Status' %}
16
+ </th>
17
+ <th>
18
+ {% trans 'Started at' %}
19
+ </th>
20
+ <th>
21
+ {% trans 'Completed at' %}
22
+ </th>
23
+ </tr>
24
+ </thead>
25
+ <tbody>
26
+ {% for task_state in object_list %}
27
+ <tr>
28
+ <td>
29
+ <b>{{ task_state.task }}</b>
30
+ </td>
31
+ <td>
32
+ {% with task_state.workflow_state.content_object as object %}
33
+ <a href="{% admin_edit_url object %}">
34
+ {% latest_str object %}
35
+ </a>
36
+ {% i18n_enabled as show_locale_labels %}
37
+ {% if show_locale_labels and object.locale_id %}
38
+ {% locale_label_from_id object.locale_id as locale_label %}
39
+ {% status locale_label classname="w-status--label" %}
40
+ {% endif %}
41
+ {% endwith %}
42
+ </td>
43
+ <td>
44
+ {% status task_state.get_status_display classname="w-status--primary" %}
45
+ </td>
46
+ <td>{{ task_state.started_at }}</td>
47
+ <td>{{ task_state.finished_at }}</td>
48
+ </tr>
49
+ {% endfor %}
50
+ </tbody>
51
+ </table>
52
+ {% endblock %}
53
+
54
+ {% block no_results_message %}
55
+ <p>{% trans "No pages/snippets have been submitted for moderation yet" %}</p>
56
+ {% endblock %}
@@ -1,45 +1,9 @@
1
- <script>
2
- $(function() {
3
- document.querySelectorAll('footer [data-controller="w-dropdown"]').forEach((e) => {
4
- e.addEventListener(
5
- 'w-dropdown:shown',
6
- () => {
7
- ActivateWorkflowActionsForEditView('[data-edit-form]');
8
-
9
- {% if publishing_will_cancel_workflow %}
10
- /* Make user confirm before publishing the object if it will cancel an ongoing workflow */
11
- let cancellationConfirmed = false;
12
- $('[name=action-publish]').click((e) => {
13
- if (!cancellationConfirmed) {
14
- e.stopImmediatePropagation();
15
- e.preventDefault();
16
- ModalWorkflow({
17
- 'url': "{{ confirm_workflow_cancellation_url }}",
18
- 'onload': {
19
- 'confirm': function(modal, jsonData) {
20
- $('[data-confirm-cancellation]', modal.body).click((event) => {
21
- cancellationConfirmed = true;
22
- modal.close();
23
- e.currentTarget.click();
24
- })
25
- $('[data-cancel-dialog]', modal.body).click((event) => {
26
- modal.close();
27
- })
28
- },
29
- 'no_confirmation_needed': function(modal, jsonData) {
30
- modal.close();
31
- cancellationConfirmed = true;
32
- e.currentTarget.click();
33
- }
34
- },
35
- 'triggerElement': e.currentTarget,
36
- });
37
- }
38
- });
39
- {% endif %}
40
- },
41
- { once: true }
42
- )
43
- });
44
- });
1
+ {% load wagtailadmin_tags %}
2
+ <script
3
+ src="{% versioned_static 'wagtailadmin/js/workflow-action.js' %}"
4
+ data-activate="editor"
5
+ {% if publishing_will_cancel_workflow %}
6
+ data-confirm-cancellation-url="{{ confirm_workflow_cancellation_url }}"
7
+ {% endif %}
8
+ >
45
9
  </script>
@@ -7,8 +7,18 @@
7
7
  - `user` - A user object to use for the avatar image
8
8
  - `size` (string?) - small, large, square
9
9
  - `tooltip` (string?) - Modifier classes
10
+ - `tooltip_html` (string?) - An HTML element to use for the tooltip content
10
11
  {% endcomment %}
11
- <span class='{% classnames "avatar" size classname %}' {% if tooltip %} data-controller="w-tooltip" data-w-tooltip-content-value="{{ tooltip }}" {% endif %}>
12
+ <span
13
+ class="{% classnames 'avatar' size classname %}"
14
+ {% if tooltip or tooltip_html %} data-controller="w-tooltip" {% endif %}
15
+ {% if tooltip %} data-w-tooltip-content-value="{{ tooltip }}" {% endif %}
16
+ >
17
+ {% if tooltip_html %}
18
+ <template data-w-tooltip-target="content">
19
+ {{ tooltip_html }}
20
+ </template>
21
+ {% endif %}
12
22
  {% if size == 'small' %}
13
23
  <img src="{% avatar_url user size=25 %}" alt="" decoding="async" loading="lazy"/>
14
24
  {% elif size == 'large' %}
@@ -31,16 +31,17 @@
31
31
  <div class="w-dialog__content">
32
32
  <div class="w-dialog__header">
33
33
  <h2 class="w-dialog__title w-h1" id="title-{{ id }}">
34
- {% if icon_name %}{% icon name=icon_name classname="w-dialog__icon" %}{% endif %}
35
- {{ title }}
34
+ {% fragment as icon_classname %}{% classnames "w-dialog__icon" icon_classname %}{% endfragment %}
35
+ {% if icon_name %}{% icon name=icon_name classname=icon_classname %}{% endif %}
36
+ <span id="title-text-{{ id }}">{{ title }}</span>
36
37
  </h2>
37
38
 
38
39
  {% if subtitle %}
39
- <p class="w-dialog__subtitle w-help-text">{{ subtitle }}</p>
40
+ <p class="w-dialog__subtitle w-help-text" id="subtitle-{{ id }}">{{ subtitle }}</p>
40
41
  {% endif %}
41
42
  </div>
42
43
 
43
- <div data-w-dialog-target="body">
44
+ <div class="w-dialog__body" data-w-dialog-target="body">
44
45
  {{ children }}
45
46
  </div>
46
47
  </div>
@@ -8,6 +8,7 @@
8
8
  - `toggle_classname` (string?) - additional toggle classes
9
9
  - `classname` (string?) - additional component classes
10
10
  - `children` - Dropdown contents (`a` and `button` elements only)
11
+ - `keep_mounted` (boolean?) - Whether or not the dropdown should keep its DOM node mounted when hidden
11
12
  {% endcomment %}
12
13
 
13
14
  <div class="{% classnames 'w-dropdown-button' classname %}">
@@ -16,7 +17,7 @@
16
17
  {% fragment as toggle_classes %}{% classnames toggle_classname "button" %}{% endfragment %}
17
18
  {# Built with w-sr-only so there is no visible tooltip. #}
18
19
  {% fragment as toggle_label %}<span class="w-sr-only">{% trans "More actions" %}</span>{% endfragment %}
19
- {% dropdown theme="dropdown-button" toggle_label=toggle_label toggle_classname=toggle_classes toggle_icon=toggle_icon|default:"arrow-down" toggle_tooltip_offset="[0, 0]" %}
20
+ {% dropdown theme="dropdown-button" toggle_label=toggle_label toggle_classname=toggle_classes toggle_icon=toggle_icon|default:"arrow-down" toggle_tooltip_offset="[0, 0]" keep_mounted=keep_mounted %}
20
21
  {{ children }}
21
22
  {% enddropdown %}
22
23
  {% endif %}
@@ -0,0 +1,132 @@
1
+ {% load wagtailadmin_tags i18n %}
2
+
3
+ <ol class="w-editing-sessions__list">
4
+ {% for session in sessions|slice:":4" %}
5
+ <li>
6
+ {% fragment as avatar %}
7
+ {% avatar user=session.user classname="w-editing-sessions__avatar" %}
8
+ {% endfragment %}
9
+
10
+ {% if session.revision_id %}
11
+ {% fragment as avatar_decorated %}
12
+ <div class="w-editing-sessions__decorated-avatar w-ping w-ping--critical">
13
+ {{ avatar }}
14
+ {% icon name="warning" %}
15
+ <span class="w-editing-sessions__decorator-filler"></span>
16
+ </div>
17
+ {% endfragment %}
18
+
19
+ {% if current_session.user == session.user %}
20
+ {% blocktranslate trimmed asvar saved_new_version_message %}
21
+ You saved a new version in another session
22
+ {% endblocktranslate %}
23
+ {% else %}
24
+ {% blocktranslate trimmed with user_name=session.user|user_display_name|default:_("System") asvar saved_new_version_message %}
25
+ {{ user_name }} saved a new version
26
+ {% endblocktranslate %}
27
+ {% endif %}
28
+
29
+ {% dropdown theme="popup" classname="w-editing-sessions__session w-editing-sessions__session--saved" toggle_label=avatar_decorated toggle_aria_label=saved_new_version_message %}
30
+ <div class="w-editing-sessions__popup">
31
+ <div class="w-editing-sessions__message">
32
+ {% icon name="warning" %}
33
+ {{ saved_new_version_message }}
34
+ </div>
35
+
36
+ {% comment %}
37
+ Use a custom button element instead of the dialog_toggle.html so we can add arbitrary
38
+ data attributes to the button element. This is useful for allowing the SessionController
39
+ to conditionally show the dialog, i.e. only when the user has unsaved changes.
40
+ {% endcomment %}
41
+ <button type="button" data-w-session-target="reload" class="button button-small button-secondary chooser__choose-button" data-dialog-id="w-unsaved-changes-dialog">
42
+ {% icon name="rotate" %}
43
+ {% trans "Refresh" %}
44
+ </button>
45
+ </div>
46
+ {% enddropdown %}
47
+ {% elif session.is_editing %}
48
+ {% if current_session.user == session.user %}
49
+ {% blocktranslate trimmed asvar has_unsaved_changes_message %}
50
+ You have unsaved changes in another session
51
+ {% endblocktranslate %}
52
+ {% else %}
53
+ {% blocktranslate trimmed with user_name=session.user|user_display_name|default:_("System") asvar has_unsaved_changes_message %}
54
+ {{ user_name }} has unsaved changes
55
+ {% endblocktranslate %}
56
+ {% endif %}
57
+
58
+ {% dropdown theme="popup" classname="w-editing-sessions__session w-editing-sessions__session--editing" toggle_label=avatar toggle_aria_label=has_unsaved_changes_message %}
59
+ <div class="w-editing-sessions__popup">
60
+ <div class="w-editing-sessions__message">
61
+ {% icon name="warning" %}
62
+ {{ has_unsaved_changes_message }}
63
+ </div>
64
+ </div>
65
+ {% enddropdown %}
66
+ {% else %}
67
+ <button class="w-editing-sessions__session" type="button" data-controller="w-tooltip">
68
+ {{ avatar }}
69
+ <div class="w-editing-sessions__popup" data-w-tooltip-target="content" hidden>
70
+ <span class="w-editing-sessions__name">{{ session.user|user_display_name|default:_("System") }}</span>
71
+ <span class="w-sr-only">-</span>
72
+ <span>{% trans "Currently viewing" %}</span>
73
+ </div>
74
+ </button>
75
+ {% endif %}
76
+ </li>
77
+ {% endfor %}
78
+ {% if sessions|length > 4 %}
79
+ {% blocktranslate trimmed count num_user=sessions|length|add:"-4" asvar num_other_users_message %}
80
+ One other user is currently viewing
81
+ {% plural %}
82
+ {{ num_user }} other users are currently viewing
83
+ {% endblocktranslate %}
84
+
85
+ {% fragment as more_sessions_toggle %}
86
+ +{{ sessions|length|add:"-4" }}
87
+ {% endfragment %}
88
+
89
+ <li>
90
+ <span id="w-editing-sessions-more-summary" class="w-sr-only">{{ num_other_users_message }}</span>
91
+
92
+ {% dropdown theme="drilldown" classname="w-editing-sessions__session w-editing-sessions__session--more" toggle_classname="w-editing-sessions__avatar" toggle_label=more_sessions_toggle toggle_describedby="w-editing-sessions-more-summary" %}
93
+ <ol class="w-editing-sessions__more-list">
94
+ {% for session in sessions|slice:"4:" %}
95
+ <li class="w-editing-sessions__list-item">
96
+ {% avatar user=session.user size="small" %}
97
+ <span>{{ session.user|user_display_name|default:_("System") }}</span>
98
+ </li>
99
+ {% endfor %}
100
+ </ol>
101
+ {% enddropdown %}
102
+ </li>
103
+ {% endif %}
104
+ </ol>
105
+
106
+ {% if sessions.0.revision_id %}
107
+ <template data-controller="w-teleport" data-w-teleport-target-value="#title-text-w-overwrite-changes-dialog" data-w-teleport-reset-value="true">
108
+ {% if current_session.user == sessions.0.user %}
109
+ {% blocktranslate trimmed with model_name=content_type.name asvar someone_has_saved_message %}
110
+ You have saved a newer version of this {{ model_name }} in another session
111
+ {% endblocktranslate %}
112
+ {% else %}
113
+ {% blocktranslate trimmed with user_name=sessions.0.user|user_display_name|default:_("System") model_name=content_type.name asvar someone_has_saved_message %}
114
+ {{ user_name }} has saved a newer version of this {{ model_name }}
115
+ {% endblocktranslate %}
116
+ {% endif %}
117
+ {{ someone_has_saved_message }}
118
+ </template>
119
+
120
+ <template data-controller="w-teleport" data-w-teleport-target-value="#subtitle-w-overwrite-changes-dialog" data-w-teleport-reset-value="true">
121
+ {% if current_session.user == sessions.0.user %}
122
+ {% blocktranslate trimmed asvar overwrite_message %}
123
+ Proceeding will overwrite the changes you made in that session. Refreshing the page will lose any of your unsaved changes in the current session.
124
+ {% endblocktranslate %}
125
+ {% else %}
126
+ {% blocktranslate trimmed with user_name=sessions.0.user|user_display_name|default:_("System") asvar overwrite_message %}
127
+ Proceeding will overwrite the changes made by {{ user_name }}. Refreshing the page will lose any of your unsaved changes.
128
+ {% endblocktranslate %}
129
+ {% endif %}
130
+ {{ overwrite_message }}
131
+ </template>
132
+ {% endif %}
@@ -0,0 +1,44 @@
1
+ {% load i18n l10n wagtailadmin_tags %}
2
+
3
+ {% dialog id="w-unsaved-changes-dialog" icon_name="warning" icon_classname="w-text-text-error" title=_("Refreshing the page means you will lose any unsaved changes") %}
4
+ <div class="w-editing-sessions-dialog-buttons">
5
+ <button class="button" type="button" data-controller="w-action" data-action="w-action#forceReload">{% trans "Refresh page" %}</button>
6
+ <button class="button button-secondary" type="button" data-action="w-dialog#hide">{% trans "Cancel" %}</button>
7
+ </div>
8
+ {% enddialog %}
9
+
10
+ {% comment %}
11
+ The "-" strings are only placeholders so that the appropriate elements are rendered.
12
+ The messages will be provided via the sessions list component and teleported into the corresponding elements.
13
+ The dialog won't ever be shown without the actual messages under normal circumstances.
14
+ {% endcomment %}
15
+ {% dialog id="w-overwrite-changes-dialog" dialog_root_selector='[data-edit-form]' icon_name="warning" icon_classname="w-text-text-error" title="-" subtitle="-" %}
16
+ <div class="w-editing-sessions-dialog-buttons">
17
+ <button class="button" type="button" data-w-dialog-target="confirm" data-action="w-dialog#confirm">{% trans "Continue" %}</button>
18
+ <button class="button button-secondary" type="button" data-controller="w-action" data-action="w-action#forceReload">{% trans "Refresh the page" %}</button>
19
+ </div>
20
+ {% enddialog %}
21
+
22
+ <form
23
+ method="post"
24
+ class="w-editing-sessions"
25
+ data-controller="w-swap w-action w-session"
26
+ data-w-swap-target-value="#w-editing-sessions"
27
+ data-w-swap-src-value="{{ ping_url }}"
28
+ data-w-swap-json-path-value="html"
29
+ data-w-swap-defer-value="true"
30
+ data-w-action-continue-value="true"
31
+ data-w-action-url-value="{{ release_url }}"
32
+ data-w-session-interval-value="{{ ping_interval|unlocalize }}"
33
+ data-w-session-w-dialog-outlet="[data-edit-form] [data-controller='w-dialog']#w-overwrite-changes-dialog"
34
+ data-action="w-session:ping->w-swap#submit visibilitychange@document->w-session#dispatchVisibilityState w-session:visible->w-session#ping w-session:visible->w-session#addInterval w-session:hidden->w-session#clearInterval w-session:hidden->w-action#sendBeacon w-unsaved:add@document->w-session#setUnsavedChanges w-unsaved:clear@document->w-session#setUnsavedChanges w-swap:json->w-session#updateSessionData"
35
+ >
36
+ <input type="checkbox" name="is_editing" value="1" data-w-session-target="unsavedChanges" hidden />
37
+ {% if revision_id %}
38
+ {# The ID of the latest revision that was known when this module was initially loaded #}
39
+ <input type="hidden" name="revision_id" value="{{ revision_id }}" />
40
+ {% endif %}
41
+ <div id="w-editing-sessions">
42
+ {% component sessions_list %}
43
+ </div>
44
+ </form>
@@ -114,7 +114,13 @@
114
114
  {% endif %}
115
115
  {% endblock %}
116
116
 
117
- <div class="w-w-full sm:w-w-min w-flex sm:w-flex-nowrap sm:w-flex-row w-items-center w-p-0 sm:w-py-0 sm:w-pr-4 sm:w-justify-end">
117
+ <div class="w-w-full w-overflow-auto sm:w-w-min w-flex sm:w-flex-nowrap sm:w-flex-row w-items-center w-p-0 sm:w-py-0 w-px-2 sm:w-pr-4 sm:w-justify-end">
118
+ {% block editing_sessions %}
119
+ {% if editing_sessions %}
120
+ {% component editing_sessions %}
121
+ {% endif %}
122
+ {% endblock %}
123
+
118
124
  {% block toggles %}
119
125
  {% if side_panels %}
120
126
  {% include "wagtailadmin/shared/side_panel_toggles.html" %}
@@ -21,7 +21,7 @@
21
21
  w-whitespace-nowrap
22
22
  w-px-1
23
23
  w-ml-3
24
- w-text-[0.6875rem]
24
+ w-text-11
25
25
  w-rounded-sm
26
26
  w-bg-transparent
27
27
  w-text-text-meta
@@ -1,23 +1,39 @@
1
1
  {% load i18n wagtailadmin_tags %}
2
-
3
2
  <template id="w-a11y-result-row-template">
4
3
  <div class="w-a11y-result__row" data-a11y-result-row>
5
- <h3 class="w-a11y-result__header">
6
- <span class="w-a11y-result__name" data-a11y-result-name></span>
7
- <span class="w-sr-only">{% trans 'Issues found' %}</span><span class="w-a11y-result__subtotal_count" data-a11y-result-count></span>
8
- </h3>
9
- <div class="w-a11y-result__container" data-a11y-result-container></div>
4
+ <div>
5
+ <h3 class="w-a11y-result__header">
6
+ <span class="w-a11y-result__name" data-a11y-result-name></span>
7
+ </h3>
8
+ <div class="w-a11y-result__help" data-a11y-result-help></div>
9
+ </div>
10
+ <button class="w-a11y-result__selector"
11
+ data-a11y-result-selector
12
+ aria-label="{% trans 'Show issue' %}"
13
+ type="button">{% icon name="crosshairs" classname="w-a11y-result__icon" %}</button>
10
14
  </div>
11
15
  </template>
12
- <template id="w-a11y-result-selector-template">
13
- <button class="w-a11y-result__selector" data-a11y-result-selector type="button">
14
- {% icon name="link-external" classname="w-a11y-result__icon" %}
15
- <span data-a11y-result-selector-text></span>
16
- </button>
17
- </template>
18
-
19
- <div class="w-mt-12">
20
- <h2 class="w-flex w-items-center w-gap-2"><span>{% trans 'Issues found' %}</span><span class="w-a11y-result__count" data-a11y-result-count>0</span></h2>
21
- <div data-checks-panel></div>
16
+ <div class="w-divide-y w-divide-border-furniture w-py-6 w-pl-2 lg:w-pl-8">
17
+ <div>
18
+ <h2 class="w-my-5 w-text-16 w-font-bold w-text-text-label">
19
+ {% trans 'Content metrics' %}
20
+ </h2>
21
+ <div class="w-flex w-gap-10">
22
+ <div>
23
+ <h3 class="w-my-2 w-text-14 w-text-text-placeholder">{% trans 'Words' %}</h3>
24
+ <p class="w-font-semibold w-text-text-label" data-content-word-count>-</p>
25
+ </div>
26
+ <div>
27
+ <h3 class="w-my-2 w-text-14 w-text-text-placeholder">{% trans 'Reading time' %}</h3>
28
+ <p class="w-font-semibold w-text-text-label" data-content-reading-time>-</p>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ <div class="w-mt-3">
33
+ <h2 class="w-flex w-items-center w-gap-2 w-my-5 w-text-16 w-font-bold">
34
+ <span>{% trans 'Issues found' %}</span><span class="w-a11y-result__count" data-a11y-result-count>0</span>
35
+ </h2>
36
+ <div class="w-flex w-flex-col w-gap-2.5" data-checks-panel></div>
37
+ </div>
22
38
  </div>
23
39
  {{ axe_configuration|json_script:"accessibility-axe-configuration" }}
@@ -19,7 +19,7 @@
19
19
  <body id="wagtail" class="{% classnames bodyclass sidebar_collapsed|yesno:"sidebar-collapsed," messages|yesno:"has-messages," %}" data-controller="w-init" data-w-init-ready-class="ready">
20
20
  <div data-sprite></div>
21
21
 
22
- <script src="{% versioned_static 'wagtailadmin/js/icons.js' %}" data-icon-url="{% url 'wagtailadmin_sprite' %}"></script>
22
+ <script src="{% versioned_static 'wagtailadmin/js/icons.js' %}" data-icon-url="{% icon_sprite_url %}"></script>
23
23
 
24
24
  <noscript class="capabilitymessage">
25
25
  {% blocktrans trimmed %}
@@ -17,19 +17,17 @@
17
17
  {# Contents of the dialog created in JS based on these templates. #}
18
18
  <template id="w-a11y-result-row-template">
19
19
  <div class="w-a11y-result__row" data-a11y-result-row>
20
- <h3 class="w-a11y-result__header">
21
- <span class="w-a11y-result__name" data-a11y-result-name></span>
22
- <span class="w-sr-only">{% trans 'Issues found' %}</span><span class="w-a11y-result__subtotal_count" data-a11y-result-count></span>
23
- </h3>
24
- <div class="w-a11y-result__container" data-a11y-result-container></div>
20
+ <div>
21
+ <h3 class="w-a11y-result__header">
22
+ <span class="w-a11y-result__name" data-a11y-result-name></span>
23
+ </h3>
24
+ <div class="w-a11y-result__help" data-a11y-result-help></div>
25
+ </div>
26
+ <button class="w-a11y-result__selector" data-a11y-result-selector aria-label="{% trans 'Show issue' %}" type="button">
27
+ {% icon name="crosshairs" classname="w-a11y-result__icon" %}
28
+ </button>
25
29
  </div>
26
30
  </template>
27
- <template id="w-a11y-result-selector-template">
28
- <button class="w-a11y-result__selector" data-a11y-result-selector type="button">
29
- {% icon name="crosshairs" classname="w-a11y-result__icon" %}
30
- <span data-a11y-result-selector-text></span>
31
- </button>
32
- </template>
33
31
  <template id="w-a11y-result-outline-template">
34
32
  <div class="w-a11y-result__outline" data-a11y-result-outline></div>
35
33
  </template>
@@ -29,6 +29,7 @@ from laces.templatetags.laces import component
29
29
 
30
30
  from wagtail import hooks
31
31
  from wagtail.admin.admin_url_finder import AdminURLFinder
32
+ from wagtail.admin.icons import get_icon_sprite_url
32
33
  from wagtail.admin.localization import get_js_translation_strings
33
34
  from wagtail.admin.menu import admin_menu
34
35
  from wagtail.admin.search import admin_search_areas
@@ -584,7 +585,7 @@ def bulk_action_choices(context, app_label, model_name):
584
585
 
585
586
 
586
587
  @register.inclusion_tag("wagtailadmin/shared/avatar.html")
587
- def avatar(user=None, classname=None, size=None, tooltip=None):
588
+ def avatar(user=None, classname=None, size=None, tooltip=None, tooltip_html=None):
588
589
  """
589
590
  Displays a user avatar using the avatar template
590
591
  Usage:
@@ -594,9 +595,16 @@ def avatar(user=None, classname=None, size=None, tooltip=None):
594
595
  :param user: the user to get avatar information from (User)
595
596
  :param size: default None (None|'small'|'large'|'square')
596
597
  :param tooltip: Optional tooltip to display under the avatar (string)
598
+ :param tooltip_html: Optional tooltip as an HTML element for rich content (string)
597
599
  :return: Rendered template snippet
598
600
  """
599
- return {"user": user, "classname": classname, "size": size, "tooltip": tooltip}
601
+ return {
602
+ "user": user,
603
+ "classname": classname,
604
+ "size": size,
605
+ "tooltip": tooltip,
606
+ "tooltip_html": tooltip_html,
607
+ }
600
608
 
601
609
 
602
610
  @register.simple_tag
@@ -1377,3 +1385,6 @@ def human_readable_date(date, description=None, placement="top"):
1377
1385
  # Shadow the laces `component` tag which was extracted from Wagtail. The shadowing
1378
1386
  # is useful to avoid having to update all the templates that use the `component` tag.
1379
1387
  register.tag("component", component)
1388
+
1389
+
1390
+ register.simple_tag(get_icon_sprite_url, name="icon_sprite_url")
File without changes
@@ -0,0 +1 @@
1
+ DATETIME_INPUT_FORMATS = ["%d.%m.%Y. %H:%M"]