From 9bb5656d4074fed927ceb05cec626b07cddac323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= <cuu508@gmail.com> Date: Wed, 10 Apr 2024 14:36:42 +0300 Subject: [PATCH] Implement dynamic favicon in the projects overview page cc: #971 --- CHANGELOG.md | 1 + hc/front/tests/test_index.py | 2 ++ hc/front/views.py | 4 ++++ static/js/projects.js | 5 +++++ templates/front/projects.html | 7 +++++++ 5 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cac572d..39cfc184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file. ### Improvements - Show status changes (flips) in check's log page (#447) +- Implement dynamic favicon in the projects overview page (#971) ## v3.3 - 2024-04-03 diff --git a/hc/front/tests/test_index.py b/hc/front/tests/test_index.py index 8fc4e308..d31fa45d 100644 --- a/hc/front/tests/test_index.py +++ b/hc/front/tests/test_index.py @@ -18,6 +18,7 @@ class IndexTestCase(BaseTestCase): self.assertContains(r, "Alices Project") self.assertContains(r, "3 checks") self.assertContains(r, "status ic-up") + self.assertContains(r, "favicon.svg") def test_it_shows_overall_down_status(self) -> None: self.c1.status = "down" @@ -26,3 +27,4 @@ class IndexTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.get("/") self.assertContains(r, "status ic-down") + self.assertContains(r, "favicon_down.svg") diff --git a/hc/front/views.py b/hc/front/views.py index 62504e34..88688918 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -373,9 +373,12 @@ def index(request: HttpRequest) -> HttpResponse: q = q.annotate(n_channels=Count("channel", distinct=True)) q = q.annotate(owner_email=F("owner__email")) projects = list(q) + any_down = False for project in projects: setattr(project, "overall_status", summary[project.code]["status"]) setattr(project, "any_started", summary[project.code]["started"]) + if summary[project.code]["status"] == "down": + any_down = True # The list returned by projects() is already sorted . Do an additional sorting pass # to move projects with overall_status=down to the front (without changing their @@ -386,6 +389,7 @@ def index(request: HttpRequest) -> HttpResponse: "page": "projects", "projects": projects, "last_project_id": request.session.get("last_project_id"), + "any_down": any_down, } return render(request, "front/projects.html", ctx) diff --git a/static/js/projects.js b/static/js/projects.js index 0a1c129d..f4141742 100644 --- a/static/js/projects.js +++ b/static/js/projects.js @@ -1,5 +1,6 @@ $(function () { var base = document.getElementById("base-url").getAttribute("href").slice(0, -1); + var favicon = document.querySelector('link[rel="icon"]'); // Schedule refresh to run every 3s when tab is visible and user // is active, every 60s otherwise @@ -11,8 +12,10 @@ $(function () { dataType: "json", timeout: 2000, success: function(data) { + var anyDown = false; for (var code in data) { var el = data[code]; + anyDown = anyDown || (el.status == "down"); if (el.status != lastStatus[code]) { $("#" + code + " div.status").attr("class", "status ic-" + el.status); @@ -24,6 +27,8 @@ $(function () { lastStarted[code] = el.started; } } + var downPostfix = anyDown ? "_down" : ""; + favicon.href = `${base}/static/img/favicon${downPostfix}.svg`; } }); } diff --git a/templates/front/projects.html b/templates/front/projects.html index cbee6719..f6c51ab8 100644 --- a/templates/front/projects.html +++ b/templates/front/projects.html @@ -2,6 +2,13 @@ {% load compress static hc_extras %} {% block title %}{{ site_name }}{% endblock %} +{% block favicon %} + {% if any_down %} + <link rel="icon" type="image/svg+xml" href="{% static 'img/favicon_down.svg' %}"> + {% else %} + <link rel="icon" type="image/svg+xml" href="{% static 'img/favicon.svg' %}"> + {% endif %} +{% endblock %} {% block content %}