show version adu in review page (#20726)

* load version adus in review page xhr

* Add top 10 ADU versions box

* moved ADU block to RH sidebar; made style consistent; reviewers js now runs on documen load
This commit is contained in:
Andrew Williamson 2023-05-23 11:29:33 +01:00 коммит произвёл GitHub
Родитель 257b6283c0
Коммит ed83585609
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 123 добавлений и 12 удалений

Просмотреть файл

@ -12,7 +12,7 @@
</a>
{% endwith %}
{% else %}
<img class="screenshot thumbnail" src="{{ addon.thumbnail_url }}"
<img class="screenshot thumbnail" src="{{ addon.get_icon_url(150) }}"
alt="" width="200" height="150" />
{% endif %}
</div>

Просмотреть файл

@ -1,4 +1,6 @@
<tr class="listing-header{% if version.needs_human_review %} needs-human-review{% elif version.needs_human_review_by_mad %} flagged-by-mad{%endif %}">
<tr class="listing-header{% if version.needs_human_review %} needs-human-review{% elif version.needs_human_review_by_mad %} flagged-by-mad{%endif %}"
id="version-{{ version.version.replace('.', '_') }}"
>
<th>
{% trans version = version.version, created = version.created|date, version_status = version.get_review_status_display() %}
Version {{ version }} &middot; {{ created }} <span class="light">&middot; {{ version_status }}</span>
@ -30,6 +32,10 @@
<td class="files">
{% if addon.type != amo.ADDON_STATICTHEME %}
{{ file_view(version) }}
<div class="version-adu" data-version-string="{{ version.version }}">
<h5>Average Daily Users:</h5>
<p class="version-adu-value downloads">&#x2014;</p>
</div>
{% if version.compatible_apps %}
<div class="compatibility"><h5>Compatibility:</h5>
<ul>

Просмотреть файл

@ -43,7 +43,13 @@
</p>
{% endif %}
<div id="addon" class="primary addon-type-{{ amo.ADDON_SLUGS.get(addon.type, addon.type) }}" role="main" data-id="{{ addon.id }}" data-url="{{ url('reviewers.review_viewing') }}">
<div id="addon"
class="primary addon-type-{{ amo.ADDON_SLUGS.get(addon.type, addon.type) }}"
role="main" data-id="{{ addon.id }}"
data-url="{{ url('reviewers.review_viewing') }}"
data-versions-adu-url="{{ url('reviewers.usage_per_version', addon.id) }}"
data-versions-adu-max-results="{{ VERSION_ADU_LIMIT }}"
>
{% include 'reviewers/addon_details_box.html' %}
@ -499,6 +505,15 @@
</ul>
{% endif %}
{% if addon.type != amo.ADDON_STATICTHEME %}
<div id="version-adu-top-ten">
<strong>Top 10 Version ADU</strong>
<div>
<ol></ol>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}

Просмотреть файл

@ -8754,12 +8754,15 @@ class TestUsagePerVersion(ReviewerTest):
'olympia.reviewers.views.get_average_daily_users_per_version_from_bigquery'
)
def test_basic(self, get_adu_per_version_mock):
values = {'1.1': 394, '1.2': 345, '2': 450, '3.4545': 999}
get_adu_per_version_mock.return_value = list(values.items())
get_adu_per_version_mock.return_value = [
('1.1', 394),
('2', 450),
('3.4545', 9999),
]
response = self.client.get(self.url)
assert response.status_code == 200
assert response.json() == values
assert response.json() == {'1.1': '394', '2': '450', '3.4545': '9,999'}
def test_not_reviewer(self):
user_factory(email='irregular@mozilla.com')

Просмотреть файл

