diff --git a/apps/common/api.py b/apps/common/api.py index 4637f3a0fa..6d62a770eb 100644 --- a/apps/common/api.py +++ b/apps/common/api.py @@ -9,9 +9,27 @@ menu_links = [] model_list_columns = {} - def register_multi_item_links(src, links, menu_name=None): - pass + if menu_name in multi_object_navigation: + if hasattr(src, '__iter__'): + for one_src in src: + if one_src in object_navigation[menu_name]: + multi_object_navigation[menu_name][one_src]['links'].extend(links) + else: + multi_object_navigation[menu_name][one_src] = {'links':copy.copy(links)} + else: + if src in multi_object_navigation[menu_name]: + multi_object_navigation[menu_name][src]['links'].extend(links) + else: + multi_object_navigation[menu_name][src] = {'links':links} + else: + multi_object_navigation[menu_name] = {} + if hasattr(src, '__iter__'): + for one_src in src: + multi_object_navigation[menu_name][one_src] = {'links':links} + else: + multi_object_navigation[menu_name] = {src:{'links':links}} + def register_links(src, links, menu_name=None): if menu_name in object_navigation: @@ -20,7 +38,7 @@ def register_links(src, links, menu_name=None): if one_src in object_navigation[menu_name]: object_navigation[menu_name][one_src]['links'].extend(links) else: - object_navigation[menu_name][one_src]={'links':copy.copy(links)} + object_navigation[menu_name][one_src] = {'links':copy.copy(links)} else: if src in object_navigation[menu_name]: object_navigation[menu_name][src]['links'].extend(links) diff --git a/apps/common/forms.py b/apps/common/forms.py index 9834f18b3c..b05465eb6d 100644 --- a/apps/common/forms.py +++ b/apps/common/forms.py @@ -3,13 +3,20 @@ from django.utils.safestring import mark_safe from django.utils.translation import ugettext as _ from django.db import models from django.conf import settings - +from django.template.defaultfilters import capfirst from common.utils import return_attrib class MultiItemForm(forms.Form): - action = forms.ChoiceField() + def __init__(self, *args, **kwargs): + actions = kwargs.pop('actions', []) + super(MultiItemForm, self).__init__(*args, **kwargs) + choices = [('', '------')] + choices.extend([(action[0], capfirst(action[1])) for action in actions]) + self.fields['action'].choices = choices + + action = forms.ChoiceField(label=_(u'Multi item action')) class DetailSelectMultiple(forms.widgets.SelectMultiple): diff --git a/apps/common/templates/generic_list.html b/apps/common/templates/generic_list.html index 778d9764b5..4ea2143b03 100644 --- a/apps/common/templates/generic_list.html +++ b/apps/common/templates/generic_list.html @@ -1,5 +1,6 @@ {% extends "base.html" %} {% load i18n %} +{% load navigation %} {% block title %} :: {% blocktrans %}List of {{ title }}{% endblocktrans %}{% endblock %} {#{% block secondary_links %}{{ secondary_links|safe }}{% endblock %}#} diff --git a/apps/common/templates/generic_list_subtemplate.html b/apps/common/templates/generic_list_subtemplate.html index fd91f47b5f..22ef91dd83 100644 --- a/apps/common/templates/generic_list_subtemplate.html +++ b/apps/common/templates/generic_list_subtemplate.html @@ -22,74 +22,84 @@ {% endifnotequal %} -
+
{% endif %} -
- - - {% if not hide_header %} - - {% if multi_select %} - - {% endif %} - {% if not hide_object %} - - {% endif %} - {% for column in object_list.0|get_model_list_columns %} - - {% endfor %} - {% for column in extra_columns %} - - {% endfor %} - {% if not hide_links %} - - {% endif %} - - {% endif %} - {% for object in object_list %} - - {% if multi_select %} - - {% endif %} - {% if not hide_object %} - {% if main_object %} - {% with object|object_property:main_object as object %} - - {% endwith %} - {% else %} - - {% endif %} - {% endif %} - {% if not hide_columns %} - {% for column in object|get_model_list_columns %} - - {% endfor %} - {% endif %} - {% for column in extra_columns %} - {% if column.keep_together %} - - {% else %} - + +
{% trans "Identifier" %}{{ column.name|capfirst }}{{ column.name|capfirst }} 
{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}{{ object|object_property:column.attribute|safe }} - {{ object|object_property:column.attribute|safe|make_non_breakable }} - {{ object|object_property:column.attribute|safe }}
+ + {% if not hide_header %} + + {% if multi_select %} + + {% endif %} + {% if not hide_object %} + + {% endif %} + {% for column in object_list.0|get_model_list_columns %} + + {% endfor %} + {% for column in extra_columns %} + + {% endfor %} + {% if not hide_links %} + + {% endif %} + {% endif %} - {% endfor %} - {% if not hide_links %} - - {% endif %} - - {% empty %} - - {% endfor %} - -
{% trans "Identifier" %}{{ column.name|capfirst }}{{ column.name|capfirst }} 
- {% object_navigation_template %} -
{% blocktrans %}There are no {{ title }}{% endblocktrans %}
- {% if multi_select %} - {% get_multi_item_links_form %} - {% endif %} - {% paginate %} -
-
+ {% for object in object_list %} + + {% if multi_select %} + + {% endif %} + {% if not hide_object %} + {% if main_object %} + {% with object|object_property:main_object as object %} + {% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %} + {% endwith %} + {% else %} + {% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %} + {% endif %} + {% endif %} + {% if not hide_columns %} + {% for column in object|get_model_list_columns %} + {{ object|object_property:column.attribute|safe }} + {% endfor %} + {% endif %} + {% for column in extra_columns %} + {% if column.keep_together %} + + {{ object|object_property:column.attribute|safe|make_non_breakable }} + + {% else %} + {{ object|object_property:column.attribute|safe }} + {% endif %} + {% endfor %} + {% if not hide_links %} + + {% object_navigation_template %} + + {% endif %} + + {% empty %} + {% blocktrans %}There are no {{ title }}{% endblocktrans %} + {% endfor %} + + + {% if multi_select %} + {% get_multi_item_links_form %} + + {% endif %} + + + {% paginate %} + + {% if side_bar %} +

+ {% endif %} +
diff --git a/apps/common/templatetags/navigation.py b/apps/common/templatetags/navigation.py index 0a1fcafae5..4daf26ab83 100644 --- a/apps/common/templatetags/navigation.py +++ b/apps/common/templatetags/navigation.py @@ -9,7 +9,8 @@ from django.template import TemplateSyntaxError, Library, \ from django.utils.text import unescape_string_literal from django.utils.translation import ugettext as _ -from common.api import object_navigation, menu_links as menu_navigation +from common.api import object_navigation, multi_object_navigation, \ + menu_links as menu_navigation from common.forms import MultiItemForm register = Library() @@ -141,12 +142,15 @@ def resolve_links(context, links, current_view, current_path): context_links = [] for link in links: new_link = copy.copy(link) - args, kwargs = resolve_arguments(context, link.get('args', {})) - + try: + args, kwargs = resolve_arguments(context, link.get('args', {})) + except VariableDoesNotExist: + args = [] + kwargs = {} + if 'view' in link: new_link['active'] = link['view'] == current_view - args, kwargs = resolve_arguments(context, link.get('args', {})) - + try: if kwargs: new_link['url'] = reverse(link['view'], kwargs=kwargs) @@ -166,7 +170,8 @@ def resolve_links(context, links, current_view, current_path): context_links.append(new_link) return context_links -def _get_object_navigation_links(context, menu_name=None): + +def _get_object_navigation_links(context, menu_name=None, links_dict=object_navigation): current_path = Variable('request').resolve(context).META['PATH_INFO'] current_view = resolve_to_name(current_path)#.get_full_path()) context_links = [] @@ -182,14 +187,14 @@ def _get_object_navigation_links(context, menu_name=None): obj = None try: - links = object_navigation[menu_name][current_view]['links'] + links = links_dict[menu_name][current_view]['links'] for link in resolve_links(context, links, current_view, current_path): context_links.append(link) except KeyError: pass try: - links = object_navigation[menu_name][type(obj)]['links'] + links = links_dict[menu_name][type(obj)]['links'] for link in resolve_links(context, links, current_view, current_path): context_links.append(link) except KeyError: @@ -227,6 +232,7 @@ def get_object_navigation_links(parser, token): return GetNavigationLinks(*args[1:]) +@register.inclusion_tag('generic_navigation.html', takes_context=True) def object_navigation_template(context): return { 'request':context['request'], @@ -234,14 +240,15 @@ def object_navigation_template(context): 'object_navigation_links':_get_object_navigation_links(context) } return new_context -register.inclusion_tag('generic_navigation.html', takes_context=True)(object_navigation_template) - + +@register.inclusion_tag('generic_form_instance.html', takes_context=True) def get_multi_item_links_form(context): new_context = copy.copy(context) new_context.update({ - 'form':MultiItemForm(), - 'title':_(u'Selected item actions:') + 'form':MultiItemForm(actions=[(link['url'], link['text']) for link in _get_object_navigation_links(context, links_dict=multi_object_navigation)]), + 'title':_(u'Selected item actions:'), + 'form_action':reverse('multi_object_action_view'), + 'submit_method':'get', }) return new_context -register.inclusion_tag('generic_form_subtemplate.html', takes_context=True)(get_multi_item_links_form) diff --git a/apps/common/urls.py b/apps/common/urls.py index 497860844b..20578e1242 100644 --- a/apps/common/urls.py +++ b/apps/common/urls.py @@ -6,6 +6,7 @@ from django.conf import settings urlpatterns = patterns('common.views', url(r'^about/$', direct_to_template, { 'template' : 'about.html'}, 'about'), url(r'^password/change/done/$', 'password_change_done', (), name='password_change_done'), + url(r'^object/multiple/action/$', 'multi_object_action_view', (), name='multi_object_action_view'), ) urlpatterns += patterns('', diff --git a/apps/common/views.py b/apps/common/views.py index f435cbc6d3..d9dde52e54 100644 --- a/apps/common/views.py +++ b/apps/common/views.py @@ -1,7 +1,24 @@ from django.shortcuts import redirect from django.utils.translation import ugettext as _ from django.contrib import messages +from django.http import HttpResponse, HttpResponseRedirect, Http404 + def password_change_done(request): messages.success(request, _(u'Your password has been successfully changed.')) return redirect('home') + + +def multi_object_action_view(request): + action = request.GET.get('action', None) + id_list = u','.join([key[3:] for key in request.GET.keys() if key.startswith('pk_')]) + + if not action: + messages.error(request, _(u'No action selected.')) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + + if not id_list: + messages.error(request, _(u'Must select at least one item.')) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) + + return HttpResponseRedirect('%s?id_list=%s' % (action, id_list)) diff --git a/apps/documents/__init__.py b/apps/documents/__init__.py index 20002ddfab..fcb2889b33 100644 --- a/apps/documents/__init__.py +++ b/apps/documents/__init__.py @@ -49,6 +49,7 @@ document_download = {'text':_('download'), 'view':'document_download', 'args':'o document_find_duplicates = {'text':_('find duplicates'), 'view':'document_find_duplicates', 'args':'object.id', 'famfam':'page_refresh', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_VIEW]}} document_find_all_duplicates = {'text':_('find all duplicates'), 'view':'document_find_all_duplicates', 'famfam':'page_refresh', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_VIEW]}} document_clear_transformations = {'text':_('clear all transformations'), 'view':'document_clear_transformations', 'args':'object.id', 'famfam':'page_paintbrush', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_TRANSFORM]}} +document_multiple_clear_transformations = {'text':_('clear all transformations'), 'view':'document_multiple_clear_transformations', 'famfam':'page_paintbrush', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_TRANSFORM]}} document_page_transformation_create = {'text':_('create new transformation'), 'view':'document_page_transformation_create', 'args':'object.id', 'famfam':'pencil_add', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_TRANSFORM]}} document_page_transformation_edit = {'text':_('edit'), 'view':'document_page_transformation_edit', 'args':'object.id', 'famfam':'pencil_go', 'permissions':{'namespace':'documents', 'permissions':[PERMISSION_DOCUMENT_TRANSFORM]}} @@ -62,7 +63,7 @@ staging_file_delete = {'text':_('delete'), 'view':'staging_file_delete', 'args': register_links(Document, [document_view_simple, document_view, document_edit, document_edit_metadata, document_delete, document_download, document_find_duplicates, document_clear_transformations], menu_name='sidebar') register_links(Document, [document_list, document_create, document_create_multiple, document_create_sibling], menu_name='sidebar') -register_multi_item_links(Document, [document_clear_transformations], menu_name='sidebar') +register_multi_item_links(['document_list'], [document_multiple_clear_transformations]) if ENABLE_SINGLE_DOCUMENT_UPLOAD: register_links(['document_list', 'document_create', 'document_create_multiple', 'upload_document_with_type', 'upload_multiple_documents_with_type'], [document_list, document_create, document_create_multiple], menu_name='sidebar') diff --git a/apps/documents/urls.py b/apps/documents/urls.py index 62ea103d1b..3361505a18 100644 --- a/apps/documents/urls.py +++ b/apps/documents/urls.py @@ -34,7 +34,7 @@ urlpatterns = patterns('documents.views', url(r'^document/(?P\d+)/create/siblings/$', 'document_create_sibling', {'multiple':True if ENABLE_SINGLE_DOCUMENT_UPLOAD == False else False}, 'document_create_sibling'), url(r'^document/(?P\d+)/find_duplicates/$', 'document_find_duplicates', (), 'document_find_duplicates'), url(r'^document/(?P\d+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'), - url(r'^document/(?P[0-9,]+)/clear_transformations/$', 'document_clear_transformations', (), 'document_clear_transformations'), + url(r'^document/multiple/clear_transformations/$', 'document_multiple_clear_transformations', (), 'document_multiple_clear_transformations'), url(r'^duplicates/$', 'document_find_all_duplicates', (), 'document_find_all_duplicates'), url(r'^staging_file/(?P\w+)/preview/$', 'staging_file_preview', (), 'staging_file_preview'), diff --git a/apps/documents/views.py b/apps/documents/views.py index be5d1dc77b..522395e2cd 100644 --- a/apps/documents/views.py +++ b/apps/documents/views.py @@ -744,6 +744,9 @@ def document_clear_transformations(request, document_id=None, document_id_list=N elif document_id_list: documents = [get_object_or_404(Document, pk=document_id) for document_id in document_id_list.split(',')] post_redirect = None + else: + messages.error(request, _(u'Must provide at least one document.')) + return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/')) previous = request.POST.get('previous', request.GET.get('previous', request.META.get('HTTP_REFERER', post_redirect or reverse('document_list')))) next = request.POST.get('next', request.GET.get('next', request.META.get('HTTP_REFERER', post_redirect or reverse('document_list')))) @@ -755,16 +758,15 @@ def document_clear_transformations(request, document_id=None, document_id_list=N transformation.delete() if len(documents) == 1: - messages.success(request, _(u'All the page transformations for document: %s, have been deleted successfully.') % documents) + messages.success(request, _(u'All the page transformations for document: %s, have been deleted successfully.') % ', '.join([unicode(d) for d in documents])) elif len(documents) > 1: - messages.success(request, _(u'All the page transformations for the documents: %s, have been deleted successfully.') % documents) + messages.success(request, _(u'All the page transformations for the documents: %s, have been deleted successfully.') % ', '.join([unicode(d) for d in documents])) - return HttpResponseRedirect(next)#reverse('document_view', args=[document.pk])) + return HttpResponseRedirect(next) context = { 'object_name':_(u'document transformation'), 'delete_view':True, - #'object':document, 'previous':previous, 'next':next, } @@ -780,6 +782,10 @@ def document_clear_transformations(request, document_id=None, document_id_list=N context_instance=RequestContext(request)) +def document_multiple_clear_transformations(request): + return document_clear_transformations(request, document_id_list=request.GET.get('id_list', [])) + + def document_view_simple(request, document_id): check_permissions(request.user, 'documents', [PERMISSION_DOCUMENT_VIEW])