diff --git a/integreat_cms/cms/templates/_base.html b/integreat_cms/cms/templates/_base.html index 97e3b81d18..32688a47a1 100644 --- a/integreat_cms/cms/templates/_base.html +++ b/integreat_cms/cms/templates/_base.html @@ -254,6 +254,13 @@ {% translate "Admin Dashboard" %} + {% if perms.cms.view_broken_links %} + + + {% translate "Broken Links" %} + + {% endif %} {% if perms.cms.view_region %} diff --git a/integreat_cms/cms/templates/linkcheck/link_list_row.html b/integreat_cms/cms/templates/linkcheck/link_list_row.html index 256038cf54..7fbd5b7ecb 100644 --- a/integreat_cms/cms/templates/linkcheck/link_list_row.html +++ b/integreat_cms/cms/templates/linkcheck/link_list_row.html @@ -101,7 +101,11 @@ @@ -112,7 +116,11 @@
{% render_field edit_url_form.url|add_error_class:"border-red-500" type="url" form="edit-url-form" %} - {% translate "Cancel" %}
- {% translate "Valid" %} ({{ number_valid_urls }}) - {% translate "Invalid" %} ({{ number_invalid_urls }}) - {% translate "Unchecked" %} ({{ number_unchecked_urls }}) - {% translate "Ignored" %} @@ -57,7 +97,16 @@

{% if request.user.expert_mode %} {% if LINKCHECK_EMAIL_ENABLED %} - {% translate "Email links" %} @@ -66,7 +115,16 @@

{% endif %} {% if LINKCHECK_PHONE_ENABLED %} - {% translate "Phone links" %} @@ -170,16 +228,31 @@

