Implement Web Assets' theme system and selection, and add 'light' theme #118
@ -111,6 +111,17 @@ class ExtensionUpdateForm(forms.ModelForm):
|
|||||||
'support',
|
'support',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
if (
|
||||||
|
'convert_to_draft' in self.data
|
||||||
|
and self.instance.status != self.instance.STATUSES.AWAITING_REVIEW
|
||||||
|
):
|
||||||
|
self.add_error(
|
||||||
|
None, 'An extension can be converted to draft only while it is Awating Review'
|
||||||
|
)
|
||||||
|
return self.cleaned_data
|
||||||
|
|
||||||
|
|
||||||
class ExtensionDeleteForm(forms.ModelForm):
|
class ExtensionDeleteForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
@ -97,13 +97,22 @@
|
|||||||
|
|
||||||
<section class="card p-3 mt-3">
|
<section class="card p-3 mt-3">
|
||||||
<div class="btn-col">
|
<div class="btn-col">
|
||||||
<button id="btn-save" type="submit" class="btn btn-primary">
|
<button id="btn-save" type="submit" class="btn btn-primary" name="save">
|
||||||
<i class="i-check"></i>
|
<i class="i-check"></i>
|
||||||
<span>
|
<span>
|
||||||
{% trans 'Save Changes' %}
|
{% trans 'Save Changes' %}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
{% if extension.status == extension.STATUSES.AWAITING_REVIEW %}
|
||||||
|
<button id="btn-convert-to-draft" type="submit" class="btn" name="convert_to_draft">
|
||||||
|
<i class="i-refresh"></i>
|
||||||
|
<span>
|
||||||
|
{% trans 'Convert to Draft' %}
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<a href="{{ extension.get_new_version_url }}" class="btn">
|
<a href="{{ extension.get_new_version_url }}" class="btn">
|
||||||
|
@ -2,9 +2,11 @@ from pathlib import Path
|
|||||||
|
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
|
||||||
from common.tests.factories.extensions import create_approved_version
|
from common.tests.factories.extensions import create_approved_version, create_version
|
||||||
from common.tests.utils import _get_all_form_errors
|
from common.tests.utils import _get_all_form_errors
|
||||||
|
from extensions.models import Extension
|
||||||
from files.models import File
|
from files.models import File
|
||||||
|
from reviewers.models import ApprovalActivity
|
||||||
|
|
||||||
TEST_FILES_DIR = Path(__file__).resolve().parent / 'files'
|
TEST_FILES_DIR = Path(__file__).resolve().parent / 'files'
|
||||||
POST_DATA = {
|
POST_DATA = {
|
||||||
@ -280,3 +282,28 @@ class UpdateTest(TestCase):
|
|||||||
response.context['add_preview_formset'].forms[0].errors,
|
response.context['add_preview_formset'].forms[0].errors,
|
||||||
{'source': ['Choose a JPEG, PNG or WebP image, or an MP4 video']},
|
{'source': ['Choose a JPEG, PNG or WebP image, or an MP4 video']},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_convert_to_draft(self):
|
||||||
|
version = create_version(extension__status=Extension.STATUSES.AWAITING_REVIEW)
|
||||||
|
extension = version.extension
|
||||||
|
url = extension.get_manage_url()
|
||||||
|
user = extension.authors.first()
|
||||||
|
self.client.force_login(user)
|
||||||
|
response = self.client.get(url)
|
||||||
|
self.assertContains(response, 'convert_to_draft')
|
||||||
|
response2 = self.client.post(
|
||||||
|
url,
|
||||||
|
{
|
||||||
|
**POST_DATA,
|
||||||
|
'convert_to_draft': '',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.assertEqual(response2.status_code, 302)
|
||||||
|
extension.refresh_from_db()
|
||||||
|
self.assertEqual(extension.status, extension.STATUSES.INCOMPLETE)
|
||||||
|
self.assertEqual(
|
||||||
|
extension.review_activity.last().type, ApprovalActivity.ActivityType.AWAITING_CHANGES
|
||||||
|
)
|
||||||
|
response3 = self.client.get(url)
|
||||||
|
self.assertEqual(response3.status_code, 302)
|
||||||
|
self.assertEqual(response3['Location'], extension.get_draft_url())
|
||||||
|
@ -3,7 +3,7 @@ from django import forms
|
|||||||
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
|
||||||
from django.contrib.messages.views import SuccessMessageMixin
|
from django.contrib.messages.views import SuccessMessageMixin
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.shortcuts import get_object_or_404, reverse
|
from django.shortcuts import get_object_or_404, redirect, reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.views.generic import DetailView, ListView
|
from django.views.generic import DetailView, ListView
|
||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
|
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
|
||||||
@ -109,6 +109,14 @@ class UpdateExtensionView(
|
|||||||
template_name = 'extensions/manage/update.html'
|
template_name = 'extensions/manage/update.html'
|
||||||
form_class = ExtensionUpdateForm
|
form_class = ExtensionUpdateForm
|
||||||
success_message = "Updated successfully"
|
success_message = "Updated successfully"
|
||||||
|
msg_converted_to_draft = _('Converted to Draft')
|
||||||
|
|
||||||
|
def get(self, request, *args, **kwargs):
|
||||||
|
extension = self.extension
|
||||||
|
if extension.status == extension.STATUSES.INCOMPLETE:
|
||||||
|
return redirect('extensions:draft', slug=extension.slug, type_slug=extension.type_slug)
|
||||||
|
else:
|
||||||
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_success_url(self):
|
def get_success_url(self):
|
||||||
self.object.refresh_from_db()
|
self.object.refresh_from_db()
|
||||||
@ -147,6 +155,15 @@ class UpdateExtensionView(
|
|||||||
|
|
||||||
@transaction.atomic
|
@transaction.atomic
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
if 'convert_to_draft' in self.request.POST:
|
||||||
|
form.instance.status = form.instance.STATUSES.INCOMPLETE
|
||||||
|
form.save()
|
||||||
|
ApprovalActivity(
|
||||||
|
user=self.request.user,
|
||||||
|
extension=form.instance,
|
||||||
|
type=ApprovalActivity.ActivityType.AWAITING_CHANGES,
|
||||||
|
message=self.msg_converted_to_draft,
|
||||||
|
).save()
|
||||||
edit_preview_formset = EditPreviewFormSet(
|
edit_preview_formset = EditPreviewFormSet(
|
||||||
self.request.POST, self.request.FILES, instance=self.object
|
self.request.POST, self.request.FILES, instance=self.object
|
||||||
)
|
)
|
||||||
@ -357,7 +374,7 @@ class DraftExtensionView(
|
|||||||
):
|
):
|
||||||
template_name = 'extensions/draft_finalise.html'
|
template_name = 'extensions/draft_finalise.html'
|
||||||
form_class = VersionForm
|
form_class = VersionForm
|
||||||
msg_awaiting_review = _('Extension is ready for initial review')
|
msg_awaiting_review = _('Ready for review')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def success_message(self) -> str:
|
def success_message(self) -> str:
|
||||||
|
Loading…
Reference in New Issue
Block a user