From 29a5da40b697e9fa0067d2fb259ba907dbbdf9aa Mon Sep 17 00:00:00 2001 From: JoeyStk Date: Sun, 18 Aug 2024 16:47:44 +0200 Subject: [PATCH] Rebuild translation coverage with ajax --- ..._missing_or_outdated_translations_row.html | 33 ++++++-- integreat_cms/cms/urls/protected.py | 7 +- .../cms/views/dashboard/dashboard_view.py | 33 +++++--- integreat_cms/locale/de/LC_MESSAGES/django.po | 47 +++++++++-- integreat_cms/static/src/index.ts | 1 + .../src/js/dashboard/translation-coverage.ts | 84 +++++++++++++++++++ 6 files changed, 174 insertions(+), 31 deletions(-) create mode 100644 integreat_cms/static/src/js/dashboard/translation-coverage.ts diff --git a/integreat_cms/cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html b/integreat_cms/cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html index bdad5ba8be..ac0e295a54 100644 --- a/integreat_cms/cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html +++ b/integreat_cms/cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html @@ -1,5 +1,11 @@ {% extends "../_todo_dashboard_row.html" %} {% load i18n %} +{% block todo_dashboard_ajax_url %} + {{ translation_coverage_ajax }} +{% endblock todo_dashboard_ajax_url %} +{% block todo_dashboard_id %} + translation-coverage +{% endblock todo_dashboard_id %} {% block todo_dashboard_icon %} languages {% endblock todo_dashboard_icon %} @@ -15,24 +21,33 @@ {% endwith %} {% endblock todo_dashboard_number %} {% block todo_dashboard_description %} - {% if number_of_missing_or_outdated_translations > 0 %} + + +
{% blocktranslate trimmed %} - At the moment all pages have up-to-date translations. Good job! + We are loading your outdated and missing translations in the background. Please be patient. {% endblocktranslate %} - {% endif %} +
{% endblock todo_dashboard_description %} {% block todo_dashboard_button_link %} - {% if outdated_pages %} + + {% endblock todo_dashboard_button_link %} diff --git a/integreat_cms/cms/urls/protected.py b/integreat_cms/cms/urls/protected.py index fdb77a2907..b7ceab41e1 100644 --- a/integreat_cms/cms/urls/protected.py +++ b/integreat_cms/cms/urls/protected.py @@ -532,7 +532,12 @@ "broken-links/", dashboard.DashboardView.get_broken_links_context, name="get_broken_links_ajax", - ) + ), + path( + "translation-coverage/", + dashboard.DashboardView.get_translation_coverage_context, + name="get_translation_coverage_ajax", + ), ] ), ), diff --git a/integreat_cms/cms/views/dashboard/dashboard_view.py b/integreat_cms/cms/views/dashboard/dashboard_view.py index d25c96f71e..e93a3aa297 100644 --- a/integreat_cms/cms/views/dashboard/dashboard_view.py +++ b/integreat_cms/cms/views/dashboard/dashboard_view.py @@ -65,6 +65,10 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]: "get_broken_links_ajax", kwargs={"region_slug": self.request.region.slug}, ), + "translation_coverage_ajax": reverse( + "get_translation_coverage_ajax", + kwargs={"region_slug": self.request.region.slug}, + ), } ) @@ -74,7 +78,6 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]: context.update(self.get_low_hix_value_context()) context.update(self.get_outdated_pages_context()) context.update(self.get_drafted_pages()) - context.update(self.get_translation_coverage_context()) return context @@ -261,9 +264,11 @@ def get_drafted_pages( "single_drafted_page": single_drafted_page, } + @json_response + # pylint: disable=unused-argument, disable=no-self-argument def get_translation_coverage_context( - self, - ) -> dict[str, QuerySet | PageTranslation | datetime | int | None]: + request: HttpRequest, region_slug: str + ) -> JsonResponse: r""" Extend context by info on translation coverage of pages @@ -271,22 +276,22 @@ def get_translation_coverage_context( """ number_of_outdated_pages = 0 - if not self.request.region.default_language: + if not request.region.default_language: return {} - languages = LanguageTreeNode.objects.filter(region=self.request.region).exclude( - language=self.request.region.default_language + languages = LanguageTreeNode.objects.filter(region=request.region).exclude( + language=request.region.default_language ) - pages_in_region = Page.objects.filter(region=self.request.region) + pages_in_region = Page.objects.filter(region=request.region) possible_translations = languages.count() * pages_in_region.count() published_foreign_translations = ( PageTranslation.objects.select_related("language") .order_by("page__id", "language__id", "-version") .distinct("page__id", "language__id") - .filter(page__region__slug=self.request.region.slug, minor_edit=False) - .exclude(language=self.request.region.default_language) + .filter(page__region__slug=request.region.slug, minor_edit=False) + .exclude(language=request.region.default_language) .all() ) @@ -298,7 +303,9 @@ def get_translation_coverage_context( if pagetranslation.is_outdated: number_of_outdated_pages += 1 - return { - "number_of_missing_or_outdated_translations": number_of_missing_translations - + number_of_outdated_pages - } + return JsonResponse( + data={ + "number_of_missing_or_outdated_translations": number_of_missing_translations + + number_of_outdated_pages + } + ) diff --git a/integreat_cms/locale/de/LC_MESSAGES/django.po b/integreat_cms/locale/de/LC_MESSAGES/django.po index 25d5838de2..397b336eff 100644 --- a/integreat_cms/locale/de/LC_MESSAGES/django.po +++ b/integreat_cms/locale/de/LC_MESSAGES/django.po @@ -5281,13 +5281,15 @@ msgid "" "Your pages currently have %(number_of_missing_translations)s pages that have an outdated or no translation. In order for the users to benefit " "from your content you should translate them or have them translated." -msgstr "Ihre Inhalte haben momentan %(number_of_missing_translations)s Seiten mit fehlender oder veralteter Übersetzung. Damit die Nutzer:innen von Ihren Inhalten profitieren können, sollten Sie diese übersetzen (lassen)." +msgstr "" +"Ihre Inhalte haben momentan %(number_of_missing_translations)s Seiten " +"mit fehlender oder veralteter Übersetzung. Damit die Nutzer:innen von Ihren " +"Inhalten profitieren können, sollten Sie diese übersetzen (lassen)." #: cms/templates/dashboard/todo_dashboard_rows/_missing_translations_row.html #: cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html msgid "At the moment all pages have up-to-date translations. Good job!" -msgstr "" -"Aktuell haben alle Ihre Seiten aktuelle Übersetzungen. Gute Arbeit!" +msgstr "Aktuell haben alle Ihre Seiten aktuelle Übersetzungen. Gute Arbeit!" #: cms/templates/dashboard/todo_dashboard_rows/_missing_translations_row.html #: cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html @@ -5355,12 +5357,22 @@ msgid "At the moment there is no page waiting for approval. Good job!" msgstr "Aktuell liegen keine Seiten zur Freigabe vor. Gute Arbeit!" #: cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html -#, python-format msgid "" -"Your pages currently have %(number_of_missing_or_outdated_translations)s " -"pages that have an outdated or no translation. In order for the users to " -"benefit from your content you should translate them or have them translated." -msgstr "Ihre Inhalten haben aktuell %(number_of_missing_or_outdated_translations)s Seiten mit fehlender oder veralteter Übersetzung. Damit die Nutzer:innen von Ihren Inhalten profitieren können, sollten Sie diese übersetzen (lassen)." +"Your pages currently have pages that have an outdated or no " +"translation. In order for the users to benefit from your content you should " +"translate them or have them translated." +msgstr "" +"Ihre Inhalte haben momentan Seiten mit fehlender oder " +"veralteter Übersetzung. Damit die Nutzer:innen von Ihren Inhalten " +"profitieren können, sollten Sie diese übersetzen (lassen)." + +#: cms/templates/dashboard/todo_dashboard_rows/number_of_missing_or_outdated_translations_row.html +msgid "" +"We are loading your outdated and missing translations in the background. " +"Please be patient." +msgstr "" +"Wir laden im Hintergrund gerade Ihre kaputten Links. Bitte haben Sie noch " +"ein wenig Geduld." #: cms/templates/emails/_base_email.html #: cms/templates/emails/password_reset_email.txt @@ -10334,6 +10346,25 @@ msgstr "" #~ msgid "Contents" #~ msgstr "Inhalte" +#~ msgid "" +#~ "We are loading your translation coverage in the background. Please be " +#~ "patient." +#~ msgstr "" +#~ "Wir laden im Hintergrund gerade Ihre veralteten und fehlenden " +#~ "Übersetzungen. Bitte haben Sie noch ein wenig Geduld." + +#, python-format +#~ msgid "" +#~ "Your pages currently have " +#~ "%(number_of_missing_or_outdated_translations)s pages that have an " +#~ "outdated or no translation. In order for the users to benefit from your " +#~ "content you should translate them or have them translated." +#~ msgstr "" +#~ "Ihre Inhalten haben aktuell " +#~ "%(number_of_missing_or_outdated_translations)s Seiten mit " +#~ "fehlender oder veralteter Übersetzung. Damit die Nutzer:innen von Ihren " +#~ "Inhalten profitieren können, sollten Sie diese übersetzen (lassen)." + #~ msgid "View location" #~ msgstr "Ort ansehen" diff --git a/integreat_cms/static/src/index.ts b/integreat_cms/static/src/index.ts index 4216dce99f..2e7fce8751 100644 --- a/integreat_cms/static/src/index.ts +++ b/integreat_cms/static/src/index.ts @@ -103,6 +103,7 @@ import "./js/menu"; import "./js/poi-categories/poicategory-colors-icons"; import "./js/dashboard/broken-links"; +import "./js/dashboard/translation-coverage"; // IE11: fetch /* eslint-disable-next-line @typescript-eslint/no-var-requires */ diff --git a/integreat_cms/static/src/js/dashboard/translation-coverage.ts b/integreat_cms/static/src/js/dashboard/translation-coverage.ts new file mode 100644 index 0000000000..ed41d473d2 --- /dev/null +++ b/integreat_cms/static/src/js/dashboard/translation-coverage.ts @@ -0,0 +1,84 @@ +import { getCsrfToken } from "../utils/csrf-token"; + +type Content = { + number_of_missing_or_outdated_translations: number; +}; + +const getContent = async (url: string): Promise => { + const response = await fetch(url, { + method: "POST", + headers: { + "X-CSRFToken": getCsrfToken(), + }, + }); + return response.json(); +}; + +const showAllTotalNumbers = () => { + const elements = document.querySelectorAll(".total-results"); + + elements.forEach((element) => { + if (!element.closest("#translation-coverage")) { + const el = element; + el.classList.remove("hidden"); + } + }); +}; + +window.addEventListener("load", async () => { + showAllTotalNumbers(); + + const translationCoverageElement = document.getElementById("translation-coverage"); + + if (!translationCoverageElement) { + return; + } + + const url = translationCoverageElement.dataset.url; + const hideWaitingMessage = () => { + translationCoverageElement.querySelector(".waiting-message").classList.add("hidden"); + }; + + const showSuccessMessage = () => { + translationCoverageElement.querySelector(".success-message").classList.remove("hidden"); + }; + + const showSuccessIcon = () => { + translationCoverageElement.querySelector(".success-icon").classList.remove("hidden"); + }; + + const showDescription = (affectedPageTitle: string) => { + translationCoverageElement.querySelector(".todo-message").classList.remove("hidden"); + (translationCoverageElement.querySelector(".todo-message b") as HTMLElement).innerText = affectedPageTitle; + }; + + const showNumberOfPagesElement = () => { + translationCoverageElement.querySelector(".total-results").classList.remove("hidden"); + }; + + const updateNumberOfPages = (numberOfPages: number) => { + (translationCoverageElement.querySelector(".total-results span") as HTMLElement).innerText = + numberOfPages.toString(); + }; + + const showButton = () => { + translationCoverageElement.querySelector(".todo-button").classList.remove("hidden"); + }; + + if (url) { + console.log(url); + const json = await getContent(url); + console.log(json); + hideWaitingMessage(); + showNumberOfPagesElement(); + if (json.number_of_missing_or_outdated_translations > 0) { + showDescription(String(json.number_of_missing_or_outdated_translations)); + updateNumberOfPages(json.number_of_missing_or_outdated_translations); + showButton(); + } else { + showSuccessMessage(); + showSuccessIcon(); + updateNumberOfPages(0); + } + } +});