diff --git a/assets/src/bundles/webapp/coverage.css b/assets/src/bundles/webapp/coverage.css --- a/assets/src/bundles/webapp/coverage.css +++ b/assets/src/bundles/webapp/coverage.css @@ -1,5 +1,5 @@ /** - * Copyright (C) 2021 The Software Heritage developers + * Copyright (C) 2021-2022 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information @@ -64,6 +64,10 @@ padding: 0; } +.swh-coverage-focus { + border: 2px solid #e20026; +} + /* Thin scrollbar for chromium based browsers */ .swh-coverage-info-body::-webkit-scrollbar { diff --git a/swh/web/misc/coverage.py b/swh/web/misc/coverage.py --- a/swh/web/misc/coverage.py +++ b/swh/web/misc/coverage.py @@ -412,6 +412,11 @@ "deposit": _search_url(origins["search_pattern"], "deposit") } + focus = [] + focus_param = request.GET.get("focus") + if focus_param: + focus = focus_param.split(",") + return render( request, "misc/coverage.html", @@ -420,7 +425,8 @@ "Regular crawling": listed_origins, "Discontinued hosting": legacy_origins, "On demand archival": deposited_origins, - } + }, + "focus": focus, }, ) diff --git a/swh/web/templates/misc/coverage.html b/swh/web/templates/misc/coverage.html --- a/swh/web/templates/misc/coverage.html +++ b/swh/web/templates/misc/coverage.html @@ -1,5 +1,5 @@ {% comment %} -Copyright (C) 2015-2021 The Software Heritage developers +Copyright (C) 2015-2022 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information @@ -23,7 +23,7 @@ /* @licstart The following is the entire license notice for the JavaScript code in this page. -Copyright (C) 2015-2021 The Software Heritage developers +Copyright (C) 2015-2022 The Software Heritage developers This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as @@ -48,7 +48,7 @@ <body style="padding-bottom: 0;"> <div class="wrapper" style="margin-left: 0;" data-iframe-height> <div class="content"> - <div class="container-fluid"> + <div id="swh-coverage-content" class="container-fluid"> <p> A significant amount of source code has already been ingested in the Software Heritage archive. It notably includes the following software origins. @@ -59,7 +59,8 @@ <div class="row"> {% for origins in origins_data.origins %} <div class="col-md-4 swh-coverage-col"> - <div class="card swh-coverage" id="{{ origins.type }}" title="{{ origins.info }}"> + <div class="card swh-coverage {% if focus and origins.type in focus %} swh-coverage-focus {% endif %}" + id="{{ origins.type }}" title="{{ origins.info }}"> <a href="{{ origins.info_url }}" target="_blank" rel="noopener noreferrer"> {% with 'img/logos/'|add:origins.type.lower|add:'.png' as png_logo %} <img class="card-img-top swh-coverage-logo" src="{% static png_logo %}" @@ -67,7 +68,7 @@ {% endwith %} </a> <div class="card-header swh-coverage-header"> - <a class="collapsed d-block" data-toggle="collapse" + <a class="{% if not focus %} collapsed {% endif %} d-block" data-toggle="collapse" href="#swh-coverage-info-{{ origins_type.lower|cut:' ' }}" aria-expanded="true" aria-controls="swh-coverage-info-{{ origins_type.lower|cut:' ' }}" id="heading-collapsed" @@ -82,9 +83,11 @@ </div> </a> </div> - <div id="swh-coverage-info-{{ origins_type.lower|cut:' ' }}" class="collapse" + <div id="swh-coverage-info-{{ origins_type.lower|cut:' ' }}" + class="collapse {% if focus %} show {% endif %}" aria-labelledby="heading-collapsed"> - <div class="card-body text-center swh-coverage-info-body"> + <div class="card-body text-center swh-coverage-info-body" + {% if focus is not None %} style="max-height: none;" {% endif %}> <table style="width: 100%"> {% if "instances" in origins %} <thead> @@ -147,5 +150,14 @@ </div> </div> <a href="{% url 'jslicenses' %}" rel="jslicense" style="display: none;">JavaScript license information</a> + <script> + $(document).ready(function() { + if (window.frameElement === null) { + // do not render full width page if not embedded in an iframe + $("#swh-coverage-content").removeClass("container-fluid"); + $("#swh-coverage-content").addClass("container"); + } + }); + </script> </body> </html> diff --git a/swh/web/tests/misc/test_coverage.py b/swh/web/tests/misc/test_coverage.py --- a/swh/web/tests/misc/test_coverage.py +++ b/swh/web/tests/misc/test_coverage.py @@ -6,9 +6,11 @@ from datetime import datetime, timezone from itertools import chain import os -from random import randint +from random import choices, randint import uuid +import pytest + from django.conf import settings from django.utils.html import escape @@ -31,20 +33,20 @@ ) -def test_coverage_view_with_metrics(client, swh_scheduler, mocker): - """ - Generate some sample scheduler metrics and some sample deposits - that will be consumed by the archive coverage view, then check - the HTML page gets rendered without errors. - """ +visit_types = ["git", "hg", "svn", "bzr", "svn"] + +@pytest.fixture(autouse=True) +def archive_coverage_data(mocker, swh_scheduler): + """Generate some sample scheduler metrics and some sample deposits + that will be consumed by the archive coverage view. + """ # mock calls to get nixguix origin counts mock_archive = mocker.patch("swh.web.misc.coverage.archive") mock_archive.lookup_latest_origin_snapshot.return_value = {"id": "some-snapshot"} mock_archive.lookup_snapshot_sizes.return_value = {"release": 30095} listers = [] - visit_types = ["git", "hg", "svn", "bzr", "svn"] for origins in listed_origins["origins"]: # create some instances for each lister for instance in range(randint(1, 5)): @@ -98,6 +100,8 @@ get_deposits_list = mocker.patch("swh.web.misc.coverage.get_deposits_list") get_deposits_list.return_value = deposits + +def test_coverage_view_with_metrics(client): # check view gets rendered without errors url = reverse("swh-coverage") resp = check_html_get_response( @@ -129,3 +133,34 @@ check_http_get_response( client, url, status_code=200, server_name=SWH_WEB_SERVER_NAME ) + + +def test_coverage_view_with_focus(client): + + origins = ( + listed_origins["origins"] + + legacy_origins["origins"] + + deposited_origins["origins"] + ) + + focus = choices([o["type"] for o in origins], k=randint(1, 3)) + + # check view gets rendered without errors + url = reverse("swh-coverage", query_params={"focus": ",".join(focus)}) + resp = check_html_get_response( + client, url, status_code=200, template_used="misc/coverage.html" + ) + + # check focused elements + assert_contains( + resp, + "swh-coverage-focus", + count=len([o for o in origins if o["type"] in focus]), + ) + + # check bootstrap cards are expanded + assert_contains( + resp, + 'class="collapse show"', + count=len(origins), + )