Convert the document version list view to item view mode.

Add document version preview and thumbnail widgets.
Update the new version upload event have the version
as the target and the document as the action object.

Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
Roberto Rosario
2017-08-02 03:54:21 -04:00
parent 7a29b2496b
commit 48fc36d54e
8 changed files with 163 additions and 35 deletions

View File

@@ -111,9 +111,7 @@ class DocumentVersionDetachedSignatureCreateView(FormView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_document_version().document, 'object': self.get_document_version(),
'document_version': self.get_document_version(),
'navigation_object_list': ('document', 'document_version'),
'title': _( 'title': _(
'Sign document version "%s" with a detached signature' 'Sign document version "%s" with a detached signature'
) % self.get_document_version(), ) % self.get_document_version(),
@@ -212,9 +210,7 @@ class DocumentVersionEmbeddedSignatureCreateView(FormView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_document_version().document, 'object': self.get_document_version(),
'document_version': self.get_document_version(),
'navigation_object_list': ('document', 'document_version'),
'title': _( 'title': _(
'Sign document version "%s" with a embedded signature' 'Sign document version "%s" with a embedded signature'
) % self.get_document_version(), ) % self.get_document_version(),
@@ -237,11 +233,7 @@ class DocumentVersionSignatureDeleteView(SingleObjectDeleteView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_object().document_version.document, 'object': self.get_object().document_version,
'document_version': self.get_object().document_version,
'navigation_object_list': (
'document', 'document_version', 'signature'
),
'signature': self.get_object(), 'signature': self.get_object(),
'title': _('Delete detached signature: %s') % self.get_object() 'title': _('Delete detached signature: %s') % self.get_object()
} }
@@ -260,13 +252,9 @@ class DocumentVersionSignatureDetailView(SingleObjectDetailView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_object().document_version.document,
'document_version': self.get_object().document_version,
'signature': self.get_object(),
'navigation_object_list': (
'document', 'document_version', 'signature'
),
'hide_object': True, 'hide_object': True,
'object': self.get_object().document_version,
'signature': self.get_object(),
'title': _( 'title': _(
'Details for signature: %s' 'Details for signature: %s'
) % self.get_object(), ) % self.get_object(),
@@ -305,10 +293,8 @@ class DocumentVersionSignatureListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_document_version().document,
'document_version': self.get_document_version(),
'navigation_object_list': ('document', 'document_version'),
'hide_object': True, 'hide_object': True,
'object': self.get_document_version(),
'title': _( 'title': _(
'Signatures for document version: %s' 'Signatures for document version: %s'
) % self.get_document_version(), ) % self.get_document_version(),
@@ -337,9 +323,7 @@ class DocumentVersionSignatureUploadView(SingleObjectCreateView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'document': self.get_document_version().document, 'object': self.get_document_version(),
'document_version': self.get_document_version(),
'navigation_object_list': ('document', 'document_version'),
'title': _( 'title': _(
'Upload detached signature for document version: %s' 'Upload detached signature for document version: %s'
) % self.get_document_version(), ) % self.get_document_version(),

View File

@@ -67,8 +67,10 @@ from .links import (
link_document_type_filename_list, link_document_type_list, link_document_type_filename_list, link_document_type_list,
link_document_type_setup, link_document_update_page_count, link_document_type_setup, link_document_update_page_count,
link_document_version_download, link_document_version_list, link_document_version_download, link_document_version_list,
link_document_version_revert, link_duplicated_document_list, link_document_version_return_document, link_document_version_return_list,
link_duplicated_document_scan, link_trash_can_empty link_document_version_revert, link_document_version_view,
link_duplicated_document_list, link_duplicated_document_scan,
link_trash_can_empty
) )
from .literals import ( from .literals import (
CHECK_DELETE_PERIOD_INTERVAL, CHECK_TRASH_PERIOD_INTERVAL, CHECK_DELETE_PERIOD_INTERVAL, CHECK_TRASH_PERIOD_INTERVAL,
@@ -95,7 +97,10 @@ from .statistics import (
new_document_versions_per_month, total_document_per_month, new_document_versions_per_month, total_document_per_month,
total_document_page_per_month, total_document_version_per_month total_document_page_per_month, total_document_version_per_month
) )
from .widgets import DocumentThumbnailWidget, DocumentPageThumbnailWidget from .widgets import (
DocumentThumbnailWidget, DocumentPageThumbnailWidget,
DocumentVersionThumbnailWidget
)
class DocumentsApp(MayanAppConfig): class DocumentsApp(MayanAppConfig):
@@ -234,9 +239,11 @@ class DocumentsApp(MayanAppConfig):
) )
# Document and document page thumbnail widget # Document and document page thumbnail widget
document_thumbnail_widget = DocumentThumbnailWidget()
document_page_thumbnail_widget = DocumentPageThumbnailWidget() document_page_thumbnail_widget = DocumentPageThumbnailWidget()
document_thumbnail_widget = DocumentThumbnailWidget()
document_version_thumbnail_widget = DocumentVersionThumbnailWidget()
# Document
SourceColumn( SourceColumn(
source=Document, label=_('Thumbnail'), source=Document, label=_('Thumbnail'),
func=lambda context: document_thumbnail_widget.render( func=lambda context: document_thumbnail_widget.render(
@@ -247,6 +254,7 @@ class DocumentsApp(MayanAppConfig):
source=Document, label=_('Type'), attribute='document_type' source=Document, label=_('Type'), attribute='document_type'
) )
# DocumentPage
SourceColumn( SourceColumn(
source=DocumentPage, label=_('Thumbnail'), source=DocumentPage, label=_('Thumbnail'),
func=lambda context: document_page_thumbnail_widget.render( func=lambda context: document_page_thumbnail_widget.render(
@@ -266,6 +274,7 @@ class DocumentsApp(MayanAppConfig):
attribute='document_version.document.document_type' attribute='document_version.document.document_type'
) )
# DocumentType
SourceColumn( SourceColumn(
source=DocumentType, label=_('Documents'), source=DocumentType, label=_('Documents'),
func=lambda context: context['object'].get_document_count( func=lambda context: context['object'].get_document_count(
@@ -278,6 +287,7 @@ class DocumentsApp(MayanAppConfig):
func=lambda context: two_state_template(context['object'].enabled) func=lambda context: two_state_template(context['object'].enabled)
) )
# DeletedDocument
SourceColumn( SourceColumn(
source=DeletedDocument, label=_('Thumbnail'), source=DeletedDocument, label=_('Thumbnail'),
func=lambda context: document_thumbnail_widget.render( func=lambda context: document_thumbnail_widget.render(
@@ -293,6 +303,7 @@ class DocumentsApp(MayanAppConfig):
attribute='deleted_date_time' attribute='deleted_date_time'
) )
# DocumentVersion
SourceColumn( SourceColumn(
source=DocumentVersion, label=_('Time and date'), source=DocumentVersion, label=_('Time and date'),
attribute='timestamp' attribute='timestamp'
@@ -309,6 +320,14 @@ class DocumentsApp(MayanAppConfig):
source=DocumentVersion, label=_('Comment'), source=DocumentVersion, label=_('Comment'),
attribute='comment' attribute='comment'
) )
SourceColumn(
source=DocumentVersion, label=_('Thumbnail'),
func=lambda context: document_version_thumbnail_widget.render(
instance=context['object']
)
)
# DuplicatedDocument
SourceColumn( SourceColumn(
source=DuplicatedDocument, label=_('Thumbnail'), source=DuplicatedDocument, label=_('Thumbnail'),
func=lambda context: document_thumbnail_widget.render( func=lambda context: document_thumbnail_widget.render(
@@ -478,7 +497,8 @@ class DocumentsApp(MayanAppConfig):
# Document actions # Document actions
menu_object.bind_links( menu_object.bind_links(
links=( links=(
link_document_version_revert, link_document_version_download link_document_version_view, link_document_version_revert,
link_document_version_download
), ),
sources=(DocumentVersion,) sources=(DocumentVersion,)
) )
@@ -520,6 +540,14 @@ class DocumentsApp(MayanAppConfig):
links=(link_transformation_list,), sources=(DocumentPage,) links=(link_transformation_list,), sources=(DocumentPage,)
) )
# Document versions
menu_facet.bind_links(
links=(
link_document_version_return_document,
link_document_version_return_list
), sources=(DocumentVersion,)
)
namespace = StatisticNamespace(slug='documents', label=_('Documents')) namespace = StatisticNamespace(slug='documents', label=_('Documents'))
namespace.add_statistic( namespace.add_statistic(
slug='new-documents-per-month', slug='new-documents-per-month',
@@ -576,3 +604,4 @@ class DocumentsApp(MayanAppConfig):
registry.register(DeletedDocument) registry.register(DeletedDocument)
registry.register(Document) registry.register(Document)
registry.register(DocumentType) registry.register(DocumentType)
registry.register(DocumentVersion)

View File

@@ -56,6 +56,22 @@ class DocumentPreviewForm(forms.Form):
preview = forms.CharField(widget=DocumentPagesCarouselWidget()) preview = forms.CharField(widget=DocumentPagesCarouselWidget())
class DocumentVersionPreviewForm(forms.Form):
def __init__(self, *args, **kwargs):
document_version = kwargs.pop('instance', None)
super(DocumentVersionPreviewForm, self).__init__(*args, **kwargs)
self.fields['preview'].initial = document_version
try:
self.fields['preview'].label = _(
'Document pages (%d)'
) % document_version.pages.count()
except AttributeError:
self.fields['preview'].label = _('Document version pages (%d)') % 0
preview = forms.CharField(widget=DocumentPagesCarouselWidget())
class DocumentForm(forms.ModelForm): class DocumentForm(forms.ModelForm):
""" """
Form sub classes from DocumentForm used only when editing a document Form sub classes from DocumentForm used only when editing a document

View File

@@ -142,10 +142,26 @@ link_document_multiple_update_page_count = Link(
link_document_multiple_restore = Link( link_document_multiple_restore = Link(
text=_('Restore'), view='documents:document_multiple_restore' text=_('Restore'), view='documents:document_multiple_restore'
) )
# Versions
link_document_version_download = Link( link_document_version_download = Link(
args='resolved_object.pk', permissions=(permission_document_download,), args='resolved_object.pk', permissions=(permission_document_download,),
text=_('Download version'), view='documents:document_version_download_form' text=_('Download version'), view='documents:document_version_download_form'
) )
link_document_version_return_document = Link(
icon='fa fa-file', permissions=(permission_document_view,),
text=_('Document'), view='documents:document_preview',
args='resolved_object.document.pk'
)
link_document_version_return_list = Link(
icon='fa fa-code-fork', permissions=(permission_document_version_view,),
text=_('Versions'), view='documents:document_version_list',
args='resolved_object.document.pk'
)
link_document_version_view = Link(
args='resolved_object.pk', permissions=(permission_document_version_view,),
text=_('Details'), view='documents:document_version_view'
)
# Views # Views
link_document_list = Link( link_document_list = Link(

View File

@@ -7,6 +7,7 @@ import uuid
from django.conf import settings from django.conf import settings
from django.core.files import File from django.core.files import File
from django.db import models, transaction from django.db import models, transaction
from django.template import Template, Context
from django.urls import reverse from django.urls import reverse
from django.utils.encoding import force_text, python_2_unicode_compatible from django.utils.encoding import force_text, python_2_unicode_compatible
from django.utils.timezone import now from django.utils.timezone import now
@@ -399,7 +400,9 @@ class DocumentVersion(models.Model):
verbose_name_plural = _('Document version') verbose_name_plural = _('Document version')
def __str__(self): def __str__(self):
return '{0} - {1}'.format(self.document, self.timestamp) return Template(
'{{ instance.document }} - {{ instance.timestamp }}'
).render(context=Context({'instance': self}))
def delete(self, *args, **kwargs): def delete(self, *args, **kwargs):
for page in self.pages.all(): for page in self.pages.all():
@@ -409,6 +412,9 @@ class DocumentVersion(models.Model):
return super(DocumentVersion, self).delete(*args, **kwargs) return super(DocumentVersion, self).delete(*args, **kwargs)
def get_absolute_url(self):
return reverse('documents:document_version_view', args=(self.pk,))
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
""" """
Overloaded save method that updates the document version's checksum, Overloaded save method that updates the document version's checksum,
@@ -457,7 +463,7 @@ class DocumentVersion(models.Model):
else: else:
if new_document_version: if new_document_version:
event_document_new_version.commit( event_document_new_version.commit(
actor=user, target=self.document actor=user, target=self, action_object=self.document
) )
post_version_upload.send(sender=DocumentVersion, instance=self) post_version_upload.send(sender=DocumentVersion, instance=self)

View File

@@ -30,9 +30,9 @@ from .views import (
DocumentTypeFilenameEditView, DocumentTypeFilenameListView, DocumentTypeFilenameEditView, DocumentTypeFilenameListView,
DocumentTypeListView, DocumentTypeEditView, DocumentUpdatePageCountView, DocumentTypeListView, DocumentTypeEditView, DocumentUpdatePageCountView,
DocumentVersionDownloadFormView, DocumentVersionDownloadView, DocumentVersionDownloadFormView, DocumentVersionDownloadView,
DocumentVersionListView, DocumentVersionRevertView, DocumentView, DocumentVersionListView, DocumentVersionRevertView, DocumentVersionView,
DuplicatedDocumentListView, EmptyTrashCanView, RecentDocumentListView, DocumentView, DuplicatedDocumentListView, EmptyTrashCanView,
ScanDuplicatedDocuments RecentDocumentListView, ScanDuplicatedDocuments
) )
@@ -148,6 +148,10 @@ urlpatterns = [
DocumentVersionDownloadFormView.as_view(), DocumentVersionDownloadFormView.as_view(),
name='document_version_download_form' name='document_version_download_form'
), ),
url(
r'^document/version/(?P<pk>\d+)/$', DocumentVersionView.as_view(),
name='document_version_view'
),
url( url(
r'^document/version/(?P<pk>\d+)/download/$', r'^document/version/(?P<pk>\d+)/download/$',
DocumentVersionDownloadView.as_view(), name='document_version_download' DocumentVersionDownloadView.as_view(), name='document_version_download'

View File

@@ -7,8 +7,12 @@ from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from acls.models import AccessControlList from acls.models import AccessControlList
from common.generics import ConfirmView, SingleObjectListView from common.generics import (
ConfirmView, SingleObjectDetailView, SingleObjectListView
)
from ..events import event_document_view
from ..forms import DocumentVersionPreviewForm
from ..models import Document, DocumentVersion from ..models import Document, DocumentVersion
from ..permissions import ( from ..permissions import (
permission_document_download, permission_document_version_revert, permission_document_download, permission_document_version_revert,
@@ -38,7 +42,8 @@ class DocumentVersionListView(SingleObjectListView):
def get_extra_context(self): def get_extra_context(self):
return { return {
'hide_object': True, 'object': self.get_document(), 'list_as_items': True,
'object': self.get_document(),
'title': _('Versions of document: %s') % self.get_document(), 'title': _('Versions of document: %s') % self.get_document(),
} }
@@ -96,3 +101,29 @@ class DocumentVersionDownloadFormView(DocumentDownloadFormView):
class DocumentVersionDownloadView(DocumentDownloadView): class DocumentVersionDownloadView(DocumentDownloadView):
model = DocumentVersion model = DocumentVersion
object_permission = permission_document_download object_permission = permission_document_download
class DocumentVersionView(SingleObjectDetailView):
form_class = DocumentVersionPreviewForm
model = DocumentVersion
object_permission = permission_document_version_view
def dispatch(self, request, *args, **kwargs):
result = super(
DocumentVersionView, self
).dispatch(request, *args, **kwargs)
self.get_object().document.add_as_recent_document_for_user(
request.user
)
event_document_view.commit(
actor=request.user, target=self.get_object().document
)
return result
def get_extra_context(self):
return {
'hide_labels': True,
'object': self.get_object(),
'title': _('Preview of document version: %s') % self.get_object(),
}

View File

@@ -333,6 +333,48 @@ class DocumentPageThumbnailWidget(BaseDocumentThumbnailWidget):
return force_text(instance) return force_text(instance)
class DocumentVersionThumbnailWidget(DocumentThumbnailWidget):
width = '100%'
def get_click_view_kwargs(self, instance):
return {
'pk': instance.document.pk,
'version_pk': instance.pk,
'page_pk': instance.pages.first().pk
}
def get_click_view_url(self, instance):
first_page = instance.pages.first()
if first_page:
return super(DocumentVersionThumbnailWidget, self).get_click_view_url(
instance=instance
)
else:
return '#'
def get_preview_view_kwargs(self, instance):
return {
'pk': instance.document.pk,
'version_pk': instance.pk,
'page_pk': instance.pages.first().pk
}
def get_preview_view_url(self, instance):
first_page = instance.pages.first()
if first_page:
return super(DocumentVersionThumbnailWidget, self).get_preview_view_url(
instance=instance
)
else:
return ''
def get_title(self, instance):
return getattr(instance, 'label', None)
def is_valid(self, instance):
return instance.pages
class InteractiveDocumentPageWidget(BaseDocumentThumbnailWidget): class InteractiveDocumentPageWidget(BaseDocumentThumbnailWidget):
click_view_name = None click_view_name = None