{% if view.kwargs.url_filter == 'ignored' %} {% else %} {% endif %} diff --git a/integreat_cms/cms/urls/protected.py b/integreat_cms/cms/urls/protected.py index f5c0a19ebd..51d9470ff4 100644 --- a/integreat_cms/cms/urls/protected.py +++ b/integreat_cms/cms/urls/protected.py @@ -236,6 +236,45 @@ dashboard.AdminDashboardView.as_view(), name="admin_dashboard", ), + path( + "linkcheck/", + include( + [ + path( + "", + linkcheck.LinkcheckRedirectView.as_view(), + name="linkcheck_landing", + ), + path( + "stats", + linkcheck.LinkcheckStatsView.as_view(), + name="linkcheck_stats", + ), + path( + "/", + include( + [ + path( + "", + linkcheck.LinkcheckListView.as_view(), + name="linkcheck", + ), + path( + "/", + linkcheck.LinkcheckListView.as_view(), + name="edit_url", + ), + ] + ), + ), + path( + "search_and_replace_link", + linkcheck.LinkReplaceView.as_view(), + name="search_and_replace_link", + ), + ] + ), + ), path( "regions/", include( diff --git a/integreat_cms/cms/utils/linkcheck_utils.py b/integreat_cms/cms/utils/linkcheck_utils.py index ac33be4af6..95514420dd 100644 --- a/integreat_cms/cms/utils/linkcheck_utils.py +++ b/integreat_cms/cms/utils/linkcheck_utils.py @@ -48,22 +48,22 @@ def get_urls( if url_ids is not None: # If the results should be limited to specific ids, filter the queryset urls = urls.filter(id__in=url_ids) - if region_slug: - region = Region.objects.get(slug=region_slug) - region_links = get_region_links(region) - - # Prefetch all link objects of the requested region - urls = ( - urls.filter(links__in=region_links) - .distinct() - .prefetch_related( - Prefetch( - "links", - queryset=region_links, - to_attr="region_links", - ) + + region = Region.objects.get(slug=region_slug) if region_slug else None + region_links = get_region_links(region) + + # Prefetch all link objects of the requested region + urls = ( + urls.filter(links__in=region_links) + .distinct() + .prefetch_related( + Prefetch( + "links", + queryset=region_links, + to_attr="region_links", ) ) + ) # Filter out ignored URL types if settings.LINKCHECK_IGNORED_URL_TYPES: @@ -74,34 +74,40 @@ def get_urls( return urls -def get_region_links(region: Region) -> QuerySet: +def get_region_links(region: Region| None) -> QuerySet: """ Returns the links of translations of the given region :param region: The region :return: A query containing the relevant links """ - latest_pagetranslation_versions = Subquery( - PageTranslation.objects.filter( - page__id__in=Subquery(region.non_archived_pages.values("pk")), + if region: + latest_pagetranslation_versions = Subquery( + PageTranslation.objects.filter( + page__id__in=Subquery(region.non_archived_pages.values("pk")), + ) + .distinct("page__id", "language__id") + .values_list("pk", flat=True) ) - .distinct("page__id", "language__id") - .values_list("pk", flat=True) - ) - latest_poitranslation_versions = Subquery( - POITranslation.objects.filter(poi__region=region) - .distinct("poi__id", "language__id") - .values_list("pk", flat=True) - ) - latest_eventtranslation_versions = Subquery( - EventTranslation.objects.filter(event__region=region) - .distinct("event__id", "language__id") - .values_list("pk", flat=True) - ) - latest_imprinttranslation_versions = Subquery( - ImprintPageTranslation.objects.filter(page__region=region) - .distinct("page__id", "language__id") - .values_list("pk", flat=True) - ) + latest_poitranslation_versions = Subquery( + POITranslation.objects.filter(poi__region=region) + .distinct("poi__id", "language__id") + .values_list("pk", flat=True) + ) + latest_eventtranslation_versions = Subquery( + EventTranslation.objects.filter(event__region=region) + .distinct("event__id", "language__id") + .values_list("pk", flat=True) + ) + latest_imprinttranslation_versions = Subquery( + ImprintPageTranslation.objects.filter(page__region=region) + .distinct("page__id", "language__id") + .values_list("pk", flat=True) + ) + else: + latest_pagetranslation_versions = PageTranslation.objects.distinct("page__id", "language__id").values_list("pk", flat=True) + latest_poitranslation_versions = POITranslation.objects.distinct("poi__id", "language__id").values_list("pk", flat=True) + latest_eventtranslation_versions = EventTranslation.objects.distinct("event__id", "language__id").values_list("pk", flat=True) + latest_imprinttranslation_versions = ImprintPageTranslation.objects.distinct("page__id", "language__id").values_list("pk", flat=True) # Get all link objects of the requested region region_links = Link.objects.filter( Q(page_translation__id__in=latest_pagetranslation_versions) diff --git a/integreat_cms/cms/views/linkcheck/link_replace_view.py b/integreat_cms/cms/views/linkcheck/link_replace_view.py index b8fdcf1720..edc33f1047 100644 --- a/integreat_cms/cms/views/linkcheck/link_replace_view.py +++ b/integreat_cms/cms/views/linkcheck/link_replace_view.py @@ -83,9 +83,13 @@ def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: _("Links were replaced successfully."), ) + if request.region: + return redirect( + "linkcheck_landing", + **{ + "region_slug": request.region.slug, + }, + ) return redirect( - "linkcheck_landing", - **{ - "region_slug": request.region.slug, - }, - ) + "linkcheck_landing", + ) diff --git a/integreat_cms/cms/views/linkcheck/linkcheck_list_view.py b/integreat_cms/cms/views/linkcheck/linkcheck_list_view.py index ab2a89a480..ba39dc540b 100644 --- a/integreat_cms/cms/views/linkcheck/linkcheck_list_view.py +++ b/integreat_cms/cms/views/linkcheck/linkcheck_list_view.py @@ -93,8 +93,9 @@ def get_queryset(self) -> list[Url]: :return: The QuerySet of the filtered urls """ + region = self.kwargs.get("region_slug") or None urls, count_dict = filter_urls( - self.kwargs.get("region_slug"), self.kwargs.get("url_filter") + region, self.kwargs.get("url_filter") ) self.extra_context.update(count_dict) return urls @@ -104,9 +105,10 @@ def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpRespo Dispatch the view to either get() or post() """ if edit_url_id := kwargs.pop("url_id", None): + region = request.region.slug if request.region else None try: self.instance = get_urls( - region_slug=request.region.slug, url_ids=[edit_url_id] + region, url_ids=[edit_url_id] )[0] except IndexError as e: raise Http404("This URL does not exist") from e @@ -205,8 +207,10 @@ def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: return super().get(request, *args, **kwargs) action = request.POST.get("action") + + region_slug = request.region.slug if request.region else None selected_urls = get_urls( - region_slug=request.region.slug, + region_slug=region_slug, url_ids=request.POST.getlist("selected_ids[]"), ) diff --git a/integreat_cms/release_notes/current/unreleased/1443.yml b/integreat_cms/release_notes/current/unreleased/1443.yml new file mode 100644 index 0000000000..3753568f06 --- /dev/null +++ b/integreat_cms/release_notes/current/unreleased/1443.yml @@ -0,0 +1,2 @@ +en: Add centralized link list in the network management +de: Füge die zentralisierte Linklist in die Netzwerkverwaltung hinzu