From 52fe5c556c90c83d86e031ac68ef3f03d7ae54ae Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 23 Dec 2016 01:20:52 -0400 Subject: [PATCH] Refactor folder add document using MultipleObjectFormActionView. Add support for adding a document to multiple folders at the same time. --- docs/releases/2.2.rst | 1 + .../appearance/static/appearance/css/base.css | 2 +- .../appearance/static/appearance/js/base.js | 6 +- mayan/apps/folders/forms.py | 12 +- mayan/apps/folders/urls.py | 12 +- mayan/apps/folders/views.py | 146 +++++++++--------- mayan/apps/tags/forms.py | 4 +- 7 files changed, 97 insertions(+), 86 deletions(-) diff --git a/docs/releases/2.2.rst b/docs/releases/2.2.rst index a3e7fb8bbd..d795eeb1b7 100644 --- a/docs/releases/2.2.rst +++ b/docs/releases/2.2.rst @@ -31,6 +31,7 @@ the user links - DEBUG now defaults to False. - Production settings don't override the DEBUG variable. DEBUG can be set to True on production install to debug errors live. +- Refactor add document to folder view to allow adding a documents to multiple folders at the same time. Removals -------- diff --git a/mayan/apps/appearance/static/appearance/css/base.css b/mayan/apps/appearance/static/appearance/css/base.css index 7c2e972208..ace6e9cf3d 100644 --- a/mayan/apps/appearance/static/appearance/css/base.css +++ b/mayan/apps/appearance/static/appearance/css/base.css @@ -160,7 +160,7 @@ a i { text-shadow: 1px 1px 1px rgba(0,0,0,0.3); } -.select2-container--default .select2-selection--multiple .select2-selection__choice { +.select2-container--default .select2-selection--multiple .select2-selection__choice .label { padding-bottom: 1px; } diff --git a/mayan/apps/appearance/static/appearance/js/base.js b/mayan/apps/appearance/static/appearance/js/base.js index 1b3d87f94b..22c967fcee 100644 --- a/mayan/apps/appearance/static/appearance/js/base.js +++ b/mayan/apps/appearance/static/appearance/js/base.js @@ -120,8 +120,12 @@ jQuery(document).ready(function() { }, 3000); - $('.select2').select2({ + $('.select2').select2(); + + $('.select2-tags').select2({ templateSelection: tagSelectionTemplate, templateResult: tagResultTemplate }); + + }); diff --git a/mayan/apps/folders/forms.py b/mayan/apps/folders/forms.py index cb20818141..d0f384726a 100644 --- a/mayan/apps/folders/forms.py +++ b/mayan/apps/folders/forms.py @@ -15,14 +15,20 @@ logger = logging.getLogger(__name__) class FolderListForm(forms.Form): def __init__(self, *args, **kwargs): + help_text = kwargs.pop('help_text', None) + permission = kwargs.pop('permission', None) + queryset = kwargs.pop('queryset', Folder.objects.all()) user = kwargs.pop('user', None) + logger.debug('user: %s', user) super(FolderListForm, self).__init__(*args, **kwargs) queryset = AccessControlList.objects.filter_by_access( - permission_folder_view, user, queryset=Folder.objects.all() + permission, user, queryset=queryset ) - self.fields['folder'] = forms.ModelChoiceField( - queryset=queryset, label=_('Folder') + self.fields['folders'] = forms.ModelMultipleChoiceField( + label=_('Folders'), help_text=help_text, + queryset=queryset, required=False, + widget=forms.SelectMultiple(attrs={'class': 'select2'}) ) diff --git a/mayan/apps/folders/urls.py b/mayan/apps/folders/urls.py index 0389332d48..2f6746f15c 100644 --- a/mayan/apps/folders/urls.py +++ b/mayan/apps/folders/urls.py @@ -7,9 +7,9 @@ from .api_views import ( APIFolderDocumentView, APIFolderListView, APIFolderView ) from .views import ( - DocumentFolderListView, FolderCreateView, FolderDeleteView, - FolderDetailView, FolderEditView, FolderListView, folder_add_document, - folder_add_multiple_documents, folder_document_multiple_remove + DocumentFolderListView, FolderAddDocumentView, FolderCreateView, + FolderDeleteView, FolderDetailView, FolderEditView, FolderListView, + folder_document_multiple_remove ) urlpatterns = [ @@ -28,11 +28,11 @@ urlpatterns = [ ), url( - r'^document/(?P\d+)/folder/add/$', - folder_add_document, name='folder_add_document' + r'^document/(?P\d+)/folder/add/$', + FolderAddDocumentView.as_view(), name='folder_add_document' ), url( - r'^document/multiple/folder/add/$', folder_add_multiple_documents, + r'^document/multiple/folder/add/$', FolderAddDocumentView.as_view(), name='folder_add_multiple_documents' ), url( diff --git a/mayan/apps/folders/views.py b/mayan/apps/folders/views.py index 90d01b6896..f78eea7b79 100644 --- a/mayan/apps/folders/views.py +++ b/mayan/apps/folders/views.py @@ -12,8 +12,8 @@ from django.utils.translation import ugettext_lazy as _, ungettext from acls.models import AccessControlList from common.views import ( - SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, - SingleObjectListView + MultipleObjectFormActionView, SingleObjectCreateView, + SingleObjectDeleteView, SingleObjectEditView, SingleObjectListView ) from documents.permissions import permission_document_view from documents.models import Document @@ -123,81 +123,87 @@ class DocumentFolderListView(FolderListView): return self.document.document_folders().all() -def folder_add_document(request, document_id=None, document_id_list=None): - if document_id: - queryset = Document.objects.filter(pk=document_id) - elif document_id_list: - queryset = Document.objects.filter(pk__in=document_id_list) +class FolderAddDocumentView(MultipleObjectFormActionView): + form_class = FolderListForm + model = Document + success_message = _( + 'Add to folder request performed on %(count)d document' + ) + success_message_plural = _( + 'Add to folder request performed on %(count)d documents' + ) - if not queryset: - messages.error(request, _('Must provide at least one document.')) - return HttpResponseRedirect( - request.META.get( - 'HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL) + def get_extra_context(self): + queryset = self.get_queryset() + + result = { + 'submit_label': _('Add'), + 'title': ungettext( + 'Add document to folders', + 'Add documents to folders', + queryset.count() ) - ) + } - queryset = AccessControlList.objects.filter_by_access( - permission_folder_add_document, request.user, queryset=queryset - ) + if queryset.count() == 1: + result.update( + { + 'object': queryset.first(), + 'title': _( + 'Add document "%s" to folders' + ) % queryset.first() + } + ) - post_action_redirect = None - if document_id: - post_action_redirect = reverse( - 'folders:document_folder_list', args=(document_id,) - ) + return result - previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) - next = request.POST.get('next', request.GET.get('next', post_action_redirect if post_action_redirect else request.META.get('HTTP_REFERER', reverse(settings.LOGIN_REDIRECT_URL)))) + def get_form_extra_kwargs(self): + queryset = self.get_queryset() + result = { + 'help_text': _('Folders to which the selected documents will be added.'), + 'permission': permission_folder_add_document, + 'user': self.request.user + } - if request.method == 'POST': - form = FolderListForm(request.POST, user=request.user) - if form.is_valid(): - folder = form.cleaned_data['folder'] - for document in queryset: - if document.pk not in folder.documents.values_list('pk', flat=True): - folder.documents.add(document) - messages.success( - request, _( - 'Document: %(document)s added to folder: ' - '%(folder)s successfully.' - ) % { - 'document': document, 'folder': folder - } - ) - else: - messages.warning( - request, _( - 'Document: %(document)s is already in ' - 'folder: %(folder)s.' - ) % { - 'document': document, 'folder': folder - } + if queryset.count() == 1: + result.update( + { + 'queryset': Folder.objects.exclude( + pk__in=queryset.first().folders.all() ) + } + ) - return HttpResponseRedirect(next) - else: - form = FolderListForm(user=request.user) + return result - context = { - 'form': form, - 'previous': previous, - 'next': next, - } + def object_action(self, form, instance): + folder_membership = instance.folders.all() - if queryset.count() == 1: - context['object'] = queryset.first() + for folder in form.cleaned_data['folders']: + AccessControlList.objects.check_access( + obj=folder, permissions=permission_folder_add_document, + user=self.request.user + ) - context['title'] = ungettext( - 'Add document to folder', - 'Add documents to folder', - queryset.count() - ) - - return render_to_response( - 'appearance/generic_form.html', context, - context_instance=RequestContext(request) - ) + if folder in folder_membership: + messages.warning( + self.request, _( + 'Document: %(document)s is already in ' + 'folder: %(folder)s.' + ) % { + 'document': instance, 'folder': folder + } + ) + else: + folder.documents.add(instance) + messages.success( + self.request, _( + 'Document: %(document)s added to folder: ' + '%(folder)s successfully.' + ) % { + 'document': instance, 'folder': folder + } + ) def folder_document_remove(request, folder_id, document_id=None, document_id_list=None): @@ -267,11 +273,3 @@ def folder_document_multiple_remove(request, folder_id): 'id_list', request.POST.get('id_list', '') ).split(',') ) - - -def folder_add_multiple_documents(request): - return folder_add_document( - request, document_id_list=request.GET.get( - 'id_list', request.POST.get('id_list', '') - ).split(',') - ) diff --git a/mayan/apps/tags/forms.py b/mayan/apps/tags/forms.py index 6e8d8b9a86..7fbff833ff 100644 --- a/mayan/apps/tags/forms.py +++ b/mayan/apps/tags/forms.py @@ -30,5 +30,7 @@ class TagMultipleSelectionForm(forms.Form): self.fields['tags'] = forms.ModelMultipleChoiceField( label=_('Tags'), help_text=help_text, queryset=queryset, required=False, - widget=TagFormWidget(attrs={'class': 'select2'}, queryset=queryset) + widget=TagFormWidget( + attrs={'class': 'select2-tags'}, queryset=queryset + ) )