diff --git a/HISTORY.rst b/HISTORY.rst index 9a11c9b36d..ec3b7b1a24 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -42,6 +42,7 @@ * Backport and remove unused code from the permission app. * Move the navigation and authentication templates to their respective apps. +* Add dashboard app. 3.1.11 (2019-04-XX) =================== diff --git a/docs/releases/3.2.rst b/docs/releases/3.2.rst index 8aff7a2e51..6a47f5b612 100644 --- a/docs/releases/3.2.rst +++ b/docs/releases/3.2.rst @@ -66,6 +66,7 @@ Other changes * Backport and remove unused code from the permission app. * Move the navigation and authentication templates to their respective apps. +* Add dashboard app. Removals diff --git a/mayan/apps/appearance/templates/appearance/home.html b/mayan/apps/appearance/templates/appearance/home.html index 4a6bdd4c11..17701fb347 100644 --- a/mayan/apps/appearance/templates/appearance/home.html +++ b/mayan/apps/appearance/templates/appearance/home.html @@ -4,6 +4,7 @@ {% load static %} {% load common_tags %} +{% load dashboards_tags %} {% load navigation_tags %} {% block title %}{% trans 'Dashboard' %}{% endblock %} diff --git a/mayan/apps/checkouts/apps.py b/mayan/apps/checkouts/apps.py index d8a20c001c..f961812b25 100644 --- a/mayan/apps/checkouts/apps.py +++ b/mayan/apps/checkouts/apps.py @@ -10,7 +10,7 @@ from django.utils.translation import ugettext_lazy as _ from mayan.apps.acls import ModelPermission from mayan.apps.common import MayanAppConfig, menu_facet, menu_main, menu_sidebar -from mayan.apps.common.dashboards import dashboard_main +from mayan.apps.dashboards.dashboards import dashboard_main from mayan.apps.events import ModelEventType from mayan.celery import app diff --git a/mayan/apps/checkouts/dashboard_widgets.py b/mayan/apps/checkouts/dashboard_widgets.py index 73552fbd29..0d8dc9de99 100644 --- a/mayan/apps/checkouts/dashboard_widgets.py +++ b/mayan/apps/checkouts/dashboard_widgets.py @@ -4,7 +4,7 @@ from django.apps import apps from django.urls import reverse_lazy from django.utils.translation import ugettext_lazy as _ -from mayan.apps.common.classes import DashboardWidgetNumeric +from mayan.apps.dashboards.classes import DashboardWidgetNumeric from mayan.apps.documents.permissions import permission_document_view from .icons import icon_dashboard_check_outs diff --git a/mayan/apps/common/classes.py b/mayan/apps/common/classes.py index 3222fd755e..e8fd8aa977 100644 --- a/mayan/apps/common/classes.py +++ b/mayan/apps/common/classes.py @@ -53,95 +53,6 @@ class Collection(object): return self._model.objects.all() -class Dashboard(object): - _registry = {} - - @classmethod - def get(cls, name): - return cls._registry[name] - - def __init__(self, name, label): - self.name = name - self.label = label - self.widgets = {} - self.removed_widgets = [] - self.__class__._registry[name] = self - - def add_widget(self, widget, order=0): - self.widgets[widget] = {'widget': widget, 'order': order} - - def get_widgets(self): - """ - Returns a list of widgets sorted by their 'order'. - If two or more widgets have the same 'order', sort by label. - """ - return map( - lambda x: x['widget'], - filter( - lambda x: x['widget'] not in self.removed_widgets, - sorted( - self.widgets.values(), - key=lambda x: (x['order'], x['widget'].label) - ) - ) - ) - - def remove_widget(self, widget): - self.removed_widgets.append(widget) - - def render(self, request): - rendered_widgets = [widget().render(request=request) for widget in self.get_widgets()] - - return loader.render_to_string( - template_name='dashboard/dashboard.html', context={ - 'widgets': rendered_widgets - } - ) - - -class BaseDashboardWidget(object): - _registry = {} - context = {} - template_name = None - - @classmethod - def get(cls, name): - return cls._registry[name] - - @classmethod - def get_all(cls): - return cls._registry.items() - - @classmethod - def register(cls, klass): - cls._registry[klass.name] = klass - - def get_context(self): - return self.context - - def render(self, request): - if self.template_name: - return loader.render_to_string( - template_name=self.template_name, context=self.get_context(), - ) - - -class DashboardWidgetNumeric(BaseDashboardWidget): - count = 0 - icon_class = None - label = None - link = None - template_name = 'dashboard/numeric_widget.html' - - def get_context(self): - return { - 'count': self.count, - 'icon_class': self.icon_class, - 'label': self.label, - 'link': self.link, - } - - @python_2_unicode_compatible class ErrorLogNamespace(object): def __init__(self, name, label=None): diff --git a/mayan/apps/common/templatetags/common_tags.py b/mayan/apps/common/templatetags/common_tags.py index 87f1cfe215..addaf4fef1 100644 --- a/mayan/apps/common/templatetags/common_tags.py +++ b/mayan/apps/common/templatetags/common_tags.py @@ -8,7 +8,7 @@ from django.utils.encoding import force_text import mayan -from ..classes import Collection, Dashboard +from ..classes import Collection from ..literals import MESSAGE_SQLITE_WARNING from ..utils import check_for_sqlite, return_attrib @@ -49,11 +49,6 @@ def project_information(attribute_name): return getattr(mayan, attribute_name) -@register.simple_tag(takes_context=True) -def render_dashboard(context, name): - return Dashboard.get(name=name).render(request=context.request) - - @register.simple_tag(takes_context=True) def render_subtemplate(context, template_name, template_context): """ diff --git a/mayan/apps/dashboards/__init__.py b/mayan/apps/dashboards/__init__.py new file mode 100644 index 0000000000..6ad44301d1 --- /dev/null +++ b/mayan/apps/dashboards/__init__.py @@ -0,0 +1,3 @@ +from __future__ import unicode_literals + +default_app_config = 'mayan.apps.dashboards.apps.DashboardsApp' diff --git a/mayan/apps/dashboards/apps.py b/mayan/apps/dashboards/apps.py new file mode 100644 index 0000000000..dc5a95e0e6 --- /dev/null +++ b/mayan/apps/dashboards/apps.py @@ -0,0 +1,15 @@ +from __future__ import unicode_literals + +from django.utils.translation import ugettext_lazy as _ + +from mayan.apps.common import MayanAppConfig + + +class DashboardsApp(MayanAppConfig): + app_namespace = 'dashboards' + app_url = 'dashboards' + has_rest_api = False + has_tests = False + name = 'mayan.apps.dashboards' + verbose_name = _('Dashboards') + diff --git a/mayan/apps/dashboards/classes.py b/mayan/apps/dashboards/classes.py new file mode 100644 index 0000000000..c1e4a6d478 --- /dev/null +++ b/mayan/apps/dashboards/classes.py @@ -0,0 +1,92 @@ +from __future__ import unicode_literals + +from django.template import loader + + +class Dashboard(object): + _registry = {} + + @classmethod + def get(cls, name): + return cls._registry[name] + + def __init__(self, name, label): + self.name = name + self.label = label + self.widgets = {} + self.removed_widgets = [] + self.__class__._registry[name] = self + + def add_widget(self, widget, order=0): + self.widgets[widget] = {'widget': widget, 'order': order} + + def get_widgets(self): + """ + Returns a list of widgets sorted by their 'order'. + If two or more widgets have the same 'order', sort by label. + """ + return map( + lambda x: x['widget'], + filter( + lambda x: x['widget'] not in self.removed_widgets, + sorted( + self.widgets.values(), + key=lambda x: (x['order'], x['widget'].label) + ) + ) + ) + + def remove_widget(self, widget): + self.removed_widgets.append(widget) + + def render(self, request): + rendered_widgets = [widget().render(request=request) for widget in self.get_widgets()] + + return loader.render_to_string( + template_name='dashboards/dashboard.html', context={ + 'widgets': rendered_widgets + } + ) + + +class BaseDashboardWidget(object): + _registry = {} + context = {} + template_name = None + + @classmethod + def get(cls, name): + return cls._registry[name] + + @classmethod + def get_all(cls): + return cls._registry.items() + + @classmethod + def register(cls, klass): + cls._registry[klass.name] = klass + + def get_context(self): + return self.context + + def render(self, request): + if self.template_name: + return loader.render_to_string( + template_name=self.template_name, context=self.get_context(), + ) + + +class DashboardWidgetNumeric(BaseDashboardWidget): + count = 0 + icon_class = None + label = None + link = None + template_name = 'dashboards/numeric_widget.html' + + def get_context(self): + return { + 'count': self.count, + 'icon_class': self.icon_class, + 'label': self.label, + 'link': self.link, + } diff --git a/mayan/apps/common/dashboards.py b/mayan/apps/dashboards/dashboards.py similarity index 99% rename from mayan/apps/common/dashboards.py rename to mayan/apps/dashboards/dashboards.py index e825460863..9de453cd62 100644 --- a/mayan/apps/common/dashboards.py +++ b/mayan/apps/dashboards/dashboards.py @@ -5,3 +5,4 @@ from django.utils.translation import ugettext_lazy as _ from .classes import Dashboard dashboard_main = Dashboard(name='main', label=_('Main')) + diff --git a/mayan/apps/appearance/templates/dashboard/dashboard.html b/mayan/apps/dashboards/templates/dashboards/dashboard.html similarity index 100% rename from mayan/apps/appearance/templates/dashboard/dashboard.html rename to mayan/apps/dashboards/templates/dashboards/dashboard.html diff --git a/mayan/apps/appearance/templates/dashboard/numeric_widget.html b/mayan/apps/dashboards/templates/dashboards/numeric_widget.html similarity index 100% rename from mayan/apps/appearance/templates/dashboard/numeric_widget.html rename to mayan/apps/dashboards/templates/dashboards/numeric_widget.html diff --git a/mayan/apps/dashboards/templatetags/__init__.py b/mayan/apps/dashboards/templatetags/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mayan/apps/dashboards/templatetags/dashboards_tags.py b/mayan/apps/dashboards/templatetags/dashboards_tags.py new file mode 100644 index 0000000000..ed1255e0b0 --- /dev/null +++ b/mayan/apps/dashboards/templatetags/dashboards_tags.py @@ -0,0 +1,13 @@ +from __future__ import unicode_literals + +from django.template import Library + +from ..classes import Dashboard + +register = Library() + + +@register.simple_tag(takes_context=True) +def render_dashboard(context, name): + return Dashboard.get(name=name).render(request=context.request) + diff --git a/mayan/apps/documents/apps.py b/mayan/apps/documents/apps.py index e6bb9e69ba..3190c9f288 100644 --- a/mayan/apps/documents/apps.py +++ b/mayan/apps/documents/apps.py @@ -15,9 +15,9 @@ from mayan.apps.common import ( menu_secondary, menu_setup, menu_sidebar, menu_multi_item, menu_tools ) from mayan.apps.common.classes import ModelField -from mayan.apps.common.dashboards import dashboard_main from mayan.apps.common.signals import post_initial_setup from mayan.apps.common.widgets import TwoStateWidget +from mayan.apps.dashboards.dashboards import dashboard_main from mayan.apps.converter.links import link_transformation_list from mayan.apps.converter.permissions import ( permission_transformation_create, diff --git a/mayan/apps/documents/dashboard_widgets.py b/mayan/apps/documents/dashboard_widgets.py index fb42590a96..e47f151871 100644 --- a/mayan/apps/documents/dashboard_widgets.py +++ b/mayan/apps/documents/dashboard_widgets.py @@ -4,7 +4,7 @@ from django.apps import apps from django.urls import reverse_lazy from django.utils.translation import ugettext_lazy as _ -from mayan.apps.common.classes import DashboardWidgetNumeric +from mayan.apps.dashboards.classes import DashboardWidgetNumeric from .icons import ( icon_dashboard_documents_in_trash, icon_dashboard_document_types, diff --git a/mayan/settings/base.py b/mayan/settings/base.py index 47a50497c3..54ad4a079c 100644 --- a/mayan/settings/base.py +++ b/mayan/settings/base.py @@ -92,6 +92,7 @@ INSTALLED_APPS = ( 'mayan.apps.authentication', 'mayan.apps.common', 'mayan.apps.converter', + 'mayan.apps.dashboards', 'mayan.apps.django_gpg', 'mayan.apps.dynamic_search', 'mayan.apps.events',