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:
Родитель
257b6283c0
Коммит
ed83585609
|
@ -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 }} · {{ created }} <span class="light">· {{ 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">—</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();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче