Add dashboard feature
This commit is contained in:
@@ -159,3 +159,12 @@ hr {
|
||||
a i {
|
||||
padding-right: 3px;
|
||||
}
|
||||
|
||||
.panel-dashboard-widget {
|
||||
box-shadow: 1px 1px 1px rgba(0,0,0,0.3);
|
||||
border: 1px solid black;
|
||||
}
|
||||
|
||||
.panel-dashboard-widget .panel-heading i {
|
||||
text-shadow: 1px 1px 1px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{% load i18n %}
|
||||
|
||||
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-3">
|
||||
<div class="panel panel-secondary panel-dashboard-widget">
|
||||
<div class="panel-heading">
|
||||
<div class="row">
|
||||
<div class="col-xs-2">
|
||||
<i class="fa fa-{{ widget.icon }} fa-2x"></i>
|
||||
</div>
|
||||
<div class="col-xs-10 text-right">
|
||||
<strong>{{ widget.label }}</strong>
|
||||
<div class="huge">
|
||||
{% if widget.func %}
|
||||
{{ widget.func }}
|
||||
{% else %}
|
||||
{{ widget.queryset.count }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if widget.link %}
|
||||
<a href="{{ widget.link }}">
|
||||
<div class="panel-footer">
|
||||
<span class="pull-left">{% trans 'View Details' %}</span>
|
||||
<span class="pull-right"><i class="fa fa-external-link"></i></span>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -3,6 +3,7 @@
|
||||
{% load i18n %}
|
||||
{% load static %}
|
||||
|
||||
{% load common_tags %}
|
||||
{% load navigation_tags %}
|
||||
|
||||
{% block title %}{% trans 'Home' %}{% endblock %}
|
||||
@@ -53,30 +54,21 @@
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="panel panel-default center-block">
|
||||
<div class="panel-heading">{% trans 'Search pages' %}</div>
|
||||
<div class="panel-heading">{% trans 'Search' %}</div>
|
||||
<div class="panel-body">
|
||||
<form action="{% url 'search:results' search_model='documents.DocumentPageResult' %}" method="get" role="search">
|
||||
<div class="input-group">
|
||||
<input class="form-control" name="q" placeholder="{% trans 'Space separated terms' %}" type="text" value="{{ search_terms|default:'' }}">
|
||||
<input class="form-control" name="q" placeholder="{% trans 'Search pages' %}" type="text" value="{{ search_terms|default:'' }}">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="submit">{% trans 'Search' %}</button>
|
||||
<a class="btn btn-primary" href="{% url 'search:search_advanced' search_model='documents.DocumentPageResult' %}">{% trans 'Advanced' %}</a>
|
||||
</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<div class="panel panel-default center-block">
|
||||
<div class="panel-heading">{% trans 'Search documents' %}</div>
|
||||
<div class="panel-body">
|
||||
<br/>
|
||||
<form action="{% url 'search:results' search_model='documents.Document' %}" method="get" role="search">
|
||||
<div class="input-group">
|
||||
<input class="form-control" name="q" placeholder="{% trans 'Space separated terms' %}" type="text" value="{{ search_terms|default:'' }}">
|
||||
<input class="form-control" name="q" placeholder="{% trans 'Search documents' %}" type="text" value="{{ search_terms|default:'' }}">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-default" type="submit">{% trans 'Search' %}</button>
|
||||
<a class="btn btn-primary" href="{% url 'search:search_advanced' search_model='documents.Document' %}">{% trans 'Advanced' %}</a>
|
||||
@@ -88,4 +80,11 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% get_dashboard_widgets as dashboard_widgets %}
|
||||
<div class="row">
|
||||
{% for widget in dashboard_widgets %}
|
||||
{% include 'appearance/dashboard_widget.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -5,6 +5,24 @@ from django.db import models
|
||||
from django.utils.translation import ugettext
|
||||
|
||||
|
||||
class DashboardWidget(object):
|
||||
_registry = []
|
||||
|
||||
@classmethod
|
||||
def get_all(cls):
|
||||
return cls._registry
|
||||
|
||||
def __init__(self, label, func=None, icon=None, link=None, queryset=None, statistic_slug=None):
|
||||
self.label = label
|
||||
self.icon = icon
|
||||
self.link = link
|
||||
self.queryset = queryset
|
||||
self.func = func
|
||||
self.statistic_slug = statistic_slug
|
||||
|
||||
self.__class__._registry.append(self)
|
||||
|
||||
|
||||
class ModelAttribute(object):
|
||||
__registry = {}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from django.template.loader import get_template
|
||||
|
||||
import mayan
|
||||
|
||||
from ..classes import DashboardWidget
|
||||
from ..utils import return_attrib
|
||||
|
||||
register = Library()
|
||||
@@ -22,6 +23,11 @@ except sh.CommandNotFound:
|
||||
DATE = None
|
||||
|
||||
|
||||
@register.assignment_tag
|
||||
def get_dashboard_widgets():
|
||||
return DashboardWidget.get_all()
|
||||
|
||||
|
||||
@register.filter
|
||||
def get_encoded_parameter(item, parameters_dict):
|
||||
result = {}
|
||||
|
||||
@@ -4,6 +4,7 @@ from datetime import timedelta
|
||||
|
||||
from kombu import Exchange, Queue
|
||||
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from acls import ModelPermission
|
||||
@@ -13,7 +14,7 @@ from common import (
|
||||
MayanAppConfig, MissingItem, menu_facet, menu_front_page, menu_object,
|
||||
menu_secondary, menu_setup, menu_sidebar, menu_multi_item, menu_tools
|
||||
)
|
||||
from common.classes import ModelAttribute
|
||||
from common.classes import DashboardWidget, ModelAttribute
|
||||
from common.signals import post_initial_setup
|
||||
from common.widgets import two_state_template
|
||||
from converter.links import link_transformation_list
|
||||
@@ -71,6 +72,7 @@ from .search import document_search, document_page_search # NOQA
|
||||
from .settings import setting_display_size, setting_thumbnail_size
|
||||
from .statistics import (
|
||||
new_documents_per_month, new_document_pages_per_month,
|
||||
new_document_pages_this_month, new_documents_this_month,
|
||||
new_document_versions_per_month, total_document_per_month,
|
||||
total_document_page_per_month, total_document_version_per_month
|
||||
)
|
||||
@@ -96,6 +98,41 @@ class DocumentsApp(MayanAppConfig):
|
||||
DocumentTypeFilename = self.get_model('DocumentTypeFilename')
|
||||
DocumentVersion = self.get_model('DocumentVersion')
|
||||
|
||||
DashboardWidget(
|
||||
func=new_document_pages_this_month, icon='fa fa-calendar',
|
||||
label=_('New pages this month'),
|
||||
link=reverse_lazy(
|
||||
'statistics:statistic_detail',
|
||||
args=('new-document-pages-per-month',)
|
||||
)
|
||||
)
|
||||
DashboardWidget(
|
||||
func=new_documents_this_month, icon='fa fa-calendar',
|
||||
label=_('New documents this month'),
|
||||
link=reverse_lazy(
|
||||
'statistics:statistic_detail',
|
||||
args=('new-documents-per-month',)
|
||||
)
|
||||
)
|
||||
|
||||
DashboardWidget(
|
||||
icon='fa fa-file', queryset=Document.objects.all(),
|
||||
label=_('Total documents'),
|
||||
link=reverse_lazy('documents:document_list')
|
||||
)
|
||||
|
||||
DashboardWidget(
|
||||
icon='fa fa-book', queryset=DocumentType.objects.all(),
|
||||
label=_('Document types'),
|
||||
link=reverse_lazy('documents:document_type_list')
|
||||
)
|
||||
|
||||
DashboardWidget(
|
||||
icon='fa fa-trash', queryset=DeletedDocument.objects.all(),
|
||||
label=_('Documents in trash'),
|
||||
link=reverse_lazy('documents:document_list_deleted')
|
||||
)
|
||||
|
||||
MissingItem(
|
||||
label=_('Create a document type'),
|
||||
description=_(
|
||||
|
||||
@@ -2,11 +2,13 @@ from __future__ import absolute_import, unicode_literals
|
||||
|
||||
import datetime
|
||||
|
||||
from django.apps import apps
|
||||
|
||||
import qsstats
|
||||
|
||||
|
||||
def new_documents_per_month():
|
||||
from .models import Document
|
||||
Document = apps.get_model(app_label='documents', model_name='Document')
|
||||
|
||||
qss = qsstats.QuerySetStats(Document.passthrough.all(), 'date_added')
|
||||
|
||||
@@ -15,43 +17,78 @@ def new_documents_per_month():
|
||||
|
||||
return {
|
||||
'series': {
|
||||
'Documents': map(lambda x: {x[0].month: x[1]}, qss.time_series(start=this_year, end=today, interval='months'))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def new_document_versions_per_month():
|
||||
from .models import DocumentVersion
|
||||
|
||||
qss = qsstats.QuerySetStats(DocumentVersion.objects.all(), 'document__date_added')
|
||||
|
||||
today = datetime.date.today()
|
||||
this_year = datetime.date(year=today.year, month=1, day=1)
|
||||
|
||||
return {
|
||||
'series': {
|
||||
'Versions': map(lambda x: {x[0].month: x[1]}, qss.time_series(start=this_year, end=today, interval='months'))
|
||||
'Documents': map(
|
||||
lambda x: {x[0].month: x[1]},
|
||||
qss.time_series(start=this_year, end=today, interval='months')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def new_document_pages_per_month():
|
||||
from .models import DocumentPage
|
||||
DocumentPage = apps.get_model(
|
||||
app_label='documents', model_name='DocumentPage'
|
||||
)
|
||||
|
||||
qss = qsstats.QuerySetStats(DocumentPage.objects.all(), 'document_version__document__date_added')
|
||||
qss = qsstats.QuerySetStats(
|
||||
DocumentPage.objects.all(), 'document_version__document__date_added'
|
||||
)
|
||||
|
||||
today = datetime.date.today()
|
||||
this_year = datetime.date(year=today.year, month=1, day=1)
|
||||
|
||||
return {
|
||||
'series': {
|
||||
'Pages': map(lambda x: {x[0].month: x[1]}, qss.time_series(start=this_year, end=today, interval='months'))
|
||||
'Pages': map(
|
||||
lambda x: {x[0].month: x[1]},
|
||||
qss.time_series(start=this_year, end=today, interval='months')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def new_documents_this_month():
|
||||
Document = apps.get_model(app_label='documents', model_name='Document')
|
||||
|
||||
qss = qsstats.QuerySetStats(Document.objects.all(), 'date_added')
|
||||
return qss.this_month() or '0'
|
||||
|
||||
|
||||
def new_document_versions_per_month():
|
||||
DocumentVersion = apps.get_model(
|
||||
app_label='documents', model_name='DocumentVersion'
|
||||
)
|
||||
|
||||
qss = qsstats.QuerySetStats(
|
||||
DocumentVersion.objects.all(), 'document__date_added'
|
||||
)
|
||||
|
||||
today = datetime.date.today()
|
||||
this_year = datetime.date(year=today.year, month=1, day=1)
|
||||
|
||||
return {
|
||||
'series': {
|
||||
'Versions': map(
|
||||
lambda x: {x[0].month: x[1]},
|
||||
qss.time_series(start=this_year, end=today, interval='months')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def new_document_pages_this_month():
|
||||
DocumentPage = apps.get_model(
|
||||
app_label='documents', model_name='DocumentPage'
|
||||
)
|
||||
|
||||
qss = qsstats.QuerySetStats(
|
||||
DocumentPage.objects.all(), 'document_version__document__date_added'
|
||||
)
|
||||
return qss.this_month() or '0'
|
||||
|
||||
|
||||
def total_document_per_month():
|
||||
from .models import Document
|
||||
Document = apps.get_model(app_label='documents', model_name='Document')
|
||||
|
||||
qss = qsstats.QuerySetStats(Document.objects.all(), 'date_added')
|
||||
this_year = datetime.date.today().year
|
||||
@@ -78,9 +115,13 @@ def total_document_per_month():
|
||||
|
||||
|
||||
def total_document_version_per_month():
|
||||
from .models import DocumentVersion
|
||||
DocumentVersion = apps.get_model(
|
||||
app_label='documents', model_name='DocumentVersion'
|
||||
)
|
||||
|
||||
qss = qsstats.QuerySetStats(DocumentVersion.objects.all(), 'document__date_added')
|
||||
qss = qsstats.QuerySetStats(
|
||||
DocumentVersion.objects.all(), 'document__date_added'
|
||||
)
|
||||
this_year = datetime.date.today().year
|
||||
|
||||
result = []
|
||||
@@ -105,9 +146,13 @@ def total_document_version_per_month():
|
||||
|
||||
|
||||
def total_document_page_per_month():
|
||||
from .models import DocumentPage
|
||||
DocumentPage = apps.get_model(
|
||||
app_label='documents', model_name='DocumentPage'
|
||||
)
|
||||
|
||||
qss = qsstats.QuerySetStats(DocumentPage.objects.all(), 'document_version__document__date_added')
|
||||
qss = qsstats.QuerySetStats(
|
||||
DocumentPage.objects.all(), 'document_version__document__date_added'
|
||||
)
|
||||
this_year = datetime.date.today().year
|
||||
|
||||
result = []
|
||||
|
||||
Reference in New Issue
Block a user