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.
- wagtail/__init__.py +1 -1
- wagtail/actions/copy_for_translation.py +15 -1
- wagtail/admin/checks.py +20 -30
- wagtail/admin/forms/pages.py +10 -0
- wagtail/admin/icons.py +43 -0
- wagtail/admin/locale/en/LC_MESSAGES/django.po +405 -295
- wagtail/admin/locale/en/LC_MESSAGES/djangojs.po +21 -3
- wagtail/admin/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/admin/locale/sl/LC_MESSAGES/django.po +30 -0
- wagtail/admin/menu.py +2 -2
- wagtail/admin/migrations/0004_editingsession.py +57 -0
- wagtail/admin/migrations/0005_editingsession_is_editing.py +18 -0
- wagtail/admin/models.py +36 -3
- wagtail/admin/rich_text/editors/draftail/__init__.py +2 -20
- wagtail/admin/static/wagtailadmin/css/core.css +1 -1
- wagtail/admin/static/wagtailadmin/js/bulk-actions.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/chooser-widget.js +1 -1
- wagtail/admin/static/wagtailadmin/js/comments.js +1 -1
- wagtail/admin/static/wagtailadmin/js/core.js +1 -1
- wagtail/admin/static/wagtailadmin/js/date-time-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/draftail.js +1 -1
- wagtail/admin/static/wagtailadmin/js/expanding-formset.js +1 -1
- wagtail/admin/static/wagtailadmin/js/filtered-select.js +1 -1
- wagtail/admin/static/wagtailadmin/js/modal-workflow.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser-telepath.js +1 -1
- wagtail/admin/static/wagtailadmin/js/page-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js +2 -1
- wagtail/admin/static/wagtailadmin/js/preview-panel.js.LICENSE.txt +11 -0
- wagtail/admin/static/wagtailadmin/js/privacy-switch.js +1 -1
- wagtail/admin/static/wagtailadmin/js/sidebar.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser-modal.js +1 -1
- wagtail/admin/static/wagtailadmin/js/task-chooser.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/blocks.js +1 -1
- wagtail/admin/static/wagtailadmin/js/telepath/widgets.js +1 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js +2 -1
- wagtail/admin/static/wagtailadmin/js/userbar.js.LICENSE.txt +11 -0
- wagtail/admin/static/wagtailadmin/js/vendor.js +1 -1
- wagtail/admin/static/wagtailadmin/js/vendor.js.LICENSE.txt +0 -12
- wagtail/admin/static/wagtailadmin/js/wagtailadmin.js +1 -1
- wagtail/admin/static/wagtailadmin/js/workflow-action.js +1 -1
- wagtail/admin/templates/wagtailadmin/collection_privacy/ancestor_privacy.html +2 -6
- wagtail/admin/templates/wagtailadmin/generic/index_results.html +1 -17
- wagtail/admin/templates/wagtailadmin/generic/listing_results.html +20 -1
- wagtail/admin/templates/wagtailadmin/home/workflow_objects_to_moderate.html +2 -11
- wagtail/admin/templates/wagtailadmin/page_privacy/ancestor_privacy.html +2 -6
- wagtail/admin/templates/wagtailadmin/page_privacy/no_privacy.html +2 -0
- wagtail/admin/templates/wagtailadmin/pages/_editor_js.html +0 -1
- wagtail/admin/templates/wagtailadmin/pages/action_menu/menu.html +1 -1
- wagtail/admin/templates/wagtailadmin/reports/aging_pages_results.html +54 -0
- wagtail/admin/templates/wagtailadmin/reports/base_page_report.html +1 -17
- wagtail/admin/templates/wagtailadmin/reports/base_page_report_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/reports/base_report.html +1 -40
- wagtail/admin/templates/wagtailadmin/reports/base_report_results.html +1 -0
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_report.html +21 -27
- wagtail/admin/templates/wagtailadmin/reports/listing/_list_page_types_usage.html +48 -54
- wagtail/admin/templates/wagtailadmin/reports/{locked_pages.html → locked_pages_results.html} +3 -3
- wagtail/admin/templates/wagtailadmin/reports/page_types_usage_results.html +10 -0
- wagtail/admin/templates/wagtailadmin/reports/site_history_results.html +53 -0
- wagtail/admin/templates/wagtailadmin/reports/workflow_results.html +74 -0
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks_results.html +56 -0
- wagtail/admin/templates/wagtailadmin/shared/_workflow_init.html +8 -44
- wagtail/admin/templates/wagtailadmin/shared/avatar.html +11 -1
- wagtail/admin/templates/wagtailadmin/shared/dialog/dialog.html +5 -4
- wagtail/admin/templates/wagtailadmin/shared/dropdown/dropdown_button.html +2 -1
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/list.html +132 -0
- wagtail/admin/templates/wagtailadmin/shared/editing_sessions/module.html +44 -0
- wagtail/admin/templates/wagtailadmin/shared/headers/slim_header.html +7 -1
- wagtail/admin/templates/wagtailadmin/shared/page_status_tag_new.html +1 -1
- wagtail/admin/templates/wagtailadmin/shared/side_panels/checks.html +32 -16
- wagtail/admin/templates/wagtailadmin/skeleton.html +1 -1
- wagtail/admin/templates/wagtailadmin/userbar/item_accessibility.html +9 -11
- wagtail/admin/templatetags/wagtailadmin_tags.py +13 -2
- wagtail/admin/tests/formats/en/__init__.py +0 -0
- wagtail/admin/tests/formats/en/formats.py +1 -0
- wagtail/admin/tests/pages/test_create_page.py +47 -0
- wagtail/admin/tests/pages/test_edit_page.py +10 -8
- wagtail/admin/tests/pages/test_parent_page_chooser_view.py +45 -1
- wagtail/admin/tests/test_checks.py +53 -3
- wagtail/admin/tests/test_collections_views.py +62 -1
- wagtail/admin/tests/test_edit_handlers.py +37 -0
- wagtail/admin/tests/test_editing_sessions.py +1336 -0
- wagtail/admin/tests/test_icon_sprite.py +12 -21
- wagtail/admin/tests/test_page_chooser.py +309 -7
- wagtail/admin/tests/test_privacy.py +82 -0
- wagtail/admin/tests/test_reports_views.py +464 -70
- wagtail/admin/tests/test_userbar.py +93 -6
- wagtail/admin/tests/test_workflows.py +223 -33
- wagtail/admin/tests/viewsets/test_model_viewset.py +151 -2
- wagtail/admin/ui/editing_sessions.py +57 -0
- wagtail/admin/urls/__init__.py +9 -15
- wagtail/admin/urls/editing_sessions.py +17 -0
- wagtail/admin/urls/reports.py +33 -1
- wagtail/admin/userbar.py +77 -20
- wagtail/admin/views/chooser.py +49 -22
- wagtail/admin/views/collections.py +0 -11
- wagtail/admin/views/editing_sessions.py +193 -0
- wagtail/admin/views/generic/__init__.py +1 -0
- wagtail/admin/views/generic/history.py +9 -3
- wagtail/admin/views/generic/mixins.py +44 -3
- wagtail/admin/views/generic/models.py +46 -72
- wagtail/admin/views/generic/permissions.py +20 -10
- wagtail/admin/views/home.py +2 -31
- wagtail/admin/views/page_privacy.py +20 -5
- wagtail/admin/views/pages/choose_parent.py +62 -0
- wagtail/admin/views/pages/edit.py +28 -0
- wagtail/admin/views/reports/aging_pages.py +6 -10
- wagtail/admin/views/reports/audit_logging.py +13 -42
- wagtail/admin/views/reports/base.py +31 -4
- wagtail/admin/views/reports/locked_pages.py +5 -8
- wagtail/admin/views/reports/page_types_usage.py +6 -10
- wagtail/admin/views/reports/workflows.py +36 -12
- wagtail/admin/viewsets/base.py +8 -3
- wagtail/admin/viewsets/chooser.py +1 -1
- wagtail/admin/viewsets/model.py +26 -1
- wagtail/admin/wagtail_hooks.py +2 -1
- wagtail/api/v2/filters.py +6 -0
- wagtail/api/v2/tests/test_documents.py +1 -1
- wagtail/api/v2/tests/test_images.py +1 -1
- wagtail/api/v2/tests/test_pages.py +11 -1
- wagtail/api/v2/utils.py +2 -2
- wagtail/blocks/base.py +35 -12
- wagtail/blocks/definition_lookup.py +85 -0
- wagtail/blocks/list_block.py +12 -0
- wagtail/blocks/migrations/migrate_operation.py +2 -0
- wagtail/blocks/stream_block.py +19 -0
- wagtail/blocks/struct_block.py +19 -0
- wagtail/contrib/forms/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/frontend_cache/backends/__init__.py +5 -0
- wagtail/contrib/frontend_cache/backends/azure.py +179 -0
- wagtail/contrib/frontend_cache/backends/base.py +28 -0
- wagtail/contrib/frontend_cache/backends/cloudflare.py +114 -0
- wagtail/contrib/frontend_cache/backends/cloudfront.py +99 -0
- wagtail/contrib/frontend_cache/backends/http.py +64 -0
- wagtail/contrib/frontend_cache/tests.py +59 -17
- wagtail/contrib/frontend_cache/utils.py +26 -8
- wagtail/contrib/redirects/filters.py +15 -1
- wagtail/contrib/redirects/locale/en/LC_MESSAGES/django.po +37 -72
- wagtail/contrib/redirects/models.py +6 -5
- wagtail/contrib/redirects/templates/wagtailredirects/edit.html +1 -38
- wagtail/contrib/redirects/tests/test_redirects.py +141 -1
- wagtail/contrib/redirects/urls.py +1 -2
- wagtail/contrib/redirects/views.py +39 -80
- wagtail/contrib/routable_page/models.py +6 -4
- wagtail/contrib/routable_page/tests.py +11 -0
- wagtail/contrib/search_promotions/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/settings/locale/en/LC_MESSAGES/django.po +4 -4
- wagtail/contrib/simple_translation/locale/en/LC_MESSAGES/django.po +5 -1
- wagtail/contrib/simple_translation/models.py +2 -1
- wagtail/contrib/styleguide/locale/en/LC_MESSAGES/django.po +7 -7
- wagtail/contrib/table_block/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/contrib/table_block/static/table_block/js/table.js +1 -1
- wagtail/contrib/typed_table_block/blocks.py +19 -0
- wagtail/contrib/typed_table_block/locale/en/LC_MESSAGES/django.po +10 -10
- wagtail/contrib/typed_table_block/static/typed_table_block/js/typed_table_block.js +1 -1
- wagtail/contrib/typed_table_block/tests.py +38 -0
- wagtail/coreutils.py +1 -1
- wagtail/documents/__init__.py +1 -1
- wagtail/documents/locale/en/LC_MESSAGES/django.po +8 -8
- wagtail/documents/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/documents/locale/sl/LC_MESSAGES/django.po +20 -0
- wagtail/documents/models.py +5 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-modal.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser-telepath.js +1 -1
- wagtail/documents/static/wagtaildocs/js/document-chooser.js +1 -1
- wagtail/documents/tests/test_models.py +5 -1
- wagtail/embeds/apps.py +2 -0
- wagtail/embeds/embeds.py +12 -14
- wagtail/embeds/finders/__init__.py +2 -0
- wagtail/embeds/finders/facebook.py +17 -33
- wagtail/embeds/finders/instagram.py +19 -16
- wagtail/embeds/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/embeds/signal_handlers.py +13 -0
- wagtail/embeds/tests/test_embeds.py +7 -7
- wagtail/fields.py +58 -14
- wagtail/images/__init__.py +1 -1
- wagtail/images/locale/en/LC_MESSAGES/django.po +34 -34
- wagtail/images/locale/sl/LC_MESSAGES/django.mo +0 -0
- wagtail/images/locale/sl/LC_MESSAGES/django.po +20 -0
- wagtail/images/models.py +2 -0
- wagtail/images/static/wagtailimages/js/image-chooser-modal.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser-telepath.js +1 -1
- wagtail/images/static/wagtailimages/js/image-chooser.js +1 -1
- wagtail/images/templates/wagtailimages/images/edit.html +4 -4
- wagtail/images/tests/test_admin_views.py +26 -2
- wagtail/images/views/chooser.py +6 -1
- wagtail/locale/en/LC_MESSAGES/django.po +84 -80
- wagtail/locales/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/locales/tests.py +16 -0
- wagtail/locales/wagtail_hooks.py +0 -9
- wagtail/migrations/0094_alter_page_locale.py +19 -0
- wagtail/models/__init__.py +11 -5
- wagtail/models/i18n.py +6 -1
- wagtail/project_template/requirements.txt +1 -1
- wagtail/search/locale/en/LC_MESSAGES/django.po +1 -1
- wagtail/signals.py +4 -0
- wagtail/sites/locale/en/LC_MESSAGES/django.po +2 -2
- wagtail/sites/tests.py +15 -0
- wagtail/sites/wagtail_hooks.py +0 -9
- wagtail/snippets/locale/en/LC_MESSAGES/django.po +9 -9
- wagtail/snippets/permissions.py +5 -3
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser-telepath.js +1 -1
- wagtail/snippets/static/wagtailsnippets/js/snippet-chooser.js +1 -1
- wagtail/snippets/templates/wagtailsnippets/snippets/action_menu/menu.html +1 -1
- wagtail/snippets/tests/test_snippets.py +78 -12
- wagtail/snippets/tests/test_viewset.py +22 -0
- wagtail/snippets/views/snippets.py +19 -14
- wagtail/snippets/wagtail_hooks.py +2 -10
- wagtail/templatetags/wagtailcore_tags.py +3 -0
- wagtail/test/dummy_external_storage.py +1 -1
- wagtail/test/i18n/migrations/0003_alter_clusterabletestmodel_locale_and_more.py +40 -0
- wagtail/test/routablepage/models.py +4 -0
- wagtail/test/snippets/migrations/0012_alter_translatablesnippet_locale.py +20 -0
- wagtail/test/testapp/migrations/0038_sociallink.py +52 -0
- wagtail/test/testapp/migrations/0039_alter_eventcategory_locale_and_more.py +45 -0
- wagtail/test/testapp/models.py +24 -0
- wagtail/test/testapp/views.py +1 -0
- wagtail/test/testapp/wagtail_hooks.py +9 -0
- wagtail/test/urls_multilang.py +6 -1
- wagtail/test/urls_multilang_non_root.py +11 -0
- wagtail/tests/streamfield_migrations/test_migrations.py +53 -12
- wagtail/tests/test_audit_log.py +72 -2
- wagtail/tests/test_blocks.py +103 -0
- wagtail/tests/test_signals.py +49 -2
- wagtail/tests/test_streamfield.py +153 -0
- wagtail/tests/test_utils.py +14 -0
- wagtail/tests/tests.py +5 -0
- wagtail/users/apps.py +1 -0
- wagtail/users/forms.py +7 -0
- wagtail/users/locale/en/LC_MESSAGES/django.po +55 -50
- wagtail/users/models.py +1 -0
- wagtail/users/templates/wagtailusers/groups/includes/formatted_permissions.html +3 -2
- wagtail/users/templatetags/wagtailusers_tags.py +9 -0
- wagtail/users/tests/__init__.py +7 -1
- wagtail/users/tests/test_admin_views.py +117 -32
- wagtail/users/views/groups.py +4 -0
- wagtail/users/views/users.py +58 -14
- wagtail/users/wagtail_hooks.py +7 -123
- wagtail/utils/utils.py +1 -0
- wagtail/utils/version.py +5 -2
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/METADATA +3 -3
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/RECORD +248 -222
- wagtail/admin/templates/wagtailadmin/reports/aging_pages.html +0 -58
- wagtail/admin/templates/wagtailadmin/reports/page_types_usage.html +0 -18
- wagtail/admin/templates/wagtailadmin/reports/site_history.html +0 -57
- wagtail/admin/templates/wagtailadmin/reports/workflow.html +0 -81
- wagtail/admin/templates/wagtailadmin/reports/workflow_tasks.html +0 -63
- wagtail/contrib/frontend_cache/backends.py +0 -400
- wagtail/contrib/redirects/templates/wagtailredirects/list.html +0 -43
- wagtail/contrib/redirects/templates/wagtailredirects/reports/redirects_report.html +0 -14
- wagtail/contrib/redirects/tests/test_reports_view.py +0 -82
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/LICENSE +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/WHEEL +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/entry_points.txt +0 -0
- {wagtail-6.1.3.dist-info → wagtail-6.2rc1.dist-info}/top_level.txt +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from typing import List
|
|
2
3
|
|
|
3
4
|
from django.core.exceptions import PermissionDenied, SuspiciousOperation
|
|
4
5
|
from django.db import transaction
|
|
@@ -16,7 +17,6 @@ from wagtail.admin.auth import PermissionPolicyChecker
|
|
|
16
17
|
from wagtail.admin.forms.search import SearchForm
|
|
17
18
|
from wagtail.admin.ui.tables import Column, StatusTagColumn, TitleColumn
|
|
18
19
|
from wagtail.admin.views import generic
|
|
19
|
-
from wagtail.admin.views.reports import ReportView
|
|
20
20
|
from wagtail.admin.widgets.button import Button
|
|
21
21
|
from wagtail.contrib.redirects import models
|
|
22
22
|
from wagtail.contrib.redirects.filters import RedirectsReportFilterSet
|
|
@@ -45,12 +45,12 @@ class RedirectTargetColumn(Column):
|
|
|
45
45
|
url_name = "wagtailadmin_pages:edit"
|
|
46
46
|
|
|
47
47
|
def get_value(self, instance):
|
|
48
|
-
if instance.
|
|
48
|
+
if instance.redirect_page_id:
|
|
49
49
|
return instance.redirect_page.get_admin_display_title()
|
|
50
50
|
return instance.redirect_link
|
|
51
51
|
|
|
52
52
|
def get_url(self, instance):
|
|
53
|
-
if instance.
|
|
53
|
+
if instance.redirect_page_id:
|
|
54
54
|
return reverse(self.url_name, args=[instance.redirect_page_id])
|
|
55
55
|
return None
|
|
56
56
|
|
|
@@ -105,71 +105,54 @@ class IndexView(generic.IndexView):
|
|
|
105
105
|
primary=lambda r: r.is_permanent,
|
|
106
106
|
),
|
|
107
107
|
]
|
|
108
|
+
filterset_class = RedirectsReportFilterSet
|
|
109
|
+
list_export = [
|
|
110
|
+
"old_path",
|
|
111
|
+
"link",
|
|
112
|
+
"get_is_permanent_display",
|
|
113
|
+
"site",
|
|
114
|
+
]
|
|
115
|
+
export_headings = {
|
|
116
|
+
"old_path": _("From"),
|
|
117
|
+
"site": _("Site"),
|
|
118
|
+
"link": _("To"),
|
|
119
|
+
"get_is_permanent_display": _("Type"),
|
|
120
|
+
}
|
|
108
121
|
|
|
109
122
|
def get_base_queryset(self):
|
|
110
123
|
return super().get_base_queryset().select_related("redirect_page", "site")
|
|
111
124
|
|
|
112
125
|
@cached_property
|
|
113
|
-
def header_more_buttons(self):
|
|
114
|
-
|
|
126
|
+
def header_more_buttons(self) -> List[Button]:
|
|
127
|
+
buttons = super().header_more_buttons.copy()
|
|
128
|
+
buttons.append(
|
|
115
129
|
Button(
|
|
116
130
|
_("Import redirects"),
|
|
117
131
|
url=reverse("wagtailredirects:start_import"),
|
|
118
132
|
icon_name="doc-full-inverse",
|
|
119
|
-
priority=
|
|
120
|
-
)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
url=reverse("wagtailredirects:report"),
|
|
124
|
-
icon_name="download",
|
|
125
|
-
priority=100,
|
|
126
|
-
),
|
|
127
|
-
]
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
@permission_checker.require("change")
|
|
131
|
-
def edit(request, redirect_id):
|
|
132
|
-
theredirect = get_object_or_404(models.Redirect, id=redirect_id)
|
|
133
|
+
priority=50,
|
|
134
|
+
)
|
|
135
|
+
)
|
|
136
|
+
return buttons
|
|
133
137
|
|
|
134
|
-
if not permission_policy.user_has_permission_for_instance(
|
|
135
|
-
request.user, "change", theredirect
|
|
136
|
-
):
|
|
137
|
-
raise PermissionDenied
|
|
138
138
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
reverse("wagtailredirects:edit", args=(theredirect.id,)),
|
|
152
|
-
_("Edit"),
|
|
153
|
-
)
|
|
154
|
-
],
|
|
155
|
-
)
|
|
156
|
-
return redirect("wagtailredirects:index")
|
|
157
|
-
else:
|
|
158
|
-
messages.error(request, _("The redirect could not be saved due to errors."))
|
|
159
|
-
else:
|
|
160
|
-
form = RedirectForm(instance=theredirect)
|
|
139
|
+
class EditView(generic.EditView):
|
|
140
|
+
model = Redirect
|
|
141
|
+
form_class = RedirectForm
|
|
142
|
+
permission_policy = permission_policy
|
|
143
|
+
template_name = "wagtailredirects/edit.html"
|
|
144
|
+
index_url_name = "wagtailredirects:index"
|
|
145
|
+
edit_url_name = "wagtailredirects:edit"
|
|
146
|
+
delete_url_name = "wagtailredirects:delete"
|
|
147
|
+
pk_url_kwarg = "redirect_id"
|
|
148
|
+
error_message = gettext_lazy("The redirect could not be saved due to errors.")
|
|
149
|
+
header_icon = "redirect"
|
|
150
|
+
_show_breadcrumbs = True
|
|
161
151
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
"redirect": theredirect,
|
|
167
|
-
"form": form,
|
|
168
|
-
"user_can_delete": permission_policy.user_has_permission(
|
|
169
|
-
request.user, "delete"
|
|
170
|
-
),
|
|
171
|
-
},
|
|
172
|
-
)
|
|
152
|
+
def get_success_message(self):
|
|
153
|
+
return _("Redirect '%(redirect_title)s' updated.") % {
|
|
154
|
+
"redirect_title": self.object.title
|
|
155
|
+
}
|
|
173
156
|
|
|
174
157
|
|
|
175
158
|
@permission_checker.require("delete")
|
|
@@ -444,27 +427,3 @@ def to_readable_errors(error):
|
|
|
444
427
|
errors = [x.lstrip("* ") for x in errors]
|
|
445
428
|
errors = ", ".join(errors)
|
|
446
429
|
return errors
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
class RedirectsReportView(ReportView):
|
|
450
|
-
header_icon = "redirect"
|
|
451
|
-
title = _("Export Redirects")
|
|
452
|
-
template_name = "wagtailredirects/reports/redirects_report.html"
|
|
453
|
-
filterset_class = RedirectsReportFilterSet
|
|
454
|
-
|
|
455
|
-
list_export = [
|
|
456
|
-
"old_path",
|
|
457
|
-
"link",
|
|
458
|
-
"get_is_permanent_display",
|
|
459
|
-
"site",
|
|
460
|
-
]
|
|
461
|
-
|
|
462
|
-
export_headings = {
|
|
463
|
-
"old_path": _("From"),
|
|
464
|
-
"site": _("Site"),
|
|
465
|
-
"link": _("To"),
|
|
466
|
-
"get_is_permanent_display": _("Type"),
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
def get_queryset(self):
|
|
470
|
-
return models.Redirect.objects.all().order_by("old_path")
|
|
@@ -137,12 +137,12 @@ class RoutablePageMixin:
|
|
|
137
137
|
"""
|
|
138
138
|
This method takes a URL path and finds the view to call.
|
|
139
139
|
"""
|
|
140
|
-
|
|
140
|
+
resolver_match = self.get_resolver().resolve(path)
|
|
141
141
|
|
|
142
142
|
# Bind the method
|
|
143
|
-
|
|
143
|
+
resolver_match.func = resolver_match.func.__get__(self, type(self))
|
|
144
144
|
|
|
145
|
-
return
|
|
145
|
+
return resolver_match
|
|
146
146
|
|
|
147
147
|
def route(self, request, path_components):
|
|
148
148
|
"""
|
|
@@ -154,7 +154,9 @@ class RoutablePageMixin:
|
|
|
154
154
|
if path_components:
|
|
155
155
|
path += "/".join(path_components) + "/"
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
resolver_match = self.resolve_subpage(path)
|
|
158
|
+
request.routable_resolver_match = resolver_match
|
|
159
|
+
view, args, kwargs = resolver_match
|
|
158
160
|
return RouteResult(self, args=(view, args, kwargs))
|
|
159
161
|
except Http404:
|
|
160
162
|
pass
|
|
@@ -134,6 +134,9 @@ class TestRoutablePage(TestCase):
|
|
|
134
134
|
(context["page"], context["self"], context.get("foo")),
|
|
135
135
|
(self.routable_page, self.routable_page, None),
|
|
136
136
|
)
|
|
137
|
+
self.assertEqual(
|
|
138
|
+
context["request"].routable_resolver_match.url_name, "index_route"
|
|
139
|
+
)
|
|
137
140
|
|
|
138
141
|
def test_get_render_method_route_view(self):
|
|
139
142
|
with self.assertTemplateUsed("routablepagetests/routable_page_test.html"):
|
|
@@ -157,6 +160,14 @@ class TestRoutablePage(TestCase):
|
|
|
157
160
|
(self.routable_page, 1, "fighters"),
|
|
158
161
|
)
|
|
159
162
|
|
|
163
|
+
def test_get_render_method_route_view_with_arg(self):
|
|
164
|
+
response = self.client.get(
|
|
165
|
+
self.routable_page.url + "render-method-with-arg/foo/"
|
|
166
|
+
)
|
|
167
|
+
resolver_match = response.context_data["request"].routable_resolver_match
|
|
168
|
+
self.assertEqual(resolver_match.url_name, "render_method_test_with_arg")
|
|
169
|
+
self.assertEqual(resolver_match.kwargs, {"slug": "foo"})
|
|
170
|
+
|
|
160
171
|
def test_get_routable_page_with_overridden_index_route(self):
|
|
161
172
|
page = self.home_page.add_child(
|
|
162
173
|
instance=RoutablePageWithOverriddenIndexRouteTest(
|
|
@@ -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-
|
|
11
|
+
"POT-Creation-Date: 2024-07-19 16:26+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"
|
|
@@ -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-
|
|
11
|
+
"POT-Creation-Date: 2024-07-19 16:26+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"
|
|
@@ -44,15 +44,15 @@ msgstr ""
|
|
|
44
44
|
msgid "Settings"
|
|
45
45
|
msgstr ""
|
|
46
46
|
|
|
47
|
-
#: views.py:
|
|
47
|
+
#: views.py:62
|
|
48
48
|
msgid "This setting could not be opened because there is no site defined."
|
|
49
49
|
msgstr ""
|
|
50
50
|
|
|
51
|
-
#: views.py:
|
|
51
|
+
#: views.py:84
|
|
52
52
|
msgid "The setting could not be saved due to errors."
|
|
53
53
|
msgstr ""
|
|
54
54
|
|
|
55
|
-
#: views.py:
|
|
55
|
+
#: views.py:152
|
|
56
56
|
#, python-format
|
|
57
57
|
msgid "%(setting_type)s updated."
|
|
58
58
|
msgstr ""
|
|
@@ -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-
|
|
11
|
+
"POT-Creation-Date: 2024-07-19 16:26+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"
|
|
@@ -54,6 +54,10 @@ msgid_plural "Translate the parent pages."
|
|
|
54
54
|
msgstr[0] ""
|
|
55
55
|
msgstr[1] ""
|
|
56
56
|
|
|
57
|
+
#: models.py:21
|
|
58
|
+
msgid "Can submit translations"
|
|
59
|
+
msgstr ""
|
|
60
|
+
|
|
57
61
|
#: templates/simple_translation/admin/submit_translation.html:26
|
|
58
62
|
msgid "Submit"
|
|
59
63
|
msgstr ""
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from django.conf import settings
|
|
2
2
|
from django.db.models import Model
|
|
3
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
4
|
|
|
4
5
|
from wagtail import hooks
|
|
5
6
|
from wagtail.models import Locale
|
|
@@ -17,7 +18,7 @@ class SimpleTranslation(Model):
|
|
|
17
18
|
class Meta:
|
|
18
19
|
default_permissions = []
|
|
19
20
|
permissions = [
|
|
20
|
-
("submit_translation", "Can submit translations"),
|
|
21
|
+
("submit_translation", _("Can submit translations")),
|
|
21
22
|
]
|
|
22
23
|
|
|
23
24
|
|
|
@@ -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-
|
|
11
|
+
"POT-Creation-Date: 2024-07-19 16:26+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"
|
|
@@ -34,26 +34,26 @@ msgstr ""
|
|
|
34
34
|
msgid "Delete image"
|
|
35
35
|
msgstr ""
|
|
36
36
|
|
|
37
|
-
#: views.py:
|
|
37
|
+
#: views.py:113 wagtail_hooks.py:20
|
|
38
38
|
msgid "Styleguide"
|
|
39
39
|
msgstr ""
|
|
40
40
|
|
|
41
|
-
#: views.py:
|
|
41
|
+
#: views.py:121
|
|
42
42
|
msgid "Success message"
|
|
43
43
|
msgstr ""
|
|
44
44
|
|
|
45
|
-
#: views.py:
|
|
45
|
+
#: views.py:123 views.py:131 views.py:139
|
|
46
46
|
msgid "View live"
|
|
47
47
|
msgstr ""
|
|
48
48
|
|
|
49
|
-
#: views.py:
|
|
49
|
+
#: views.py:124 views.py:132 views.py:140
|
|
50
50
|
msgid "Edit"
|
|
51
51
|
msgstr ""
|
|
52
52
|
|
|
53
|
-
#: views.py:
|
|
53
|
+
#: views.py:129
|
|
54
54
|
msgid "Warning message"
|
|
55
55
|
msgstr ""
|
|
56
56
|
|
|
57
|
-
#: views.py:
|
|
57
|
+
#: views.py:137
|
|
58
58
|
msgid "Error message"
|
|
59
59
|
msgstr ""
|
|
@@ -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-
|
|
11
|
+
"POT-Creation-Date: 2024-07-19 16:26+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"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var e,t={6865:(e,t,
|
|
1
|
+
(()=>{"use strict";var e,t={6865:(e,t,n)=>{var a=n(1669),l=n.n(a),i=n(4188);const o={contenteditable:"true","plaintext-only":"true",tabindex:"0"};function r(e,t){const n=e+"-handsontable-container";var a=e+"-handsontable-header",r=e+"-handsontable-col-header",s=e+"-table-header-choice";const d=e+"-handsontable-col-caption",c=l()("#"+e);var h=l()("#"+a),p=l()("#"+r),f=l()("#"+s);const u=l()("#"+d),b={};let g=null,v=null,w=!1;const m=l()("#"+e).parent(),_=function(){let e=0;return m.find(".htCore").each((function(){e+=l()(this).height()})),e+m.find("[data-field]").first().height()},y=[`#${n}`,".wtHider",".wtHolder"],$=function(t){const n=l()("#"+e);l().each(y,(function(){n.closest("[data-field]").find(this).height(t)}))};try{v=JSON.parse(c.val())}catch(e){}null!==v&&((0,i.$)(v,"table_caption")&&u.prop("value",v.table_caption),(0,i.$)(v,"table_header_choice")&&f.prop("value",v.table_header_choice)),(0,i.$)(t,"width")&&(0,i.$)(t,"height")||l()(window).on("resize",(()=>{var e;g.updateSettings({width:l()(".w-field--table_input").closest(".w-panel").width(),height:_()}),e="100%",l().each(y,(function(){l()(this).width(e)})),l()(".w-field--table_input").width(e)}));const C=function(){const e=[],t=[];g.getCellsMeta().forEach((t=>{let n,a;(0,i.$)(t,"className")&&(n=t.className),(0,i.$)(t,"hidden")&&(a=!0),(void 0!==n||a)&&e.push({row:t.row,col:t.col,className:n,hidden:a})})),g.getPlugin("mergeCells").isEnabled()&&g.getPlugin("mergeCells").mergedCellsCollection.mergedCells.forEach((e=>{t.push({row:e.row,col:e.col,rowspan:e.rowspan,colspan:e.colspan})})),c.val(JSON.stringify({data:g.getData(),cell:e,mergeCells:t,first_row_is_table_header:h.val(),first_col_is_header:p.val(),table_header_choice:f.val(),table_caption:u.val()}))},O=function(e,t){$(_()),C(),l()((()=>{l()(m).find("td, th").attr(o)}))};f.on("change",(()=>{C()})),u.on("change",(()=>{C()}));const S={afterChange:function(e,t){w&&"loadData"!==t&&"MergeCells"!==t&&C()},afterCreateCol:O,afterCreateRow:O,afterRemoveCol:O,afterRemoveRow:O,afterSetCellMeta:function(e,t,n,a){w&&"className"===n&&C()},afterMergeCells:function(e,t,n){w&&C()},afterUnmergeCells:function(e,t){w&&C()},afterInit:function(){w=!0}};null!==v&&((0,i.$)(v,"data")&&(S.data=v.data),(0,i.$)(v,"cell")&&(S.cell=v.cell)),Object.keys(S).forEach((e=>{b[e]=S[e]})),Object.keys(t).forEach((e=>{b[e]=t[e]})),(0,i.$)(b,"mergeCells")&&!0===b.mergeCells&&null!==v&&(0,i.$)(v,"mergeCells")&&(b.mergeCells=v.mergeCells),g=new Handsontable(document.getElementById(n),b),window.addEventListener("load",(()=>{g.render(),$(_()),m.find("td, th").attr(o),window.dispatchEvent(new Event("resize"))}))}window.initTable=r,window.telepath.register("wagtail.widgets.TableInput",class{constructor(e,t){this.options=e,this.strings=t}render(e,t,n,a){const i=document.createElement("div");i.innerHTML=`\n <div class="w-field__wrapper" data-field-wrapper>\n <label class="w-field__label" for="${n}-table-header-choice">${this.strings["Table headers"]}</label>\n <select id="${n}-table-header-choice" name="table-header-choice">\n <option value="">Select a header option</option>\n <option value="row">\n ${this.strings["Display the first row as a header"]}\n </option>\n <option value="column">\n ${this.strings["Display the first column as a header"]}\n </option>\n <option value="both">\n ${this.strings["Display the first row AND first column as headers"]}\n </option>\n <option value="neither">\n ${this.strings["No headers"]}\n </option>\n </select>\n <p class="help">${this.strings["Which cells should be displayed as headers?"]}</p>\n </div>\n <div class="w-field__wrapper" data-field-wrapper>\n <label class="w-field__label" for="${n}-handsontable-col-caption">${this.strings["Table caption"]}</label>\n <div class="w-field w-field--char_field w-field--text_input" data-field>\n <div class="w-field__help" id="${n}-handsontable-col-caption-helptext" data-field-help>\n <div class="help">${this.strings["A heading that identifies the overall topic of the table, and is useful for screen reader users."]}</div>\n </div>\n <div class="w-field__input" data-field-input>\n <input type="text" id="${n}-handsontable-col-caption" name="handsontable-col-caption" aria-describedby="${n}-handsontable-col-caption-helptext" />\n </div>\n </div>\n </div>\n <div id="${n}-handsontable-container"></div>\n <input type="hidden" name="${t}" id="${n}" placeholder="${this.strings.Table}">\n `,l()((()=>{const e=document.getElementById(`${n}-handsontable-container`);l()(e).find("td, th").attr(o)})),e.replaceWith(i);const s=i.querySelector(`input[name="${t}"]`),d=this.options,c={getValue:()=>JSON.parse(s.value),getState:()=>JSON.parse(s.value),setState(e){s.value=JSON.stringify(e),r(n,d)},focus(){}};return c.setState(a),c}})},1669:e=>{e.exports=jQuery}},n={};function a(e){var l=n[e];if(void 0!==l)return l.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,a),i.exports}a.m=t,e=[],a.O=(t,n,l,i)=>{if(!n){var o=1/0;for(c=0;c<e.length;c++){for(var[n,l,i]=e[c],r=!0,s=0;s<n.length;s++)(!1&i||o>=i)&&Object.keys(a.O).every((e=>a.O[e](n[s])))?n.splice(s--,1):(r=!1,i<o&&(o=i));if(r){e.splice(c--,1);var d=l();void 0!==d&&(t=d)}}return t}i=i||0;for(var c=e.length;c>0&&e[c-1][2]>i;c--)e[c]=e[c-1];e[c]=[n,l,i]},a.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return a.d(t,{a:t}),t},a.d=(e,t)=>{for(var n in t)a.o(t,n)&&!a.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),a.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.j=853,(()=>{var e={853:0};a.O.j=t=>0===e[t];var t=(t,n)=>{var l,i,[o,r,s]=n,d=0;if(o.some((t=>0!==e[t]))){for(l in r)a.o(r,l)&&(a.m[l]=r[l]);if(s)var c=s(a)}for(t&&t(n);d<o.length;d++)i=o[d],a.o(e,i)&&e[i]&&e[i][0](),e[i]=0;return a.O(c)},n=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];n.forEach(t.bind(null,0)),n.push=t.bind(null,n.push.bind(n))})();var l=a.O(void 0,[321],(()=>a(6865)));l=a.O(l)})();
|
|
@@ -87,6 +87,14 @@ class BaseTypedTableBlock(Block):
|
|
|
87
87
|
block.set_name(name)
|
|
88
88
|
self.child_blocks[name] = block
|
|
89
89
|
|
|
90
|
+
@classmethod
|
|
91
|
+
def construct_from_lookup(cls, lookup, child_blocks, **kwargs):
|
|
92
|
+
if child_blocks:
|
|
93
|
+
child_blocks = [
|
|
94
|
+
(name, lookup.get_block(index)) for name, index in child_blocks
|
|
95
|
+
]
|
|
96
|
+
return cls(child_blocks, **kwargs)
|
|
97
|
+
|
|
90
98
|
def value_from_datadict(self, data, files, prefix):
|
|
91
99
|
caption = data["%s-caption" % prefix]
|
|
92
100
|
|
|
@@ -259,6 +267,17 @@ class BaseTypedTableBlock(Block):
|
|
|
259
267
|
kwargs = self._constructor_kwargs
|
|
260
268
|
return (path, args, kwargs)
|
|
261
269
|
|
|
270
|
+
def deconstruct_with_lookup(self, lookup):
|
|
271
|
+
path = "wagtail.contrib.typed_table_block.blocks.TypedTableBlock"
|
|
272
|
+
args = [
|
|
273
|
+
[
|
|
274
|
+
(name, lookup.add_block(block))
|
|
275
|
+
for name, block in self.child_blocks.items()
|
|
276
|
+
]
|
|
277
|
+
]
|
|
278
|
+
kwargs = self._constructor_kwargs
|
|
279
|
+
return (path, args, kwargs)
|
|
280
|
+
|
|
262
281
|
def check(self, **kwargs):
|
|
263
282
|
errors = super().check(**kwargs)
|
|
264
283
|
for name, child_block in self.child_blocks.items():
|
|
@@ -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-
|
|
11
|
+
"POT-Creation-Date: 2024-07-19 16:26+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"
|
|
@@ -18,40 +18,40 @@ msgstr ""
|
|
|
18
18
|
"Content-Transfer-Encoding: 8bit\n"
|
|
19
19
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
|
20
20
|
|
|
21
|
-
#: blocks.py:
|
|
21
|
+
#: blocks.py:313
|
|
22
22
|
msgid "Caption"
|
|
23
23
|
msgstr ""
|
|
24
24
|
|
|
25
|
-
#: blocks.py:
|
|
25
|
+
#: blocks.py:315
|
|
26
26
|
msgid ""
|
|
27
27
|
"A heading that identifies the overall topic of the table, and is useful for "
|
|
28
28
|
"screen reader users."
|
|
29
29
|
msgstr ""
|
|
30
30
|
|
|
31
|
-
#: blocks.py:
|
|
31
|
+
#: blocks.py:317
|
|
32
32
|
msgid "Add column"
|
|
33
33
|
msgstr ""
|
|
34
34
|
|
|
35
|
-
#: blocks.py:
|
|
35
|
+
#: blocks.py:318
|
|
36
36
|
msgid "Add row"
|
|
37
37
|
msgstr ""
|
|
38
38
|
|
|
39
|
-
#: blocks.py:
|
|
39
|
+
#: blocks.py:319
|
|
40
40
|
msgid "Column heading"
|
|
41
41
|
msgstr ""
|
|
42
42
|
|
|
43
|
-
#: blocks.py:
|
|
43
|
+
#: blocks.py:320
|
|
44
44
|
msgid "Insert column"
|
|
45
45
|
msgstr ""
|
|
46
46
|
|
|
47
|
-
#: blocks.py:
|
|
47
|
+
#: blocks.py:321
|
|
48
48
|
msgid "Delete column"
|
|
49
49
|
msgstr ""
|
|
50
50
|
|
|
51
|
-
#: blocks.py:
|
|
51
|
+
#: blocks.py:322
|
|
52
52
|
msgid "Insert row"
|
|
53
53
|
msgstr ""
|
|
54
54
|
|
|
55
|
-
#: blocks.py:
|
|
55
|
+
#: blocks.py:323
|
|
56
56
|
msgid "Delete row"
|
|
57
57
|
msgstr ""
|
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{"use strict";var t,e={7595:(t,e,n)=>{var i=n(4327),o=n(9675),s=n(4545);class l{constructor(t,e,n,o,s){this.blockDef=t,this.type=t.name,this.caption="",this.columns=[],this.rows=[],this.columnCountIncludingDeleted=0,this.rowCountIncludingDeleted=0,this.prefix=n,this.childBlockDefsByName={},this.blockDef.childBlockDefs.forEach((t=>{this.childBlockDefsByName[t.name]=t}));const l=this.blockDef.meta.strings,a=`${(0,i.Z)(n)}-caption`,d=$(`\n <div class="typed-table-block ${(0,i.Z)(this.blockDef.meta.classname||"")}">\n <div class="w-field__wrapper" data-field-wrapper>\n <label class="w-field__label" for="${a}">\n ${l.CAPTION}\n </label>\n <div class="w-field w-field--char_field w-field--text_input" data-field>\n <div class="w-field__help" data-field-help>\n <div class="help">\n ${l.CAPTION_HELP_TEXT}\n </div>\n </div>\n <div class="w-field__input" data-field-input>\n <input type="text" id="${a}" name="${a}" value="" />\n <span></span>\n </div>\n </div>\n </div>\n <input type="hidden" name="${(0,i.Z)(n)}-column-count" data-column-count value="0">\n <input type="hidden" name="${(0,i.Z)(n)}-row-count" data-row-count value="0">\n <div data-deleted-fields></div>\n <div class="typed-table-block__wrapper">\n <table>\n <thead>\n <tr>\n <th></th>\n <th class="control-cell">\n <button type="button" class="button button-small button-secondary append-column" data-append-column>\n ${(0,i.Z)(l.ADD_COLUMN)}\n </button>\n </th>\n </tr>\n </thead>\n <tbody>\n </tbody>\n <tfoot>\n <tr>\n <td class="control-cell">\n <button\n type="button"\n class="button button-small button-secondary button--icon text-replace prepend-row"\n data-add-row\n aria-label="${(0,i.Z)(l.ADD_ROW)}"\n title="${(0,i.Z)(l.ADD_ROW)}"\n >\n <svg class="icon icon-plus icon" aria-hidden="true">\n <use href="#icon-plus"></use>\n </svg>\n </button></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n `);$(e).replaceWith(d),this.container=d,this.captionInput=d.find(`#${a}`).get(0),this.thead=d.find("table > thead").get(0),this.tbody=d.find("table > tbody").get(0),this.columnCountInput=d.find("input[data-column-count]").get(0),this.rowCountInput=d.find("input[data-row-count]").get(0),this.deletedFieldsContainer=d.find("[data-deleted-fields]").get(0),this.appendColumnButton=d.find("button[data-append-column]"),this.addRowButton=d.find("button[data-add-row]"),this.addRowButton.hide(),this.blockDef.meta.helpText&&d.append(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `),this.addColumnCallback=null,this.addColumnMenu=$('<ul class="add-column-menu"></ul>'),this.blockDef.childBlockDefs.forEach((t=>{const e=$('<button type="button" class="button button-small"></button>').text(t.meta.label);e.on("click",(()=>{this.addColumnCallback&&this.addColumnCallback(t),this.hideAddColumnMenu()}));const n=$("<li></li>").append(e);this.addColumnMenu.append(n)})),this.addColumnMenuBaseElement=null,this.appendColumnButton.on("click",(()=>{this.toggleAddColumnMenu(this.appendColumnButton,(t=>{this.insertColumn(this.columns.length,t,{addInitialRow:!0})}))})),this.addRowButton.on("click",(()=>{this.insertRow(this.rows.length)})),this.setState(o),s&&this.setError(s)}showAddColumnMenu(t,e){this.addColumnMenuBaseElement=t,t.after(this.addColumnMenu),this.addColumnMenu.show(),this.addColumnCallback=e}hideAddColumnMenu(){this.addColumnMenu.hide(),this.addColumnMenuBaseElement=null}toggleAddColumnMenu(t,e){this.addColumnMenuBaseElement===t?this.hideAddColumnMenu():this.showAddColumnMenu(t,e)}clear(){this.setCaption(""),this.columns=[],this.rows=[],this.columnCountIncludingDeleted=0,this.columnCountInput.value=0,this.rowCountIncludingDeleted=0,this.rowCountInput.value=0,this.deletedFieldsContainer.replaceChildren();const t=this.thead.children[0];t.replaceChildren(t.firstElementChild,t.lastElementChild),this.appendColumnButton.text(this.blockDef.meta.strings.ADD_COLUMN).removeClass("button--icon text-replace white").removeAttr("aria-label").removeAttr("title"),this.tbody.replaceChildren(),this.addRowButton.hide()}setCaption(t){this.caption=t,this.captionInput.value=t}insertColumn(t,e,n){const s={blockDef:e,position:t,id:this.columnCountIncludingDeleted};this.columnCountIncludingDeleted+=1,(0,o.y)(t,this.columns.length).forEach((t=>{this.columns[t].position+=1,this.columns[t].positionInput.value=this.columns[t].position})),this.columns.splice(t,0,s),this.columnCountInput.value=this.columnCountIncludingDeleted;const l=this.thead.children[0],a=l.children,d=document.createElement("th");l.insertBefore(d,a[t+1]),s.typeInput=document.createElement("input"),s.typeInput.type="hidden",s.typeInput.name=this.prefix+"-column-"+s.id+"-type",s.typeInput.value=e.name,d.appendChild(s.typeInput),s.positionInput=document.createElement("input"),s.positionInput.type="hidden",s.positionInput.name=this.prefix+"-column-"+s.id+"-order",s.positionInput.value=t,d.appendChild(s.positionInput),s.deletedInput=document.createElement("input"),s.deletedInput.type="hidden",s.deletedInput.name=this.prefix+"-column-"+s.id+"-deleted",s.deletedInput.value="",this.deletedFieldsContainer.appendChild(s.deletedInput);const u=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace prepend-column"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.INSERT_COLUMN)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.INSERT_COLUMN)}">\n <svg class="icon icon-plus icon" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>`);$(d).append(u),u.on("click",(()=>{this.toggleAddColumnMenu(u,(t=>{this.insertColumn(s.position,t,{addInitialRow:!0})}))})),s.headingInput=document.createElement("input"),s.headingInput.type="text",s.headingInput.name=this.prefix+"-column-"+s.id+"-heading",s.headingInput.className="column-heading",s.headingInput.placeholder=this.blockDef.meta.strings.COLUMN_HEADING,d.appendChild(s.headingInput);const c=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace no delete-column"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.DELETE_COLUMN)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.DELETE_COLUMN)}">\n <svg class="icon icon-bin icon" aria-hidden="true"><use href="#icon-bin"></use></svg>\n </button>`);$(d).append(c),c.on("click",(()=>{this.deleteColumn(s.position)}));const r=this.blockDef.childBlockDefaultStates[e.name];return Array.from(this.tbody.children).forEach(((e,n)=>{const i=this.rows[n],o=e.children,l=document.createElement("td");e.insertBefore(l,o[t+1]);const a=this.initCell(l,s,i,r);i.blocks.splice(t,0,a)})),this.addRowButton.show(),this.appendColumnButton.html('<svg class="icon icon-plus icon" aria-hidden="true"><use href="#icon-plus"></use></svg>').addClass("button--icon text-replace white").attr("aria-label",this.blockDef.meta.strings.ADD_COLUMN).addClass("button--icon text-replace white").attr("aria-label",this.blockDef.meta.strings.ADD_COLUMN).attr("title",this.blockDef.meta.strings.ADD_COLUMN),n&&n.addInitialRow&&0===this.tbody.children.length&&this.insertRow(0),s}deleteColumn(t){this.columns[t].deletedInput.value="1";const e=this.thead.children[0],n=e.children;e.removeChild(n[t+1]),Array.from(this.tbody.children).forEach(((e,n)=>{const i=e.children;e.removeChild(i[t+1]),this.rows[n].blocks.splice(t,1)})),this.columns.splice(t,1),(0,o.y)(t,this.columns.length).forEach((t=>{this.columns[t].position-=1,this.columns[t].positionInput.value=this.columns[t].position})),0===this.columns.length&&this.clear()}insertRow(t,e){const n=document.createElement("tr"),s={blocks:[],position:t,id:this.rowCountIncludingDeleted};if(t<this.rows.length){const e=this.tbody.children[t];this.tbody.insertBefore(n,e)}else this.tbody.appendChild(n);this.rows.splice(t,0,s),this.rowCountIncludingDeleted+=1,this.rowCountInput.value=this.rowCountIncludingDeleted;const l=document.createElement("td");l.className="control-cell",n.appendChild(l);const a=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace prepend-row"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.INSERT_ROW)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.INSERT_ROW)}">\n <svg class="icon icon-plus icon" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>`);$(l).append(a),a.on("click",(()=>{this.insertRow(s.position)})),this.columns.forEach(((t,i)=>{let o;o=e?e[i]:this.blockDef.childBlockDefaultStates[t.blockDef.name];const l=document.createElement("td");n.appendChild(l),s.blocks[i]=this.initCell(l,t,s,o)}));const d=document.createElement("td");d.className="control-cell",n.appendChild(d),s.positionInput=document.createElement("input"),s.positionInput.type="hidden",s.positionInput.name=this.prefix+"-row-"+s.id+"-order",s.positionInput.value=s.position,d.appendChild(s.positionInput);const u=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace no delete-row"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.DELETE_ROW)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.DELETE_ROW)}">\n <svg class="icon icon-bin icon" aria-hidden="true"><use href="#icon-bin"></use></svg>\n </button>`);return $(d).append(u),u.on("click",(()=>{this.deleteRow(s.position)})),s.deletedInput=document.createElement("input"),s.deletedInput.type="hidden",s.deletedInput.name=this.prefix+"-row-"+s.id+"-deleted",s.deletedInput.value="",this.deletedFieldsContainer.appendChild(s.deletedInput),(0,o.y)(t+1,this.rows.length).forEach((t=>{this.rows[t].position+=1,this.rows[t].positionInput.value=this.rows[t].position})),s}deleteRow(t){this.rows[t].deletedInput.value="1";const e=this.tbody.children[t];this.tbody.removeChild(e),this.rows.splice(t,1),(0,o.y)(t,this.rows.length).forEach((t=>{this.rows[t].position-=1,this.rows[t].positionInput.value=this.rows[t].position}))}initCell(t,e,n,i){const o=document.createElement("div");t.appendChild(o);const s=this.prefix+"-cell-"+n.id+"-"+e.id;return e.blockDef.render(o,s,i,null)}setState(t){this.clear(),t&&(t.columns.forEach(((t,e)=>{const n=this.childBlockDefsByName[t.type];this.insertColumn(e,n).headingInput.value=t.heading})),t.rows.forEach(((t,e)=>{this.insertRow(e,t.values)})),this.setCaption(t.caption))}setError(t){if(!t)return;const e=this.container[0];if((0,s.$)(e),t.messages&&(0,s.U)(e,t.messages),t.blockErrors)for(const[e,n]of Object.entries(t.blockErrors))for(const[t,i]of Object.entries(n))this.rows[e].blocks[t].setError(i)}getState(){return{columns:this.getColumnStates(),rows:this.rows.map((t=>({values:t.blocks.map((t=>t.getState()))}))),caption:this.caption}}getDuplicatedState(){return{columns:this.getColumnStates(),rows:this.rows.map((t=>({values:t.blocks.map((t=>void 0===t.getDuplicatedState?t.getState():t.getDuplicatedState()))})))}}getValue(){return{columns:this.getColumnStates(),rows:this.rows.map((t=>({values:t.blocks.map((t=>t.getValue()))}))),caption:this.caption}}getColumnStates(){return this.columns.map((t=>({type:t.blockDef.name,heading:t.headingInput.value})))}getTextLabel(t){const e=t&&t.maxLength;let n="";for(const t of this.rows)for(const i of t.blocks)if(i.getTextLabel){const t=i.getTextLabel({maxLength:e});if(t)if(n){const i=n+", "+t;if(e&&i.length>e-1)return n.endsWith("…")||(n+="…"),n;n=i}else n=t}return n}focus(t){this.columns.length?this.rows.length?this.rows[0].blocks[0].focus(t):this.addRowButton.focus():this.appendColumnButton.focus()}}window.telepath.register("wagtail.contrib.typed_table_block.blocks.TypedTableBlock",class{constructor(t,e,n,i){this.name=t,this.childBlockDefs=e,this.childBlockDefaultStates=n,this.meta=i}render(t,e,n,i){return new l(this,t,e,n,i)}})}},n={};function i(t){var o=n[t];if(void 0!==o)return o.exports;var s=n[t]={id:t,loaded:!1,exports:{}};return e[t].call(s.exports,s,s.exports,i),s.loaded=!0,s.exports}i.m=e,t=[],i.O=(e,n,o,s)=>{if(!n){var l=1/0;for(c=0;c<t.length;c++){for(var[n,o,s]=t[c],a=!0,d=0;d<n.length;d++)(!1&s||l>=s)&&Object.keys(i.O).every((t=>i.O[t](n[d])))?n.splice(d--,1):(a=!1,s<l&&(l=s));if(a){t.splice(c--,1);var u=o();void 0!==u&&(e=u)}}return e}s=s||0;for(var c=t.length;c>0&&t[c-1][2]>s;c--)t[c]=t[c-1];t[c]=[n,o,s]},i.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.nmd=t=>(t.paths=[],t.children||(t.children=[]),t),i.j=702,(()=>{var t={702:0};i.O.j=e=>0===t[e];var e=(e,n)=>{var o,s,[l,a,d]=n,u=0;if(l.some((e=>0!==t[e]))){for(o in a)i.o(a,o)&&(i.m[o]=a[o]);if(d)var c=d(i)}for(e&&e(n);u<l.length;u++)s=l[u],i.o(t,s)&&t[s]&&t[s][0](),t[s]=0;return i.O(c)},n=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];n.forEach(e.bind(null,0)),n.push=e.bind(null,n.push.bind(n))})();var o=i.O(void 0,[321],(()=>i(7595)));o=i.O(o)})();
|
|
1
|
+
(()=>{"use strict";var t,e={7595:(t,e,n)=>{var i=n(4327),o=n(9675),s=n(4545);class l{constructor(t,e,n,o,s){this.blockDef=t,this.type=t.name,this.caption="",this.columns=[],this.rows=[],this.columnCountIncludingDeleted=0,this.rowCountIncludingDeleted=0,this.prefix=n,this.childBlockDefsByName={},this.blockDef.childBlockDefs.forEach((t=>{this.childBlockDefsByName[t.name]=t}));const l=this.blockDef.meta.strings,a=`${(0,i.Z)(n)}-caption`,d=$(`\n <div class="typed-table-block ${(0,i.Z)(this.blockDef.meta.classname||"")}">\n <div class="w-field__wrapper" data-field-wrapper>\n <label class="w-field__label" for="${a}">\n ${l.CAPTION}\n </label>\n <div class="w-field w-field--char_field w-field--text_input" data-field>\n <div class="w-field__help" data-field-help>\n <div class="help">\n ${l.CAPTION_HELP_TEXT}\n </div>\n </div>\n <div class="w-field__input" data-field-input>\n <input type="text" id="${a}" name="${a}" value="" />\n <span></span>\n </div>\n </div>\n </div>\n <input type="hidden" name="${(0,i.Z)(n)}-column-count" data-column-count value="0">\n <input type="hidden" name="${(0,i.Z)(n)}-row-count" data-row-count value="0">\n <div data-deleted-fields></div>\n <div class="typed-table-block__wrapper">\n <table>\n <thead>\n <tr>\n <th></th>\n <th class="control-cell">\n <button type="button" class="button button-small button-secondary append-column" data-append-column>\n ${(0,i.Z)(l.ADD_COLUMN)}\n </button>\n </th>\n </tr>\n </thead>\n <tbody>\n </tbody>\n <tfoot>\n <tr>\n <td class="control-cell">\n <button\n type="button"\n class="button button-small button-secondary button--icon text-replace prepend-row"\n data-add-row\n aria-label="${(0,i.Z)(l.ADD_ROW)}"\n title="${(0,i.Z)(l.ADD_ROW)}"\n >\n <svg class="icon icon-plus icon" aria-hidden="true">\n <use href="#icon-plus"></use>\n </svg>\n </button></td>\n </tr>\n </tfoot>\n </table>\n </div>\n </div>\n `);$(e).replaceWith(d),this.container=d,this.captionInput=d.find(`#${a}`).get(0),this.thead=d.find("table > thead").get(0),this.tbody=d.find("table > tbody").get(0),this.columnCountInput=d.find("input[data-column-count]").get(0),this.rowCountInput=d.find("input[data-row-count]").get(0),this.deletedFieldsContainer=d.find("[data-deleted-fields]").get(0),this.appendColumnButton=d.find("button[data-append-column]"),this.addRowButton=d.find("button[data-add-row]"),this.addRowButton.hide(),this.blockDef.meta.helpText&&d.append(`\n <div class="c-sf-help">\n <div class="help">\n ${this.blockDef.meta.helpText}\n </div>\n </div>\n `),this.addColumnCallback=null,this.addColumnMenu=$('<ul class="add-column-menu"></ul>'),this.blockDef.childBlockDefs.forEach((t=>{const e=$('<button type="button" class="button button-small"></button>').text(t.meta.label);e.on("click",(()=>{this.addColumnCallback&&this.addColumnCallback(t),this.hideAddColumnMenu()}));const n=$("<li></li>").append(e);this.addColumnMenu.append(n)})),this.addColumnMenuBaseElement=null,this.appendColumnButton.on("click",(()=>{this.toggleAddColumnMenu(this.appendColumnButton,(t=>{this.insertColumn(this.columns.length,t,{addInitialRow:!0})}))})),this.addRowButton.on("click",(()=>{this.insertRow(this.rows.length)})),this.setState(o),s&&this.setError(s)}showAddColumnMenu(t,e){this.addColumnMenuBaseElement=t,t.after(this.addColumnMenu),this.addColumnMenu.show(),this.addColumnCallback=e}hideAddColumnMenu(){this.addColumnMenu.hide(),this.addColumnMenuBaseElement=null}toggleAddColumnMenu(t,e){this.addColumnMenuBaseElement===t?this.hideAddColumnMenu():this.showAddColumnMenu(t,e)}clear(){this.setCaption(""),this.columns=[],this.rows=[],this.columnCountIncludingDeleted=0,this.columnCountInput.value=0,this.rowCountIncludingDeleted=0,this.rowCountInput.value=0,this.deletedFieldsContainer.replaceChildren();const t=this.thead.children[0];t.replaceChildren(t.firstElementChild,t.lastElementChild),this.appendColumnButton.text(this.blockDef.meta.strings.ADD_COLUMN).removeClass("button--icon text-replace white").removeAttr("aria-label").removeAttr("title"),this.tbody.replaceChildren(),this.addRowButton.hide()}setCaption(t){this.caption=t,this.captionInput.value=t}insertColumn(t,e,n){const s={blockDef:e,position:t,id:this.columnCountIncludingDeleted};this.columnCountIncludingDeleted+=1,(0,o.y)(t,this.columns.length).forEach((t=>{this.columns[t].position+=1,this.columns[t].positionInput.value=this.columns[t].position})),this.columns.splice(t,0,s),this.columnCountInput.value=this.columnCountIncludingDeleted;const l=this.thead.children[0],a=l.children,d=document.createElement("th");l.insertBefore(d,a[t+1]),s.typeInput=document.createElement("input"),s.typeInput.type="hidden",s.typeInput.name=this.prefix+"-column-"+s.id+"-type",s.typeInput.value=e.name,d.appendChild(s.typeInput),s.positionInput=document.createElement("input"),s.positionInput.type="hidden",s.positionInput.name=this.prefix+"-column-"+s.id+"-order",s.positionInput.value=t,d.appendChild(s.positionInput),s.deletedInput=document.createElement("input"),s.deletedInput.type="hidden",s.deletedInput.name=this.prefix+"-column-"+s.id+"-deleted",s.deletedInput.value="",this.deletedFieldsContainer.appendChild(s.deletedInput);const u=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace prepend-column"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.INSERT_COLUMN)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.INSERT_COLUMN)}">\n <svg class="icon icon-plus icon" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>`);$(d).append(u),u.on("click",(()=>{this.toggleAddColumnMenu(u,(t=>{this.insertColumn(s.position,t,{addInitialRow:!0})}))})),s.headingInput=document.createElement("input"),s.headingInput.type="text",s.headingInput.name=this.prefix+"-column-"+s.id+"-heading",s.headingInput.className="column-heading",s.headingInput.placeholder=this.blockDef.meta.strings.COLUMN_HEADING,d.appendChild(s.headingInput);const c=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace no delete-column"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.DELETE_COLUMN)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.DELETE_COLUMN)}">\n <svg class="icon icon-bin icon" aria-hidden="true"><use href="#icon-bin"></use></svg>\n </button>`);$(d).append(c),c.on("click",(()=>{this.deleteColumn(s.position)}));const r=this.blockDef.childBlockDefaultStates[e.name];return Array.from(this.tbody.children).forEach(((e,n)=>{const i=this.rows[n],o=e.children,l=document.createElement("td");e.insertBefore(l,o[t+1]);const a=this.initCell(l,s,i,r);i.blocks.splice(t,0,a)})),this.addRowButton.show(),this.appendColumnButton.html('<svg class="icon icon-plus icon" aria-hidden="true"><use href="#icon-plus"></use></svg>').addClass("button--icon text-replace white").attr("aria-label",this.blockDef.meta.strings.ADD_COLUMN).addClass("button--icon text-replace white").attr("aria-label",this.blockDef.meta.strings.ADD_COLUMN).attr("title",this.blockDef.meta.strings.ADD_COLUMN),n&&n.addInitialRow&&0===this.tbody.children.length&&this.insertRow(0),s}deleteColumn(t){this.columns[t].deletedInput.value="1";const e=this.thead.children[0],n=e.children;e.removeChild(n[t+1]),Array.from(this.tbody.children).forEach(((e,n)=>{const i=e.children;e.removeChild(i[t+1]),this.rows[n].blocks.splice(t,1)})),this.columns.splice(t,1),(0,o.y)(t,this.columns.length).forEach((t=>{this.columns[t].position-=1,this.columns[t].positionInput.value=this.columns[t].position})),0===this.columns.length&&this.clear()}insertRow(t,e){const n=document.createElement("tr"),s={blocks:[],position:t,id:this.rowCountIncludingDeleted};if(t<this.rows.length){const e=this.tbody.children[t];this.tbody.insertBefore(n,e)}else this.tbody.appendChild(n);this.rows.splice(t,0,s),this.rowCountIncludingDeleted+=1,this.rowCountInput.value=this.rowCountIncludingDeleted;const l=document.createElement("td");l.className="control-cell",n.appendChild(l);const a=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace prepend-row"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.INSERT_ROW)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.INSERT_ROW)}">\n <svg class="icon icon-plus icon" aria-hidden="true"><use href="#icon-plus"></use></svg>\n </button>`);$(l).append(a),a.on("click",(()=>{this.insertRow(s.position)})),this.columns.forEach(((t,i)=>{let o;o=e?e[i]:this.blockDef.childBlockDefaultStates[t.blockDef.name];const l=document.createElement("td");n.appendChild(l),s.blocks[i]=this.initCell(l,t,s,o)}));const d=document.createElement("td");d.className="control-cell",n.appendChild(d),s.positionInput=document.createElement("input"),s.positionInput.type="hidden",s.positionInput.name=this.prefix+"-row-"+s.id+"-order",s.positionInput.value=s.position,d.appendChild(s.positionInput);const u=$(`<button type="button"\n class="button button-secondary button-small button--icon text-replace no delete-row"\n aria-label="${(0,i.Z)(this.blockDef.meta.strings.DELETE_ROW)}"\n title="${(0,i.Z)(this.blockDef.meta.strings.DELETE_ROW)}">\n <svg class="icon icon-bin icon" aria-hidden="true"><use href="#icon-bin"></use></svg>\n </button>`);return $(d).append(u),u.on("click",(()=>{this.deleteRow(s.position)})),s.deletedInput=document.createElement("input"),s.deletedInput.type="hidden",s.deletedInput.name=this.prefix+"-row-"+s.id+"-deleted",s.deletedInput.value="",this.deletedFieldsContainer.appendChild(s.deletedInput),(0,o.y)(t+1,this.rows.length).forEach((t=>{this.rows[t].position+=1,this.rows[t].positionInput.value=this.rows[t].position})),s}deleteRow(t){this.rows[t].deletedInput.value="1";const e=this.tbody.children[t];this.tbody.removeChild(e),this.rows.splice(t,1),(0,o.y)(t,this.rows.length).forEach((t=>{this.rows[t].position-=1,this.rows[t].positionInput.value=this.rows[t].position}))}initCell(t,e,n,i){const o=document.createElement("div");t.appendChild(o);const s=this.prefix+"-cell-"+n.id+"-"+e.id;return e.blockDef.render(o,s,i,null)}setState(t){this.clear(),t&&(t.columns.forEach(((t,e)=>{const n=this.childBlockDefsByName[t.type];this.insertColumn(e,n).headingInput.value=t.heading})),t.rows.forEach(((t,e)=>{this.insertRow(e,t.values)})),this.setCaption(t.caption))}setError(t){if(!t)return;const e=this.container[0];if((0,s.$)(e),t.messages&&(0,s.U)(e,t.messages),t.blockErrors)for(const[e,n]of Object.entries(t.blockErrors))for(const[t,i]of Object.entries(n))this.rows[e].blocks[t].setError(i)}getState(){return{columns:this.getColumnStates(),rows:this.rows.map((t=>({values:t.blocks.map((t=>t.getState()))}))),caption:this.caption}}getDuplicatedState(){return{columns:this.getColumnStates(),rows:this.rows.map((t=>({values:t.blocks.map((t=>void 0===t.getDuplicatedState?t.getState():t.getDuplicatedState()))})))}}getValue(){return{columns:this.getColumnStates(),rows:this.rows.map((t=>({values:t.blocks.map((t=>t.getValue()))}))),caption:this.caption}}getColumnStates(){return this.columns.map((t=>({type:t.blockDef.name,heading:t.headingInput.value})))}getTextLabel(t){const e=t&&t.maxLength;let n="";for(const t of this.rows)for(const i of t.blocks)if(i.getTextLabel){const t=i.getTextLabel({maxLength:e});if(t)if(n){const i=n+", "+t;if(e&&i.length>e-1)return n.endsWith("…")||(n+="…"),n;n=i}else n=t}return n}focus(t){this.columns.length?this.rows.length?this.rows[0].blocks[0].focus(t):this.addRowButton.focus():this.appendColumnButton.focus()}}window.telepath.register("wagtail.contrib.typed_table_block.blocks.TypedTableBlock",class{constructor(t,e,n,i){this.name=t,this.childBlockDefs=e,this.childBlockDefaultStates=n,this.meta=i}render(t,e,n,i){return new l(this,t,e,n,i)}})}},n={};function i(t){var o=n[t];if(void 0!==o)return o.exports;var s=n[t]={exports:{}};return e[t](s,s.exports,i),s.exports}i.m=e,t=[],i.O=(e,n,o,s)=>{if(!n){var l=1/0;for(c=0;c<t.length;c++){for(var[n,o,s]=t[c],a=!0,d=0;d<n.length;d++)(!1&s||l>=s)&&Object.keys(i.O).every((t=>i.O[t](n[d])))?n.splice(d--,1):(a=!1,s<l&&(l=s));if(a){t.splice(c--,1);var u=o();void 0!==u&&(e=u)}}return e}s=s||0;for(var c=t.length;c>0&&t[c-1][2]>s;c--)t[c]=t[c-1];t[c]=[n,o,s]},i.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.j=702,(()=>{var t={702:0};i.O.j=e=>0===t[e];var e=(e,n)=>{var o,s,[l,a,d]=n,u=0;if(l.some((e=>0!==t[e]))){for(o in a)i.o(a,o)&&(i.m[o]=a[o]);if(d)var c=d(i)}for(e&&e(n);u<l.length;u++)s=l[u],i.o(t,s)&&t[s]&&t[s][0](),t[s]=0;return i.O(c)},n=globalThis.webpackChunkwagtail=globalThis.webpackChunkwagtail||[];n.forEach(e.bind(null,0)),n.push=e.bind(null,n.push.bind(n))})();var o=i.O(void 0,[321],(()=>i(7595)));o=i.O(o)})();
|
|
@@ -4,6 +4,7 @@ from django.test import TestCase
|
|
|
4
4
|
|
|
5
5
|
from wagtail import blocks
|
|
6
6
|
from wagtail.blocks.base import get_error_json_data
|
|
7
|
+
from wagtail.blocks.definition_lookup import BlockDefinitionLookup
|
|
7
8
|
from wagtail.blocks.struct_block import StructBlockValidationError
|
|
8
9
|
from wagtail.contrib.typed_table_block.blocks import (
|
|
9
10
|
TypedTable,
|
|
@@ -257,3 +258,40 @@ class TestTableBlock(TestCase):
|
|
|
257
258
|
"blockErrors": {1: {2: {"messages": ["This field is required."]}}},
|
|
258
259
|
},
|
|
259
260
|
)
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class TestBlockDefinitionLookup(TestCase):
|
|
264
|
+
def test_block_lookup(self):
|
|
265
|
+
lookup = BlockDefinitionLookup(
|
|
266
|
+
{
|
|
267
|
+
0: ("wagtail.blocks.CharBlock", [], {"required": True}),
|
|
268
|
+
1: (
|
|
269
|
+
"wagtail.blocks.ChoiceBlock",
|
|
270
|
+
[],
|
|
271
|
+
{
|
|
272
|
+
"choices": [
|
|
273
|
+
("be", "Belgium"),
|
|
274
|
+
("fr", "France"),
|
|
275
|
+
("nl", "Netherlands"),
|
|
276
|
+
]
|
|
277
|
+
},
|
|
278
|
+
),
|
|
279
|
+
2: (
|
|
280
|
+
"wagtail.contrib.typed_table_block.blocks.TypedTableBlock",
|
|
281
|
+
[
|
|
282
|
+
[
|
|
283
|
+
("text", 0),
|
|
284
|
+
("country", 1),
|
|
285
|
+
],
|
|
286
|
+
],
|
|
287
|
+
{},
|
|
288
|
+
),
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
struct_block = lookup.get_block(2)
|
|
292
|
+
self.assertIsInstance(struct_block, TypedTableBlock)
|
|
293
|
+
text_block = struct_block.child_blocks["text"]
|
|
294
|
+
self.assertIsInstance(text_block, blocks.CharBlock)
|
|
295
|
+
self.assertTrue(text_block.required)
|
|
296
|
+
country_block = struct_block.child_blocks["country"]
|
|
297
|
+
self.assertIsInstance(country_block, blocks.ChoiceBlock)
|
wagtail/coreutils.py
CHANGED
|
@@ -146,7 +146,7 @@ def cautious_slugify(value):
|
|
|
146
146
|
|
|
147
147
|
def safe_snake_case(value):
|
|
148
148
|
"""
|
|
149
|
-
Convert a string to ASCII similar to Django's slugify, with
|
|
149
|
+
Convert a string to ASCII similar to Django's slugify, with cautious handling of
|
|
150
150
|
non-ASCII alphanumeric characters. See `cautious_slugify`.
|
|
151
151
|
|
|
152
152
|
Any inner whitespace, hyphens or dashes will be converted to underscores and
|
wagtail/documents/__init__.py
CHANGED
|
@@ -14,7 +14,7 @@ def get_document_model_string():
|
|
|
14
14
|
def get_document_model():
|
|
15
15
|
"""
|
|
16
16
|
Get the document model from the ``WAGTAILDOCS_DOCUMENT_MODEL`` setting.
|
|
17
|
-
Defaults to the standard
|
|
17
|
+
Defaults to the standard ``wagtail.documents.models.Document`` model
|
|
18
18
|
if no custom model is defined.
|
|
19
19
|
"""
|
|
20
20
|
from django.apps import apps
|