@ -50,6 +50,7 @@ from olympia.amo.decorators import (
permission_required,
post_required,
)
from olympia.amo.templatetags.jinja_helpers import numberfmt
from olympia.amo.utils import paginate
from olympia.api.permissions import (
AllowAnyKindOfReviewer,
@ -103,7 +104,10 @@ from olympia.reviewers.utils import (
)
from olympia.scanners.admin import formatted_matched_rules_with_files_and_data
from olympia.stats.decorators import bigquery_api_view
from olympia.stats.utils import get_average_daily_users_per_version_from_bigquery
from olympia.stats.utils import (
get_average_daily_users_per_version_from_bigquery,
VERSION_ADU_LIMIT,
)
from olympia.users.models import UserProfile
from olympia.versions.models import Version, VersionReviewerFlags
from olympia.zadmin.models import get_config, set_config
@ -736,6 +740,7 @@ def review(request, addon, channel=None):
unlisted=(channel == amo.CHANNEL_UNLISTED),
user_ratings=user_ratings,
version=version,
VERSION_ADU_LIMIT=VERSION_ADU_LIMIT,
versions_with_a_due_date_other=versions_with_a_due_date_other,
versions_flagged_by_mad_other=versions_flagged_by_mad_other,
versions_pending_rejection_other=versions_pending_rejection_other,
@ -1511,4 +1516,4 @@ class ReviewAddonVersionCompareViewSet(
@non_atomic_requests
def usage_per_version(request, addon):
versions_avg = get_average_daily_users_per_version_from_bigquery(addon)
return JsonResponse(dict(versions_avg))
return JsonResponse({version: numberfmt(adu) for (version, adu) in versions_avg})

Просмотреть файл

@ -269,7 +269,10 @@ GROUP BY hashed_addon_id"""
]
def get_average_daily_users_per_version_from_bigquery(addon, limit=100):
VERSION_ADU_LIMIT = 100
def get_average_daily_users_per_version_from_bigquery(addon, limit=VERSION_ADU_LIMIT):
"""This function is used by the reviewer tools to show per-version adu to
reviewers inline."""
client = create_client()

Просмотреть файл

@ -25,7 +25,7 @@
text-decoration: none;
vertical-align: middle;
width: 16px; height: 16px;
}
.ed-sprite-firefox { background-position: 0 0; }
.ed-sprite-thunderbird { background-position: 0 -16px; }
@ -818,6 +818,9 @@ div.reviewer-stats-table > div.reviewer-stats-dark {
.review-files .install {
padding: 0;
}
.review-files p.version-adu-value {
display: inline;
}
.review-files .files > .compatibility, .review-files .files > .compatibility li {
padding-top: 0;
}
@ -1262,6 +1265,21 @@ p.is_promoted {
}
}
#version-adu-top-ten {
ol {
margin-bottom: 0;
margin-left: 1em;
li * {
font-style: italic;
color: lightgray;
}
li a {
color: #0996F8;
}
}
}
.more-actions {
border: 1px solid #ebebeb;
padding: 10px;

Просмотреть файл

@ -1,4 +1,4 @@
(function () {
$(document).ready(function () {
if ($('.daily-message').length) {
initDailyMessage();
}
@ -46,13 +46,17 @@
initQueue();
}
if ($('.version-adu').length > 0) {
initVersionsADU();
}
// Show add-on ID when icon is clicked
if ($('#addon[data-id], #persona[data-id]').length) {
$('#addon .icon').click(function () {
window.location.hash = 'id=' + $('#addon, #persona').attr('data-id');
});
}
})();
});
function initReviewActions() {
function showForm(element, pageload) {
@ -497,3 +501,60 @@ function initScrollingSidebar() {
}, 20),
);
}
function initVersionsADU() {
function fillVersionsTable(versionAduPairs) {
versionAduPairs.forEach(([version, adu]) => {
$(
format(
'.version-adu[data-version-string="{0}"] .version-adu-value',
version,
),
).text(adu);
});
let missingAduText;
const queryLimit = $('#addon').data('versions-adu-max-results');
if (versionAduPairs.length === queryLimit) {
// if we've got max results we may have hit the limit of the query
missingAduText = format('<= {0}', versionAduPairs[queryLimit - 1]);
} else {
// otherwise these are just 0 ADU versions
missingAduText = '0';
}
$('.version-adu-value:contains("\u2014")').text(missingAduText);
}
function fillTopTenBox(versionAduPairs) {
versionAduPairs.slice(0, 10).forEach(([version, adu]) => {
const versionEntryId = '#version-' + version.replaceAll('.', '_');
let versionLinkOrText;
if ($(versionEntryId).length) {
versionLinkOrText = format(
'<a href="{0}">{1}</a>',
versionEntryId,
version,
);
} else {
versionLinkOrText = format('<span>{0}</span>', version);
}
$('#version-adu-top-ten ol').append(
format('<li>{0}: {1}</li>', versionLinkOrText, adu),
);
});
if (!versionAduPairs.length) {
$('#version-adu-top-ten div').append(
'No average daily user values found.',
);
}
}
function loadVersionsADU() {
const aduUrl = $('#addon').data('versions-adu-url');
$.get(aduUrl, function (data) {
const versionAduPairs = Object.entries(data);
fillVersionsTable(versionAduPairs);
fillTopTenBox(versionAduPairs);
});
}
loadVersionsADU();
}