Fix admin messages never auto-dismissing (root cause) #66
@@ -15,7 +15,6 @@ from apps.core.middleware import AdminMessageGuardMiddleware
|
|||||||
|
|
||||||
|
|
||||||
def admin_message_test_view(request):
|
def admin_message_test_view(request):
|
||||||
messages.success(request, "Page 'Test page' has been updated.")
|
|
||||||
messages.success(request, "Page 'Test page' has been updated.")
|
messages.success(request, "Page 'Test page' has been updated.")
|
||||||
messages.success(request, "Page 'Test page' has been published.")
|
messages.success(request, "Page 'Test page' has been published.")
|
||||||
return render(request, "wagtailadmin/base.html", {})
|
return render(request, "wagtailadmin/base.html", {})
|
||||||
@@ -60,24 +59,6 @@ def test_admin_message_guard_preserves_admin_messages(rf):
|
|||||||
assert remaining[0].message == "Page 'Test page' has been updated."
|
assert remaining[0].message == "Page 'Test page' has been updated."
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
|
||||||
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
|
||||||
def test_wagtail_admin_template_deduplicates_consecutive_messages(client, django_user_model):
|
|
||||||
admin = django_user_model.objects.create_superuser(
|
|
||||||
username="admin-messages",
|
|
||||||
email="admin-messages@example.com",
|
|
||||||
password="admin-pass",
|
|
||||||
)
|
|
||||||
client.force_login(admin)
|
|
||||||
|
|
||||||
response = client.get("/cms/__tests__/admin-messages/")
|
|
||||||
content = response.content.decode()
|
|
||||||
|
|
||||||
assert response.status_code == 200
|
|
||||||
assert content.count("has been updated.") == 1
|
|
||||||
assert content.count("has been published.") == 1
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||||
def test_admin_messages_have_auto_clear(client, django_user_model):
|
def test_admin_messages_have_auto_clear(client, django_user_model):
|
||||||
@@ -94,3 +75,46 @@ def test_admin_messages_have_auto_clear(client, django_user_model):
|
|||||||
|
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
assert "data-w-messages-auto-clear-value" in content
|
assert "data-w-messages-auto-clear-value" in content
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||||
|
def test_server_rendered_messages_have_auto_dismiss_script(client, django_user_model):
|
||||||
|
"""Server-rendered messages must include an inline script that removes them
|
||||||
|
after a timeout, because the w-messages Stimulus controller only auto-clears
|
||||||
|
messages added via JavaScript — not ones already in the HTML."""
|
||||||
|
admin = django_user_model.objects.create_superuser(
|
||||||
|
username="admin-dismiss",
|
||||||
|
email="admin-dismiss@example.com",
|
||||||
|
password="admin-pass",
|
||||||
|
)
|
||||||
|
client.force_login(admin)
|
||||||
|
|
||||||
|
response = client.get("/cms/__tests__/admin-messages/")
|
||||||
|
content = response.content.decode()
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
# Messages are rendered with the data-server-rendered marker
|
||||||
|
assert "data-server-rendered" in content
|
||||||
|
# The auto-dismiss script targets those markers
|
||||||
|
assert "querySelectorAll" in content
|
||||||
|
assert "[data-server-rendered]" in content
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
@override_settings(ROOT_URLCONF="apps.core.tests.test_message_handling")
|
||||||
|
def test_admin_messages_render_all_messages(client, django_user_model):
|
||||||
|
"""All messages should be rendered (no de-duplication filtering)."""
|
||||||
|
admin = django_user_model.objects.create_superuser(
|
||||||
|
username="admin-render",
|
||||||
|
email="admin-render@example.com",
|
||||||
|
password="admin-pass",
|
||||||
|
)
|
||||||
|
client.force_login(admin)
|
||||||
|
|
||||||
|
response = client.get("/cms/__tests__/admin-messages/")
|
||||||
|
content = response.content.decode()
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert "has been updated." in content
|
||||||
|
assert "has been published." in content
|
||||||
|
|||||||
@@ -8,25 +8,24 @@
|
|||||||
{% keyboard_shortcuts_dialog %}
|
{% keyboard_shortcuts_dialog %}
|
||||||
<main class="content-wrapper w-overflow-x-hidden" id="main">
|
<main class="content-wrapper w-overflow-x-hidden" id="main">
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
{# Always show messages div so it can be appended to by JS #}
|
||||||
<div class="messages" role="status" data-controller="w-messages" data-action="w-messages:add@document->w-messages#add" data-w-messages-added-class="new" data-w-messages-show-class="appear" data-w-messages-show-delay-value="100" data-w-messages-auto-clear-value="8000">
|
<div class="messages" role="status" data-controller="w-messages" data-action="w-messages:add@document->w-messages#add" data-w-messages-added-class="new" data-w-messages-show-class="appear" data-w-messages-show-delay-value="100" data-w-messages-auto-clear-value="8000">
|
||||||
<ul data-w-messages-target="container">
|
<ul data-w-messages-target="container">
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
{% message_level_tag message as level_tag %}
|
{% message_level_tag message as level_tag %}
|
||||||
{% ifchanged level_tag message.extra_tags message %}
|
<li class="{% message_tags message %}" data-server-rendered>
|
||||||
<li class="{% message_tags message %}">
|
{% if level_tag == "error" %}
|
||||||
{% if level_tag == "error" %}
|
{% icon name="warning" classname="messages-icon" %}
|
||||||
{% icon name="warning" classname="messages-icon" %}
|
{% elif message.extra_tags == "lock" %}
|
||||||
{% elif message.extra_tags == "lock" %}
|
{% icon name="lock" classname="messages-icon" %}
|
||||||
{% icon name="lock" classname="messages-icon" %}
|
{% elif message.extra_tags == "unlock" %}
|
||||||
{% elif message.extra_tags == "unlock" %}
|
{% icon name="lock-open" classname="messages-icon" %}
|
||||||
{% icon name="lock-open" classname="messages-icon" %}
|
{% else %}
|
||||||
{% else %}
|
{% icon name=level_tag classname="messages-icon" %}
|
||||||
{% icon name=level_tag classname="messages-icon" %}
|
{% endif %}
|
||||||
{% endif %}
|
{{ message }}
|
||||||
{{ message }}
|
</li>
|
||||||
</li>
|
|
||||||
{% endifchanged %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
@@ -41,6 +40,27 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{% comment %}
|
||||||
|
Wagtail's w-messages Stimulus controller only auto-clears messages
|
||||||
|
added dynamically via JavaScript (the add() method). Server-rendered
|
||||||
|
messages — the <li> elements above — have no connect() handler and
|
||||||
|
sit in the DOM forever. This script schedules their removal so they
|
||||||
|
auto-dismiss after the same timeout used for dynamic messages.
|
||||||
|
{% endcomment %}
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var items = document.querySelectorAll('[data-server-rendered]');
|
||||||
|
if (!items.length) return;
|
||||||
|
setTimeout(function () {
|
||||||
|
items.forEach(function (el) { el.remove(); });
|
||||||
|
var ul = document.querySelector('[data-w-messages-target="container"]');
|
||||||
|
if (ul && !ul.children.length) {
|
||||||
|
document.body.classList.remove('has-messages');
|
||||||
|
}
|
||||||
|
}, 8000);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
Reference in New Issue
Block a user