Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

improve the devhub versions page (bug 750914) #1795

Closed
wants to merge 3 commits into from

2 participants

@magopian
Collaborator

Not being aware of the various statuses (on addons/versions/files) and their
consequences, I'd love a thorough review and tests on this.

Eg: a version is seen as disabled (and faded out) if all its files' statuses
are disabled, is that correct?

This PR is based on the PR #1788, which is based on the PR #1752. So only the last commit is relevant to this PR.

improve_versions

@magopian
Collaborator

@cvan r?

@ngokevin
Owner

Let's move this PR to Olympia, the new AMO repo.

@magopian magopian referenced this pull request in mozilla/olympia
Merged

improve the devhub versions page (bug 750914) #14

@magopian
Collaborator

Moved to olympia/pull/14

@magopian magopian closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
8 apps/devhub/helpers.py
@@ -222,3 +222,11 @@ def display_url(url):
def get_compat_counts(addon):
"""Get counts for add-on compatibility reports."""
return CompatReport.get_counts(addon.guid)
+
+
+@register.function
+def version_disabled(version):
+ """Return True if all the files are disabled."""
+ disabled = [status == amo.STATUS_DISABLED
+ for _id, status in version.statuses]
+ return all(disabled)
View
2  apps/devhub/templates/devhub/addons/edit.html
@@ -19,7 +19,7 @@
<header>
{{ dev_breadcrumbs(addon) }}
{{ l10n_menu(addon.default_locale) }}
- <h2>{{ title }}</h2>
+ <h2>{{ addon.name }}</h2>
</header>
<section class="primary" role="main">
View
44 apps/devhub/templates/devhub/addons/listing/items.html
@@ -1,4 +1,4 @@
-{% from "devhub/addons/listing/macros.html" import dev_heading, dev_item_info, dev_item_actions %}
+{% from "devhub/addons/listing/macros.html" import dev_heading, dev_item_info %}
{% set collection = collection or None %}
{% set username = request.amo_user.username if request.user.is_authenticated() else '' %}
{% for addon in addons %}
@@ -17,7 +17,7 @@
{{ dev_item_info(addon, amo) }}
</div>
<ul class="item-details">
- {% if not webapp %}
+ {% if addon.is_persona() %}
{% if addon.current_version %}
{% set link = url('devhub.versions.edit', addon.slug, addon.current_version.id) %}
{# L10n: {1} is a version number. #}
@@ -33,38 +33,34 @@
<li class="date-updated">{{ _('<strong>Last updated:</strong> {0}'|
f(addon.last_updated|datetime)) }}</li>
{% endif %}
- {% endif %}
- <li id="version-status-item">
- <strong>{{ _('Status:') }}</strong>
- <a{% if not addon.is_persona() %} href="{{ addon.get_dev_url('versions') }}"{% endif %}>
+ <li id="version-status-item">
+ <strong>{{ _('Status:') }}</strong>
{% if addon.disabled_by_user %}
<span class="{{ status_class(addon) }}"><b>{{ _('Disabled') }}</b></span>
{% else %}
<span class="{{ status_class(addon) }}">
<b>{{ amo.STATUS_CHOICES[addon.status] }}</b></span>
{% endif %}
- </a>
- </li>
- {% with position = get_position(addon) %}
- {% if position.pos and position.total %}
- <li class="queue-position">
- {% trans pos=position.pos|numberfmt, total=position.total|numberfmt %}
- <b>Queue position:</b> {{ pos }} of {{ total }}
- {% endtrans %}
- </li>
- {% endif %}
- {% endwith %}
+ </li>
+ {% with position = get_position(addon) %}
+ {% if position.pos and position.total %}
+ <li class="queue-position">
+ {% trans pos=position.pos|numberfmt, total=position.total|numberfmt %}
+ <b>Queue position:</b> {{ pos }} of {{ total }}
+ {% endtrans %}
+ </li>
+ {% endif %}
+ {% endwith %}
+ {% else %}
+ {% include "devhub/includes/addon_details.html" %}
+ {% endif %}
</ul>
{% endif %}
<div class="item-actions">
- {% if webapp %}
- {% include "devhub/addons/listing/item_actions_app.html" %}
+ {% if addon.is_persona() %}
+ {% include "devhub/addons/listing/item_actions_theme.html" %}
{% else %}
- {% if addon.is_persona() %}
- {% include "devhub/addons/listing/item_actions_theme.html" %}
- {% else %}
- {% include "devhub/addons/listing/item_actions.html" %}
- {% endif %}
+ {% include "devhub/addons/listing/item_actions.html" %}
{% endif %}
</div>
</div>
View
2  apps/devhub/templates/devhub/addons/owner.html
@@ -22,7 +22,7 @@
{% if not webapp %}
{{ l10n_menu(addon.default_locale) }}
{% endif %}
- <h2>{{ title }}</h2>
+ <h2>{{ addon.name }}</h2>
</header>
<section id="edit-addon" class="primary devhub-form" role="main">
<form method="post" class="item" action="">
View
2  apps/devhub/templates/devhub/addons/profile.html
@@ -7,7 +7,7 @@
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
{{ l10n_menu(addon.default_locale) }}
- <h2>{{ title }}</h2>
+ <h2>{{ addon.name }}</h2>
</header>
<section class="primary" role="main">
{% set remove_url = addon.get_dev_url('profile.remove') %}
View
119 apps/devhub/templates/devhub/includes/addon_details.html
@@ -0,0 +1,119 @@
+{% from "includes/forms.html" import tip %}
+
+{% macro status_and_tip(addon, tip) %}
+ <span class="{{ status_class(addon) }}"><b>{{ amo.STATUS_CHOICES[addon.status] }}</b></span>
+ <span class="tip tooltip" title="{{ tip }}">?</span>
+{% endmacro %}
+
+<li>
+ <strong>
+ {{ _('Status:') }}
+
+ {% if addon.disabled_by_user and addon.status != amo.STATUS_DISABLED %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("Your add-on's listing is disabled and is not showing
+ anywhere in our gallery or update service.")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_NULL %}
+ <a href="{{ url('devhub.submit.resume', addon.slug) }}">
+ {{ status_and_tip(addon, _('Please complete your add-on.')) }}
+ </a>
+ {% elif addon.status == amo.STATUS_PENDING %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon, _('You will receive an email when the review is complete.')) }}
+ </a>
+ {% elif addon.status == amo.STATUS_UNREVIEWED %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("You will receive an email when the review is complete. Until
+ then, your add-on is not listed in our gallery but can be
+ accessed directly from its details page.")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_NOMINATED %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("You will receive an email when the review is complete. Until
+ then, your add-on is not listed in our gallery but can be
+ accessed directly from its details page. ")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_PUBLIC %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("Your add-on is displayed in our gallery and users are
+ receiving automatic updates.")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_DISABLED %}
+ <a href="{{ addon.get_dev_url('versions') }}#version-upload" class="version-upload">
+ {{ status_and_tip(addon,
+ _("Your add-on was disabled by a site administrator and is no
+ longer shown in our gallery. If you have any questions,
+ please email marketplace-staff@mozilla.org.")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_LITE %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("Your add-on is displayed in our gallery as experimental
+ and users are receiving automatic updates. Some features
+ are unavailable to your add-on.")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_LITE_AND_NOMINATED %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("You will receive an email when the full review is complete.
+ Until then, your add-on is displayed in our gallery as
+ experimental and users are receiving automatic updates.
+ Some features are unavailable to your add-on.")) }}
+ </a>
+ {% elif addon.status == amo.STATUS_PURGATORY %}
+ <a href="{{ addon.get_dev_url('versions') }}">
+ {{ status_and_tip(addon,
+ _("All add-ons hosted in our gallery must now be reviewed by an
+ editor. If you wish to continue hosting your add-on, please
+ click to select a review process.")) }}
+ </a>
+ {% endif %}
+ </strong>
+</li>
+{% if addon.current_version %}
+ <li>
+ <strong>{{ _('Current Version:') }}</strong>
+ <a href="{{ addon.current_version.get_url_path() }}">
+ {{ addon.current_version }}
+ <span class="tip tooltip" title="{{ _('This is the version of your add-on that will
+ be installed if someone clicks the Install
+ button on addons.mozilla.org.') }}">?</span>
+ </a>
+ </li>
+{% endif %}
+<li>
+ {% if sorting == 'created' %}
+ {# L10n: {0} is a date. #}
+ <strong>{{ _('Created:') }}</strong>
+ {{ addon.created|datetime(_('%b %e, %Y')) }}
+ {% else %}
+ <strong>{{ _('Last Updated:') }}</strong>
+ {{ addon.last_updated|datetime(_('%b %e, %Y')) }}
+ {% endif %}
+</li>
+{% if addon.latest_version and addon.latest_version != addon.current_version %}
+ <li>
+ <strong>{{ _('Next Version:') }}</strong>
+ <a href="{{ addon.latest_version.get_url_path() }}">
+ {{ addon.latest_version.version }}
+ <span class="tip tooltip" title="{{ _('This is the newest uploaded version, however
+ it isn’t live on the site yet.') }}">?</span>
+ </a>
+ </li>
+{% endif %}
+{% with position = get_position(addon) %}
+ {% if position and position.pos and position.total %}
+ <li>
+ <strong>{{ _('Queue Position:') }}</strong>
+ {% trans position=position.pos|numberfmt,
+ total=position.total|numberfmt %}
+ {{ position }} of {{ total }}
+ {% endtrans %}
+ </li>
+ {% endif %}
+{% endwith %}
View
40 apps/devhub/templates/devhub/includes/addons_edit_nav.html
@@ -1,29 +1,49 @@
{% set urls = [
(addon.get_dev_url(), _('Edit Listing')),
- (addon.get_dev_url('owner'), _('Manage Authors') if webapp
- else _('Manage Authors & License')),
+ (addon.get_dev_url('owner'), _('Manage Authors & License')),
(addon.get_dev_url('profile'), _('Manage Developer Profile')),
(addon.get_dev_url('payments'), _('Manage Payments')),
- (addon.get_dev_url('versions'), _('Manage App Status') if webapp
- else _('Manage Status & Versions')),
+ (addon.get_dev_url('versions'), _('Manage Status & Versions')),
] %}
+
{% if addon.is_premium() and waffle.switch('allow-refund') %}
{% do urls.insert(4, (addon.get_dev_url('refunds'), loc('Manage Refunds'))) %}
{% endif %}
-{% if addon.is_webapp() %}
- {% do urls.insert(4,
- (addon.get_dev_url('in_app_config'), _('Manage In-App Payments'))
- ) %}
-{% endif %}
<section class="secondary" role="complementary">
+ <div class="addon-status">
+ <img class="addon-icon" src="{{ addon.icon_url }}">
+ <ul class="addon-details">
+ {% include "devhub/includes/addon_details.html" %}
+ </ul>
+ <p class="addon-upload">
+ {% if not addon.is_incomplete() and not addon.is_disabled %}
+ <strong>
+ <a href="{{ addon.get_dev_url('versions') }}#version-upload" class="version-upload">{{ _('Upload New Version') }}</a>
+ </strong>
+ &middot;
+ {% endif %}
+ <a href="{{ addon.get_dev_url('versions') }}">{{ _('View All' ) }}</a>
+ </p>
+ </div>
<div class="highlight" id="edit-addon-nav">
- <h3>{{ addon.name }}</h3>
<ul class="refinements">
{% for url, title in urls %}
<li {% if url in request.path %}class="selected"{% endif %}>
<a href="{{ url }}">{{ title }}</a></li>
{% endfor %}
+ <li class="addon-manage">
+ {% if check_addon_ownership(request, addon, dev=True) %}
+ {% if addon.disabled_by_user and addon.status != amo.STATUS_DISABLED %}
+ <a href="{{ addon.get_dev_url('enable') }}" class="enable-addon">{{ _('Enable Add-on') }}</a>
+ {% elif not addon.is_disabled %}
+ <a href="{{ addon.get_dev_url('versions') }}#disable-addon" class="disable-addon">{{ _('Disable Add-on') }}</a>
+ {% endif %}
+ {% endif %}
+ {% if check_addon_ownership(request, addon) and addon.can_be_deleted() %}
+ <a href="{{ addon.get_dev_url('versions') }}#delete-addon" class="delete-addon">{{ _('Delete Add-on') }}</a>
+ {% endif %}
+ </li>
</ul>
<ul class="refinements">
<li><a href="{{ addon.get_url_path() }}">
View
2  apps/devhub/templates/devhub/payments/payments.html
@@ -11,7 +11,7 @@
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
- <h2>{{ title }}</h2>
+ <h2>{{ addon.name }}</h2>
</header>
<section class="primary payments devhub-form" role="main">
{% set contrib = addon.takes_contributions and addon.has_full_profile() or errors %}
View
420 apps/devhub/templates/devhub/versions/list.html
@@ -1,10 +1,6 @@
{% extends "devhub/base.html" %}
-{% if webapp %}
- {% set title = loc('Manage App Status') %}
-{% else %}
- {% set title = _('Status & Versions') %}
-{% endif %}
+{% set title = _('Status & Versions') %}
{% block title %}{{ dev_page_title(title, addon) }}{% endblock %}
{% macro status(msg) %}
@@ -14,158 +10,80 @@
{% block content %}
<header>
{{ dev_breadcrumbs(addon, items=[(None, title)]) }}
- <h2>{{ title }}</h2>
+ <h2>{{ addon.name }}</h2>
</header>
<section id="edit-addon" class="primary devhub-form" role="main">
- <h3>{{ _('Current Status') }}</h3>
- <div class="item" id="version-status">
- <div>
- {% if addon.disabled_by_user and addon.status != amo.STATUS_DISABLED %}
- {% if webapp %}
- {{ status(loc('You have <b>disabled</b> this app.')|safe) }}
- {{ loc("Your app's listing is disabled and is not showing anywhere in
- our gallery. You may re-enable it at any time below.") }}
- {% else %}
- {{ status(_('You have <b>disabled</b> this add-on.')) }}
- {{ _("Your add-on's listing is disabled and is not showing anywhere in our gallery or update service. You may re-enable it at any time below.") }}
- {% endif %}
- {% elif addon.status == amo.STATUS_NULL %}
- {% if webapp %}
- {{ status(loc('This app is <b>incomplete</b>.')|safe) }}
- {% else %}
- {{ status(_('This add-on is <b>incomplete</b>.')) }}
- {% endif %}
- <a href="{{ url('devhub.submit.resume', addon.slug) }}">
- {% if webapp %}
- {{ _('Please complete your app.') -}}
- {% else %}
- {{ _('Please complete your add-on.') -}}
- {% endif %}</a>
- {% elif addon.status == amo.STATUS_PENDING %}
- {{ status(loc('This app is <b>awaiting review</b>.')|safe) }}
- {{ loc('You will receive an email when the review is complete.') }}
- {% elif addon.status == amo.STATUS_UNREVIEWED %}
- {% if webapp %}
- {{ status(loc('This app is <b>awaiting preliminary review</b>.')|safe) }}
- {{ loc("You will receive an email when the review is complete. Until
- then, your app is not listed in our gallery but can be
- accessed directly from its details page.") }}
- {% else %}
- {{ status(_('This add-on is <b>awaiting preliminary review</b>.')) }}
- {{ _("You will receive an email when the review is complete. Until then, your add-on is not listed in our gallery but can be accessed directly from its details page.") }}
- {% endif %}
- {% elif addon.status == amo.STATUS_NOMINATED %}
- {{ status(_('This add-on is <b>awaiting full review</b>.')) }}
- {{ _("You will receive an email when the review is complete. Until then, your add-on is not listed in our gallery but can be accessed directly from its details page. ") }}
- {% elif addon.status == amo.STATUS_PUBLIC %}
- {% if webapp %}
- {{ status(loc('This app is <b>public</b>.')|safe) }}
- {{ loc('Your app is displayed in our gallery.') }}
- {% else %}
- {{ status(_('This add-on has been <b>fully reviewed</b>.')) }}
- {{ _("Your add-on is displayed in our gallery and users are receiving automatic updates.") }}
- {% endif %}
- {% elif addon.status == amo.STATUS_DISABLED %}
- {% if webapp %}
- {{ status(loc('This app has been <b>disabled by Mozilla</b>.')|safe) }}
- {{ loc("Your app was disabled by a site administrator and is no
- longer shown in our gallery. If you have any questions,
- please email marketplace-staff@mozilla.org.") }}
- {% else %}
- {{ status(_('This add-on has been <b>disabled by Mozilla</b>.')) }}
- {{ _("Your add-on was disabled by a site administrator and is no longer shown in our gallery. If you have any questions, please email marketplace-staff@mozilla.org.") }}
- {% endif %}
- {% endif %}
- {% if not webapp %}
- {% if addon.status == amo.STATUS_LITE %}
- {{ status(_('This add-on has been <b>preliminarily reviewed</b>.')) }}
- {{ _("Your add-on is displayed in our gallery as experimental and users are receiving automatic updates. Some features are unavailable to your add-on.") }}
- {% elif addon.status == amo.STATUS_LITE_AND_NOMINATED %}
- {% if webapp %}
- {{ status(loc('This app has been <b>preliminarily reviewed</b> and is <i>awaiting full review</i>.')|safe) }}
- {{ loc("You will receive an email when the full review is complete.
- Until then, your app is displayed in our gallery as
- experimental and users are receiving automatic updates. Some
- features are unavailable to your app.") }}
- {% else %}
- {{ status(_('This add-on has been <b>preliminarily reviewed</b> and is <i>awaiting full review</i>.')) }}
- {{ _("You will receive an email when the full review is complete. Until then, your add-on is displayed in our gallery as experimental and users are receiving automatic updates. Some features are unavailable to your add-on.") }}
+ <div class="item" id="current-version-status">
+ <div class="item_wrapper">
+ <table>
+ <tr>
+ <th>{{ _('Currently on AMO') }}</th>
+ <th>{{ _('Status') }}</th>
+ <th>{{ _('Validation') }}</th>
+ {% if waffle.flag('perf-tests') %}
+ <th>{{ _('Performance') }}</th>
{% endif %}
- {% elif addon.status == amo.STATUS_PURGATORY %}
- {{ status(_('Please select a review option.')) }}
- {{ _("All add-ons hosted in our gallery must now be reviewed by an editor. If you wish to continue hosting your add-on, please select a review process from the choices below.") }}
- {% endif %}
- {% if not (addon.is_disabled or addon.is_incomplete()) %}
- <a href="{{ remora_url('developers/docs/policies/reviews#selection') }}">
- {{ _('Learn more') }}</a>
- {% endif %}
- {% endif %}
-
- <div class="version-status-actions item-actions">
- {% if not webapp %}
- {% if position %}
- <span class="dark" title="{{ _('Queues are not reviewed strictly in order.') }}">
- {% trans pos=position['pos'], total=position['total'] %}
- Queue Position: {{ pos }} of {{ total }}
- {% endtrans %}
- &middot;
+ <th class="version-delete">{{ _('Delete') }}</th>
+ </tr>
+ {% set version = addon.current_version %}
+ <tr>
+ <td>
+ <strong>
+ <a href="{{ url('devhub.versions.edit', addon.slug, version.id) }}"
+ title="{{ _('Edit this version') }}">
+ {{ _('Version {0}', 'addon_display_header_version')|f(version.version) }}</a>
+ </strong>
+ <span title="{{ version.created|isotime }}" class="note">
+ {{ version.created|datetime }}
</span>
- {% endif %}
- {% if check_addon_ownership(request, addon, dev=True) %}
- {% set req = {amo.STATUS_PUBLIC: _('Request Full Review'),
- amo.STATUS_LITE: _('Request Preliminary Review')} %}
- {% for status in addon.can_request_review() %}
- <form method="post"
- action="{{ url('devhub.request-review', addon.slug, status) }}">
- {{ csrf() }}
- <button class="link" type="submit">{{ req[status] }}</button> &middot;
- </form>
+ </td>
+ <td class="file-status">
+ {% for count, status in dev_files_status(version.all_files, addon) %}
+ <div>
+ {# L10n: {0} is the number of files #}
+ {{ status }} ({{ ngettext('{0} file', '{0} files', count)|f(count) }})
+ </div>
+ {% else %}
+ {{ _('0 files') }}
{% endfor %}
- {% set days = addon.days_until_full_nomination() %}
- {% if days != 0 %}
- <span class="warning">{{ ngettext('Full nomination will be available in {0} day',
- 'Full nomination will be available in {0} days',
- days)|f(days) }}</span>
- {% endif %}
- {% if not addon.is_disabled and addon.is_under_review %}
- <a href="#" id="cancel-review">{{ _('Cancel Review Request') }}</a> &middot;
- {% endif %}
- {% endif %}
- {% endif %}
- {% if check_addon_ownership(request, addon, dev=True) %}
- {% if addon.disabled_by_user and addon.status != amo.STATUS_DISABLED %}
- <a href="{{ addon.get_dev_url('enable') }}" id="enable-addon">
- {{ loc('Enable App') if webapp else _('Enable Add-on') }}</a>
- {% elif not addon.is_disabled %}
- <a href="#" id="disable-addon">
- {{ loc('Disable App') if webapp else _('Disable Add-on') }}</a>
- {% endif %}
- {% endif %}
- {% if check_addon_ownership(request, addon) and addon.can_be_deleted() %}
- &middot; <a href="#" id="delete-addon">
- {{ loc('Delete App') if webapp else _('Delete Add-on') }}</a>
- {% endif %}
- {% if not webapp %}
- {% set current = addon.current_version %}
- {% if current %}
- <span class="version-changed">
- {{ _('Displayed version: {0}')|f(current.version) }}
- </span>
+ </td>
+ <td class="file-validation">
+ <ul>
+ {% for file in version.all_files %}
+ <li>{{ file.platform }}
+ <ul>
+ {% if file.has_been_validated %}
+ <li><a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
+ {{ summarize_validation(file.validation) }}</a></li>
+ {% else %}
+ <li>{{ _('Not validated.') }}
+ <a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
+ {{ _('Validate now.') }}</a>
+ </li>
+ {% endif %}
+ </ul>
+ </li>
+ {% endfor %}
+ </ul>
+ </td>
+ {% if waffle.flag('perf-tests') %}
+ <td class="perf-tests">
+ {% include "devhub/addons/listing/perf_file_listing.html" %}
+ </td>
{% endif %}
- {% endif %}
- </div>
+ <td class="version-delete">
+ <a href="#" class="remove" data-version="{{ version.id }}">x</a>
+ </td>
+ </tr>
+ </table>
</div>
</div>
- {% if not webapp %}
- <h3>{{ _('Version History') }}</h3>
- <div class="item" id="version-list"
- data-stats="{{ url('devhub.versions.stats', addon.slug) }}">
+ <div class="item" id="next-version-status">
<div class="item_wrapper">
<table>
<tr>
- <th>{{ _('Version') }}</th>
- <th>{{ _('Submitted') }}</th>
+ <th>{{ _('Next version of this add-on') }}</th>
<th>{{ _('Status') }}</th>
<th>{{ _('Validation') }}</th>
{% if waffle.flag('perf-tests') %}
@@ -173,34 +91,43 @@
{% endif %}
<th class="version-delete">{{ _('Delete') }}</th>
</tr>
- <tr>
- <td colspan="0">
- <a href="#" class="button version-upload">{{ _('Upload a New Version') }}</a>
- </td>
- </tr>
- {% for version in versions.object_list %}
- <tr>
+ {% set version = addon.latest_version %}
+ {% if version_disabled(version) %}
+ <tr>
+ <td colspan="0">
+ <a href="#" class="button version-upload">{{ _('Upload a New Version') }}</a>
+ </td>
+ </tr>
+ {% endif %}
+ <tr{% if version_disabled(version) %} class="version-disabled"{% endif %}>
<td>
<strong>
<a href="{{ url('devhub.versions.edit', addon.slug, version.id) }}"
title="{{ _('Edit this version') }}">
{{ _('Version {0}', 'addon_display_header_version')|f(version.version) }}</a>
</strong>
- </td>
- <td>
- <span title="{{ version.created|isotime }}">
+ <span title="{{ version.created|isotime }}" class="note">
{{ version.created|datetime }}
</span>
</td>
<td class="file-status">
{% for count, status in dev_files_status(version.all_files, addon) %}
- <div>
- {# L10n: {0} is the number of files, {1} is the status #}
- {{ ngettext('{0} file is {1}', '{0} files are {1}', count)|f(count, status) }}
- </div>
+ <div>
+ {# L10n: {0} is the number of files #}
+ {{ status }} ({{ ngettext('{0} file', '{0} files', count)|f(count) }})
+ </div>
{% else %}
- {{ _('0 files') }}
+ {{ _('0 files') }}
{% endfor %}
+ {% with position = get_position(addon) %}
+ {% if position.pos and position.total %}
+ <span class="note">
+ {% trans pos=position.pos|numberfmt, total=position.total|numberfmt %}
+ Queue position: {{ pos }} of {{ total }}
+ {% endtrans %}
+ </li>
+ {% endif %}
+ {% endwith %}
</td>
<td class="file-validation">
<ul>
@@ -230,6 +157,81 @@
<a href="#" class="remove" data-version="{{ version.id }}">x</a>
</td>
</tr>
+ </table>
+ </div>
+ </div>
+
+ <h3>{{ _('Older versions') }}</h3>
+ <div class="item" id="version-list"
+ data-stats="{{ url('devhub.versions.stats', addon.slug) }}">
+ <div class="item_wrapper">
+ <table>
+ <tr>
+ <th>{{ _('Version') }}</th>
+ <th>{{ _('Status') }}</th>
+ <th>{{ _('Validation') }}</th>
+ {% if waffle.flag('perf-tests') %}
+ <th>{{ _('Performance') }}</th>
+ {% endif %}
+ <th class="version-delete">{{ _('Delete') }}</th>
+ </tr>
+ <tr>
+ <td colspan="0">
+ <a href="#" class="button version-upload">{{ _('Upload a New Version') }}</a>
+ </td>
+ </tr>
+ {% for version in versions.object_list %}
+ {% if version != addon.current_version and version != addon.latest_version %}
+ <tr{% if version_disabled(version) %} class="version-disabled"{% endif %}>
+ <td>
+ <strong>
+ <a href="{{ url('devhub.versions.edit', addon.slug, version.id) }}"
+ title="{{ _('Edit this version') }}">
+ {{ _('Version {0}', 'addon_display_header_version')|f(version.version) }}</a>
+ </strong>
+ <span title="{{ version.created|isotime }}" class="note">
+ {{ version.created|datetime }}
+ </span>
+ </td>
+ <td class="file-status">
+ {% for count, status in dev_files_status(version.all_files, addon) %}
+ <div>
+ {# L10n: {0} is the number of files #}
+ {{ status }} ({{ ngettext('{0} file', '{0} files', count)|f(count) }})
+ </div>
+ {% else %}
+ {{ _('0 files') }}
+ {% endfor %}
+ </td>
+ <td class="file-validation">
+ <ul>
+ {% for file in version.all_files %}
+ <li>{{ file.platform }}
+ <ul>
+ {% if file.has_been_validated %}
+ <li><a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
+ {{ summarize_validation(file.validation) }}</a></li>
+ {% else %}
+ <li>{{ _('Not validated.') }}
+ <a href="{{ url('devhub.file_validation', addon.slug, file.id) }}">
+ {{ _('Validate now.') }}</a>
+ </li>
+ {% endif %}
+ </ul>
+ </li>
+ {% endfor %}
+ </ul>
+ </td>
+ {% if waffle.flag('perf-tests') %}
+ <td class="perf-tests">
+ {% include "devhub/addons/listing/perf_file_listing.html" %}
+ </td>
+ {% endif %}
+ <td class="version-delete">
+ <a href="#" class="remove" data-version="{{ version.id }}">x</a>
+ </td>
+ </tr>
+ {% endif %}
{% endfor %}
</table>
</div>
@@ -239,7 +241,6 @@
</div>
{% endif %}
</div>
- {% endif %}
</section>
@@ -251,75 +252,64 @@
</div>
{% endif %}
- {% if not webapp %}
- <div id="modal-delete-version" class="modal modal-delete">
- <form method="post" action="{{ url('devhub.versions.delete', addon.slug) }}">
- <h3 data-tmpl="{{ _('Delete Version {version}') }}"></h3>
- <p>{{ _('Deleting this version will permanently delete:') }}</p>
- <ul>
- <li id="del-files"></li>
- <li id="del-reviews"></li>
- </ul>
- <p>
- {% trans %}
- <strong>Important:</strong>
- Once a version has been deleted, you may not upload a new
- version with the same version number.
- {% endtrans %}
- <p>{{ _('Deleting a version which has already been reviewed
- may also cause a significant delay in the review of
- your next update.') }}</p>
- <p>{{ _('Are you sure you wish to delete this version?') }}</p>
- {{ csrf() }}
- <div class="modal-actions">
- <input type="hidden" name="version_id" class="version_id">
- <input type="hidden" name="addon_id" class="addon_id" value="{{ addon.id }}">
- <button type="submit" class="delete-button">{{ _('Delete Version') }}</button>
- <button type="submit" class="disable-button" name="disable_version">
- {{ _('Disable Version') }}
- </button>
- {{ _('or') }} <a href="#" class="close">{{ _('Cancel') }}</a>
- </div>
- </form>
- </div>
+ <div id="modal-delete-version" class="modal modal-delete">
+ <form method="post" action="{{ url('devhub.versions.delete', addon.slug) }}">
+ <h3 data-tmpl="{{ _('Delete Version {version}') }}"></h3>
+ <p>{{ _('Deleting this version will permanently delete:') }}</p>
+ <ul>
+ <li id="del-files"></li>
+ <li id="del-reviews"></li>
+ </ul>
+ <p>
+ {% trans %}
+ <strong>Important:</strong>
+ Once a version has been deleted, you may not upload a new
+ version with the same version number.
+ {% endtrans %}
+ <p>{{ _('Deleting a version which has already been reviewed
+ may also cause a significant delay in the review of
+ your next update.') }}</p>
+ <p>{{ _('Are you sure you wish to delete this version?') }}</p>
+ {{ csrf() }}
+ <div class="modal-actions">
+ <input type="hidden" name="version_id" class="version_id">
+ <input type="hidden" name="addon_id" class="addon_id" value="{{ addon.id }}">
+ <button type="submit" class="delete-button">{{ _('Delete Version') }}</button>
+ <button type="submit" class="disable-button" name="disable_version">
+ {{ _('Disable Version') }}
+ </button>
+ {{ _('or') }} <a href="#" class="close">{{ _('Cancel') }}</a>
+ </div>
+ </form>
+ </div>
- {{ add_version_modal(_("Add a new Version"),
- url('devhub.versions.add', addon.slug),
- url('devhub.upload_for_addon', addon.slug), _("Add Version") )}}
- {% endif %}
+ {{ add_version_modal(_("Add a new Version"),
+ url('devhub.versions.add', addon.slug),
+ url('devhub.upload_for_addon', addon.slug), _("Add Version") )}}
{% if not addon.disabled_by_user and not addon.is_disabled %}
<div id="modal-disable" class="modal">
<form method="post" action="{{ addon.get_dev_url('disable') }}">
<h3>
- {{ loc('Disable App') if webapp else _('Disable Add-on') }}
+ {{ _('Disable Add-on') }}
</h3>
<p>
- {% if webapp %}
- {{ loc('Disabling your app will prevent it from appearing anywhere
- in our gallery.') }}
- {% else %}
- {% trans %}
- Disabling your add-on will prevent it from appearing anywhere in our
- gallery and will stop users from receiving automatic updates.
- {% endtrans %}
- {% endif %}
+ {% trans %}
+ Disabling your add-on will prevent it from appearing anywhere in our
+ gallery and will stop users from receiving automatic updates.
+ {% endtrans %}
</p>
<p>
- {% if webapp %}
- {{ loc('Are you sure you wish to disable your app?') }}
- {% else %}
- {% trans %}
- Are you sure you wish to disable your add-on?
- {% endtrans %}
- {% endif %}
+ {% trans %}
+ Are you sure you wish to disable your add-on?
+ {% endtrans %}
</p>
{{ csrf() }}
<input type="hidden" name="version_id" class="version_id">
<input type="hidden" name="addon_id" class="addon_id" value="{{ addon.id }}">
<p>
<button type="submit">
- {{ loc('Disable App') if webapp else _('Disable Add-on') }}
+ {{ _('Disable Add-on') }}
</button>
{{ _('or') }} <a href="#" class="close">{{ _('Cancel') }}</a>
</p>
@@ -327,7 +317,7 @@ <h3 data-tmpl="{{ _('Delete Version {version}') }}"></h3>
</div>
{% endif %}
- {% if not webapp and not addon.is_disabled and addon.is_under_review %}
+ {% if not addon.is_disabled and addon.is_under_review %}
<div id="modal-cancel" class="modal">
<form method="post" action="{{ url('devhub.addons.cancel', addon.slug) }}">
<h3>{{ _('Cancel Review Request') }}</h3>
View
10 apps/devhub/tests/test_views_versions.py
@@ -221,25 +221,25 @@ def test_show_disable_button(self):
res = self.client.get(self.url)
doc = pq(res.content)
assert doc('#modal-disable')
- assert doc('#disable-addon')
- assert not doc('#enable-addon')
+ assert doc('.disable-addon')
+ assert not doc('.enable-addon')
def test_not_show_disable(self):
self.addon.update(status=amo.STATUS_DISABLED, disabled_by_user=False)
res = self.client.get(self.url)
doc = pq(res.content)
assert not doc('#modal-disable')
- assert not doc('#disable-addon')
+ assert not doc('.disable-addon')
def test_show_enable_button(self):
self.addon.update(disabled_by_user=True)
res = self.client.get(self.url)
doc = pq(res.content)
- a = doc('#enable-addon')
+ a = doc('.enable-addon')
assert a, "Expected Enable addon link"
eq_(a.attr('href'), self.enable_url)
assert not doc('#modal-disable')
- assert not doc('#disable-addon')
+ assert not doc('.disable-addon')
def test_cancel_get(self):
cancel_url = reverse('devhub.addons.cancel', args=['a3615'])
View
2  apps/devhub/views.py
@@ -1002,7 +1002,7 @@ def json_upload_detail(request, upload, addon_slug=None):
plat_exclude = set(s) - set(supported_platforms)
plat_exclude = [str(p) for p in plat_exclude]
- result['platforms_to_exclude'] = plat_exclude
+ #result['platforms_to_exclude'] = plat_exclude
return result
View
15 media/css/devhub/forms.less
@@ -16,10 +16,19 @@
border-top: medium none;
}
}
+ tr.version-disabled {
+ opacity: 0.5;
+ }
th {
- padding-right: 20px;
+ color: #888;
+ font-size: 11px;
+ padding: 0 0 5px;
vertical-align: top;
width: 130px;
+ &.version-delete {
+ text-align: right;
+ width: 35px;
+ }
}
ul {
margin: 0;
@@ -31,6 +40,10 @@
width: 100px;
height: 75px;
}
+ .note {
+ color: @note-gray;
+ display: block;
+ }
}
table, tbody {
border-top: medium none;
View
80 media/css/impala/developers.less
@@ -69,6 +69,13 @@
right: 0;
}
}
+ ul.refinements li a {
+ padding: 0 10px 0 0;
+ }
+
+ ul.refinements li.selected a {
+ background: url("../../img/zamboni/arrow-left-blue.png") 100% .5em no-repeat;
+ }
}
}
@@ -356,6 +363,79 @@
}
}
+/* Devhub navigation panel */
+.secondary {
+ .addon-status {
+ background: white;
+ border: 1px solid @border-blue;
+ border-radius: 8px;
+ clear: both;
+ color: @medium-gray;
+ margin: 0 0 12px;
+ padding: 10px;
+ position: relative;
+ img {
+ left: 10px;
+ position: absolute;
+ top: 12px;
+ }
+ .addon-details {
+ font-size: 12px;
+ margin: 0 0 5px 45px;
+ li:first-child {
+ color: #444;
+ }
+ .tip {
+ border-radius: 6px;
+ font-size: 10px;
+ height: 12px;
+ line-height: 14px;
+ margin-left: 3px;
+ width: 12px;
+ }
+ }
+ .addon-upload {
+ border-top: 1px dotted #94bfce;
+ font-size: 11px;
+ margin: 0;
+ padding-top: 5px;
+ }
+ }
+ ul.refinements {
+ border-bottom: 1px dotted #94bfce;
+ margin-bottom: 1em;
+ padding-bottom: 1em;
+ &:last-child {
+ border-bottom: none;
+ }
+ li a {
+ color: #3d6db5;
+ font-size: .923em;
+ padding: 0 0 0 10px;
+ }
+ li.addon-manage a {
+ display: inline;
+ &:last-child {
+ padding-left: 0;
+ &:before {
+ content: "\00b7";
+ padding-right: 5px;
+ }
+ }
+ &:only-child {
+ padding-left: 10px;
+ &:before {
+ content: "";
+ padding: 0;
+ }
+ }
+ }
+ li.selected a {
+ background: url("../../img/zamboni/arrow-right-blue.png") 0 .5em no-repeat;
+ }
+ }
+}
+
.modal p,
.popup p {
line-height: 1.3;
View
25 media/css/zamboni/zamboni.css
@@ -2252,37 +2252,12 @@ form .error .note.error {
color: #235;
}
-.secondary ul.refinements {
- border-bottom: 1px dotted #94bfce;
- padding-bottom: 1em;
- margin-bottom: 1em;
-}
-
#refine-results div:last-child ul.refinements {
border-bottom: 0;
margin-bottom: 0;
padding-bottom: 0;
}
-.secondary ul.refinements li a {
- color: #3d6db5;
- padding: 0 0 0 10px;
- font-weight: bold;
- font-size: .923em;
-}
-
-.html-rtl .secondary ul.refinements li a {
- padding: 0 10px 0 0;
-}
-
-.secondary ul.refinements li.selected a {
- background: transparent url("../../img/zamboni/arrow-right-blue.png") 0 .5em no-repeat;
-}
-
-.html-rtl .secondary ul.refinements li.selected a {
- background: transparent url("../../img/zamboni/arrow-left-blue.png") 100% .5em no-repeat;
-}
-
/** =Report abuse form *********/
.abuse {
border: 0;
View
36 media/js/zamboni/devhub.js
@@ -78,7 +78,7 @@ $(document).ready(function() {
$('.addon-upload-failure-dependant').attr('disabled', true);
}
- if ($(".version-upload").length) {
+ if ($(".add-file-modal").length) {
$modal = $(".add-file-modal").modal(".version-upload", {
width: '450px',
hideme: false,
@@ -288,21 +288,31 @@ $(document).ready(function() {
// hook up various links related to current version status
$('#modal-cancel').modal('#cancel-review', {width: 400});
- $('#modal-delete').modal('#delete-addon', {
- width: 400,
- callback: function(obj) {
- return fixPasswordField(this);
+ if ($("#modal-delete").length) {
+ $('#modal-delete').modal('.delete-addon', {
+ width: 400,
+ callback: function(obj) {
+ return fixPasswordField(this);
+ }
+ });
+ if (window.location.hash === '#delete-addon') {
+ $modal.render();
}
- });
- $('#modal-disable').modal('#disable-addon', {
- width: 400,
- callback: function(d){
- $('.version_id', this).val($(d.click_target).attr('data-version'));
- return true;
+ }
+ if ($("#modal-disable").length) {
+ $modal = $('#modal-disable').modal('.disable-addon', {
+ width: 400,
+ callback: function(d){
+ $('.version_id', this).val($(d.click_target).attr('data-version'));
+ return true;
+ }
+ });
+ if (window.location.hash === '#disable-addon') {
+ $modal.render();
}
- });
+ }
- $('#enable-addon').bind('click', _pd(function() {
+ $('.enable-addon').bind('click', _pd(function() {
$.ajax({
'type': 'POST',
'url': $(this).attr('href'),
Something went wrong with that request. Please try again.