From 14f31d56148e76f90c68040f0f033e3a171e4e28 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Fri, 21 Dec 2018 23:51:20 -0400 Subject: [PATCH] Add new list templates toolbar Add the new generic list and generic list items toolbar which allow switching the list display mode. This toolbar also includes a stylized button to select and deselect all items emulating the check-all checkbox. Signed-off-by: Roberto Rosario --- .../static/appearance/js/mayan_app.js | 18 +++++++++- .../generic_list_items_subtemplate.html | 31 ++++++++-------- .../appearance/generic_list_subtemplate.html | 30 +++++++++------- .../templates/appearance/list_toolbar.html | 16 +++++++++ .../appearance/templates/appearance/root.html | 2 +- mayan/apps/common/generics.py | 12 +++++++ mayan/apps/navigation/classes.py | 35 +++++++++++++------ mayan/apps/navigation/literals.py | 4 +++ .../templatetags/navigation_tags.py | 23 +++++++++--- 9 files changed, 129 insertions(+), 42 deletions(-) create mode 100644 mayan/apps/appearance/templates/appearance/list_toolbar.html create mode 100644 mayan/apps/navigation/literals.py diff --git a/mayan/apps/appearance/static/appearance/js/mayan_app.js b/mayan/apps/appearance/static/appearance/js/mayan_app.js index 4c9f90c30b..6d0a290369 100644 --- a/mayan/apps/appearance/static/appearance/js/mayan_app.js +++ b/mayan/apps/appearance/static/appearance/js/mayan_app.js @@ -301,9 +301,23 @@ class MayanApp { app.lastChecked = null; $('body').on('click', '.check-all', function (event) { + var $this = $(this); var checked = $(event.target).prop('checked'); var $checkBoxes = $('.check-all-slave'); + if (checked === undefined) { + checked = $this.data('checked'); + checked = !checked; + $this.data('checked', checked); + console.log($this.data('icon-checked')); + + if (checked) { + $this.find('[data-fa-i2svg]').addClass($this.data('icon-checked')).removeClass($this.data('icon-unchecked')); + } else { + $this.find('[data-fa-i2svg]').addClass($this.data('icon-unchecked')).removeClass($this.data('icon-checked')); + } + } + $checkBoxes.prop('checked', checked); $checkBoxes.trigger('change'); }); @@ -353,6 +367,7 @@ class MayanApp { setupPanelSelection () { var app = this; + // Setup panel highlighting on check $('body').on('change', '.check-all-slave', function (event) { var checked = $(event.target).prop('checked'); if (checked) { @@ -366,9 +381,10 @@ class MayanApp { var $this = $(this); var targetSrc = $(event.target).prop('src'); var targetHref = $(event.target).prop('href'); + var targetIsButton = event.target.tagName === 'BUTTON'; var lastChecked = null; - if ((targetSrc === undefined) && (targetHref === undefined)) { + if ((targetSrc === undefined) && (targetHref === undefined) && (targetIsButton === false)) { var $checkbox = $this.find('.check-all-slave'); var checked = $checkbox.prop('checked'); diff --git a/mayan/apps/appearance/templates/appearance/generic_list_items_subtemplate.html b/mayan/apps/appearance/templates/appearance/generic_list_items_subtemplate.html index 8386f9d7f9..96cb181ba8 100644 --- a/mayan/apps/appearance/templates/appearance/generic_list_items_subtemplate.html +++ b/mayan/apps/appearance/templates/appearance/generic_list_items_subtemplate.html @@ -11,7 +11,6 @@ {% include 'appearance/no_results.html' %} {% else %} -

{% if page_obj %} {% if page_obj.paginator.num_pages != 1 %} @@ -24,17 +23,23 @@ {% endif %}


+
+ + {% if object_list %} + {% if not hide_multi_item_actions %} + {% get_multi_item_links_form object_list %} + {% endif %} + {% endif %} + + {% include 'appearance/list_toolbar.html' %} +
{% if object_list %} - {% if not hide_multi_item_actions %} - {% get_multi_item_links_form object_list %} - {% endif %} {% if multi_item_actions %}
-   {{ multi_item_form }}
{% endif %} @@ -65,15 +70,14 @@ {% if not hide_object %} - {% if main_object %} - {% with object|object_property:main_object as object %} - {% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %} - {% endwith %} + {% if not hide_link %} + {{ object }} {% else %} - {% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %} + {{ object }} {% endif %} + {% else %} + {% source_column_resolve column=object|get_source_columns:"only_identifier" %} {% endif %} -
@@ -81,10 +85,9 @@
- {% if not hide_columns %} - {% for column in object|get_source_columns %} -
{% source_column_resolve column=column %}{{ column_result }}
+ {% for column in object|get_source_columns:"exclude_identifier" %} +
{% source_column_resolve column=column as column_value %}{% if column_value != '' %}{{ column.label }}: {{ column_value }}{% endif %}
{% endfor %} {% endif %} diff --git a/mayan/apps/appearance/templates/appearance/generic_list_subtemplate.html b/mayan/apps/appearance/templates/appearance/generic_list_subtemplate.html index da1feb0608..67e72586e8 100644 --- a/mayan/apps/appearance/templates/appearance/generic_list_subtemplate.html +++ b/mayan/apps/appearance/templates/appearance/generic_list_subtemplate.html @@ -26,12 +26,18 @@
+ + {% if object_list %} + {% if not hide_multi_item_actions %} + {% get_multi_item_links_form object_list %} + {% endif %} + {% endif %} + + {% include 'appearance/list_toolbar.html' %} +
{% if object_list %} - {% if not hide_multi_item_actions %} - {% get_multi_item_links_form object_list %} - {% endif %} {% if multi_item_actions %}
{{ multi_item_form }} @@ -42,13 +48,17 @@
+ {% if object_list %} +
+ {% endif %} +
- + {% if not hide_header %} {% if multi_item_actions %} - + {% endif %} {% if not hide_object %} @@ -70,6 +80,8 @@ {% endif %} {% endif %} + + {% for object in object_list %} {% if multi_item_actions %} @@ -82,13 +94,7 @@ {% 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_source_columns %} diff --git a/mayan/apps/appearance/templates/appearance/list_toolbar.html b/mayan/apps/appearance/templates/appearance/list_toolbar.html new file mode 100644 index 0000000000..6ad7924172 --- /dev/null +++ b/mayan/apps/appearance/templates/appearance/list_toolbar.html @@ -0,0 +1,16 @@ +{% load i18n %} + +
+ +
diff --git a/mayan/apps/appearance/templates/appearance/root.html b/mayan/apps/appearance/templates/appearance/root.html index 74ee780dc8..b29b0c9448 100644 --- a/mayan/apps/appearance/templates/appearance/root.html +++ b/mayan/apps/appearance/templates/appearance/root.html @@ -92,7 +92,7 @@ - + diff --git a/mayan/apps/common/generics.py b/mayan/apps/common/generics.py index 322a39ac75..66b4fcc9b1 100644 --- a/mayan/apps/common/generics.py +++ b/mayan/apps/common/generics.py @@ -498,6 +498,18 @@ class SingleObjectListView(PaginationMixin, ViewPermissionCheckMixin, ObjectList return result + def get_context_data(self, **kwargs): + context = super(SingleObjectListView, self).get_context_data(**kwargs) + if context.get('list_as_items'): + default_mode = 'items' + else: + default_mode = 'list' + + list_mode = self.request.GET.get('_list_mode', default_mode) + + context.update({'list_as_items': list_mode=='items'}) + return context + def get_paginate_by(self, queryset): return setting_paginate_by.value diff --git a/mayan/apps/navigation/classes.py b/mayan/apps/navigation/classes.py index b39bcd67e5..cca12f3c56 100644 --- a/mayan/apps/navigation/classes.py +++ b/mayan/apps/navigation/classes.py @@ -495,34 +495,46 @@ class SourceColumn(object): return sorted(columns, key=lambda x: x.order) @classmethod - def get_for_source(cls, source): + def get_for_source(cls, source, exclude_identifier=False, only_identifier=False): try: - return SourceColumn.sort(columns=cls._registry[source]) + result = SourceColumn.sort(columns=cls._registry[source]) except KeyError: try: # Try it as a queryset - return SourceColumn.sort(columns=cls._registry[source.model]) + result = SourceColumn.sort(columns=cls._registry[source.model]) except AttributeError: try: # It seems to be an instance, try its class - return SourceColumn.sort(columns=cls._registry[source.__class__]) + result = SourceColumn.sort(columns=cls._registry[source.__class__]) except KeyError: try: # Special case for queryset items produced from # .defer() or .only() optimizations - return SourceColumn.sort(columns=cls._registry[list(source._meta.parents.items())[0][0]]) + result = SourceColumn.sort(columns=cls._registry[list(source._meta.parents.items())[0][0]]) except (AttributeError, KeyError, IndexError): - return () + result = () except TypeError: # unhashable type: list - return () + result = () - def __init__(self, source, label=None, attribute=None, func=None, order=None): + if exclude_identifier: + return [item for item in result if not item.is_identifier] + else: + if only_identifier: + for item in result: + if item.is_identifier: + return item + else: + return result + + def __init__(self, source, label=None, attribute=None, func=None, kwargs=None, order=None, is_identifier=False): self.source = source self._label = label self.attribute = attribute self.func = func + self.kwargs = kwargs or {} self.order = order or 0 + self.is_identifier = is_identifier self.__class__._registry.setdefault(source, []) self.__class__._registry[source].append(self) @@ -543,9 +555,12 @@ class SourceColumn(object): def resolve(self, context): if self.attribute: - result = resolve_attribute(context['object'], self.attribute) + result = resolve_attribute( + obj=context['object'], attribute=self.attribute, + kwargs=self.kwargs + ) elif self.func: - result = self.func(context=context) + result = self.func(context=context, **self.kwargs) return result diff --git a/mayan/apps/navigation/literals.py b/mayan/apps/navigation/literals.py new file mode 100644 index 0000000000..6f40e48c7d --- /dev/null +++ b/mayan/apps/navigation/literals.py @@ -0,0 +1,4 @@ +from __future__ import unicode_literals + +TEXT_ONLY_IDENTIFIER = 'only_identifier' +TEXT_EXCLUDE_IDENTIFIER = 'exclude_identifier' diff --git a/mayan/apps/navigation/templatetags/navigation_tags.py b/mayan/apps/navigation/templatetags/navigation_tags.py index 589798c54c..0f8ca917fe 100644 --- a/mayan/apps/navigation/templatetags/navigation_tags.py +++ b/mayan/apps/navigation/templatetags/navigation_tags.py @@ -4,6 +4,7 @@ from django.template import Library from ..classes import Link, Menu, SourceColumn from ..forms import MultiItemForm +from ..literals import TEXT_EXCLUDE_IDENTIFIER, TEXT_ONLY_IDENTIFIER register = Library() @@ -48,7 +49,15 @@ def get_multi_item_links_form(context, object_list): @register.filter -def get_source_columns(source): +def get_source_columns(source, args=None): + exclude_identifier = False + only_identifier = False + + if args == TEXT_EXCLUDE_IDENTIFIER: + exclude_identifier = True + elif args == TEXT_ONLY_IDENTIFIER: + only_identifier = True + try: # Is it a query set? source = source.model @@ -67,7 +76,10 @@ def get_source_columns(source): # It a list and it's empty pass - return SourceColumn.get_for_source(source) + return SourceColumn.get_for_source( + source=source, exclude_identifier=exclude_identifier, + only_identifier=only_identifier + ) @register.simple_tag(takes_context=True) @@ -78,5 +90,8 @@ def resolve_link(context, link): @register.simple_tag(takes_context=True) def source_column_resolve(context, column): - context['column_result'] = column.resolve(context=context) - return '' + if column: + result = column.resolve(context=context) + return result + else: + return ''
{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}{% if not hide_link %}{{ object }}{% else %}{{ object }}{% endif %}