From 3bc4f1300eb823607772beeb5a7ac52da4bd3d7d Mon Sep 17 00:00:00 2001 From: Sli Date: Thu, 26 Mar 2026 23:48:38 +0100 Subject: [PATCH 01/41] Fix link-once and script-once not triggering when another one disappears --- club/templates/club/club_members.jinja | 4 -- .../bundled/core/components/include-index.ts | 52 +++++++++++++++++-- core/templates/core/user_preferences.jinja | 7 --- .../templates/subscription/subscription.jinja | 8 --- 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/club/templates/club/club_members.jinja b/club/templates/club/club_members.jinja index 3aa43d56..7e37b04e 100644 --- a/club/templates/club/club_members.jinja +++ b/club/templates/club/club_members.jinja @@ -1,11 +1,7 @@ {% extends "core/base.jinja" %} {% from 'core/macros.jinja' import user_profile_link, select_all_checkbox %} -{% block additional_js %} - -{% endblock %} {% block additional_css %} - {% endblock %} diff --git a/core/static/bundled/core/components/include-index.ts b/core/static/bundled/core/components/include-index.ts index c1989f4b..b50cdbc2 100644 --- a/core/static/bundled/core/components/include-index.ts +++ b/core/static/bundled/core/components/include-index.ts @@ -6,14 +6,36 @@ import { inheritHtmlElement, registerComponent } from "#core:utils/web-component **/ @registerComponent("link-once") export class LinkOnce extends inheritHtmlElement("link") { - connectedCallback() { - super.connectedCallback(false); + refresh() { + this.clearNode(); + // We get href from node.attributes instead of node.href to avoid getting the domain part const href = this.node.attributes.getNamedItem("href").nodeValue; if (document.querySelectorAll(`link[href='${href}']`).length === 0) { this.appendChild(this.node); } } + + clearNode() { + while (this.firstChild) { + this.removeChild(this.lastChild); + } + } + + connectedCallback() { + super.connectedCallback(false); + this.refresh(); + } + + disconnectedCallback() { + this.clearNode(); + + // This re-triggers link-once elements that still exists and suppressed + // themeselves once it gets removed from the page + for (const link of document.getElementsByTagName("link-once")) { + (link as LinkOnce).refresh(); + } + } } /** @@ -22,12 +44,34 @@ export class LinkOnce extends inheritHtmlElement("link") { **/ @registerComponent("script-once") export class ScriptOnce extends inheritHtmlElement("script") { - connectedCallback() { - super.connectedCallback(false); + refresh() { + this.clearNode(); + // We get src from node.attributes instead of node.src to avoid getting the domain part const src = this.node.attributes.getNamedItem("src").nodeValue; if (document.querySelectorAll(`script[src='${src}']`).length === 0) { this.appendChild(this.node); } } + + clearNode() { + while (this.firstChild) { + this.removeChild(this.lastChild); + } + } + + connectedCallback() { + super.connectedCallback(false); + this.refresh(); + } + + disconnectedCallback() { + this.clearNode(); + + // This re-triggers script-once elements that still exists and suppressed + // themeselves once it gets removed from the page + for (const link of document.getElementsByTagName("script-once")) { + (link as LinkOnce).refresh(); + } + } } diff --git a/core/templates/core/user_preferences.jinja b/core/templates/core/user_preferences.jinja index 1aed4d94..f3694ff0 100644 --- a/core/templates/core/user_preferences.jinja +++ b/core/templates/core/user_preferences.jinja @@ -1,14 +1,7 @@ {% extends "core/base.jinja" %} -{%- block additional_js -%} - -{%- endblock -%} - {%- block additional_css -%} - {# importing ajax-select-index is necessary for it to be applied after HTMX reload #} - - {%- endblock -%} {% block title %} diff --git a/subscription/templates/subscription/subscription.jinja b/subscription/templates/subscription/subscription.jinja index 9046c296..45e88e18 100644 --- a/subscription/templates/subscription/subscription.jinja +++ b/subscription/templates/subscription/subscription.jinja @@ -6,14 +6,8 @@ {% trans %}New subscription{% endtrans %} {% endblock %} -{# The following statics are bundled with our autocomplete select. - However, if one tries to swap a form by another, then the urls in script-once - and link-once disappear. - So we give them here. - If the aforementioned bug is resolved, you can remove this. #} {% block additional_js %} - +{% endblock %} - {% if club.is_active or user.is_root %} - -
  • {{ club.name }} - - {% if not club.is_active %} - ({% trans %}inactive{% endtrans %}) - {% endif %} - - {% if club.president %} - {{ club.president.user }}{% endif %} - {% if club.short_description %}

    {{ club.short_description|markdown }}

    {% endif %} - - {% endif %} - - {%- if club.children.all()|length != 0 %} - - {%- endif -%} -
  • -{%- endmacro %} +{% block additional_css %} + +{% endblock %} {% block content %} - {% if user.is_root %} -

    {% trans %}New club{% endtrans %}

    - {% endif %} - {% if club_list %} +
    +

    {% trans %}Filters{% endtrans %}

    +
    +
    +
    + + +
    +
    + {% trans %}Club state{% endtrans %} +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +

    {% trans %}Club list{% endtrans %}

    - - {% else %} - {% trans %}There is no club in this website.{% endtrans %} - {% endif %} + {% if user.has_perm("club.add_club") %} +
    + + {% trans %}New club{% endtrans %} + + {% endif %} +
    + +
    + {{ paginate_alpine("currentPage", "nbPages") }} +
    {% endblock %} diff --git a/club/views.py b/club/views.py index 9077d0d7..2a3c8f87 100644 --- a/club/views.py +++ b/club/views.py @@ -42,7 +42,7 @@ from django.utils.functional import cached_property from django.utils.timezone import now from django.utils.translation import gettext from django.utils.translation import gettext_lazy as _ -from django.views.generic import DetailView, ListView, View +from django.views.generic import DetailView, TemplateView, View from django.views.generic.detail import SingleObjectMixin from django.views.generic.edit import CreateView, DeleteView, UpdateView @@ -180,15 +180,10 @@ class ClubTabsMixin(TabedViewMixin): return tab_list -class ClubListView(ListView): +class ClubListView(TemplateView): """List the Clubs.""" - model = Club template_name = "club/club_list.jinja" - queryset = ( - Club.objects.filter(parent=None).order_by("name").prefetch_related("children") - ) - context_object_name = "club_list" class ClubView(ClubTabsMixin, DetailView): diff --git a/core/templates/core/base/navbar.jinja b/core/templates/core/base/navbar.jinja index fd1e6ddc..64ca9721 100644 --- a/core/templates/core/base/navbar.jinja +++ b/core/templates/core/base/navbar.jinja @@ -5,9 +5,8 @@