Updated paragraphs management interface
authorThierry Florac <thierry.florac@onf.fr>
Thu, 21 Apr 2016 18:11:18 +0200
changeset 22 c270ea8f041e
parent 21 dc45cba8c8f8
child 23 1c0bac23c875
Updated paragraphs management interface
src/pyams_content/component/paragraph/zmi/container.py
src/pyams_content/component/paragraph/zmi/html.py
src/pyams_content/component/paragraph/zmi/illustration.py
src/pyams_content/component/paragraph/zmi/interfaces.py
src/pyams_content/component/paragraph/zmi/summary.py
src/pyams_content/component/paragraph/zmi/templates/paragraph-title-icon.pt
src/pyams_content/component/paragraph/zmi/templates/paragraph-title-toolbar.pt
--- a/src/pyams_content/component/paragraph/zmi/container.py	Thu Apr 21 18:10:03 2016 +0200
+++ b/src/pyams_content/component/paragraph/zmi/container.py	Thu Apr 21 18:11:18 2016 +0200
@@ -9,7 +9,11 @@
 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
 # FOR A PARTICULAR PURPOSE.
 #
+from zope.contentprovider.interfaces import IContentProvider
+
 from pyams_form.interfaces.form import IFormSecurityContext
+from pyams_viewlet.interfaces import IViewletManager
+from pyams_viewlet.manager import viewletmanager_config, WeightOrderedViewletManager, TemplateBasedViewletManager
 
 __docformat__ = 'restructuredtext'
 
@@ -23,7 +27,7 @@
 from pyams_content.component.gallery.interfaces import IGalleryLinksContainerTarget, IGalleryLinksContainer
 from pyams_content.component.links.interfaces import ILinkLinksContainerTarget, ILinkLinksContainer
 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer, IBaseParagraph
-from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
+from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor, IParagraphTitleToolbar
 from pyams_i18n.interfaces import II18n
 from pyams_skin.interfaces import IInnerPage, IPageHeader
 from pyams_skin.layer import IPyAMSLayer
@@ -44,7 +48,7 @@
 from pyams_utils.url import absolute_url
 from pyramid.exceptions import NotFound
 from pyramid.view import view_config
-from pyams_viewlet.viewlet import viewlet_config
+from pyams_viewlet.viewlet import viewlet_config, Viewlet
 from pyams_zmi.view import AdminView
 from pyramid.decorator import reify
 from z3c.table.column import GetAttrColumn
@@ -180,88 +184,66 @@
     return column.table.context
 
 
-@adapter_config(name='files', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
-                provides=IColumn)
-class ParagraphContainerExtFileLinksColumn(ActionColumn):
-    """Paragraphs container external files links column"""
+@viewletmanager_config(name='pyams_paragraph.title_toolbar', context=IBaseParagraph, layer=IPyAMSLayer,
+                       view=ParagraphContainerTable, provides=IParagraphTitleToolbar)
+@template_config(template='templates/paragraph-title-toolbar.pt', layer=IPyAMSLayer)
+@implementer(IParagraphTitleToolbar)
+class ParagraphTitleToolbarViewletManager(TemplateBasedViewletManager, WeightOrderedViewletManager):
+    """Paragraph title toolbar viewlet manager"""
+
 
+@viewlet_config(name='files', context=IExtFileLinksContainerTarget, layer=IPyAMSLayer, view=ParagraphContainerTable,
+                manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=10)
+@template_config(template='templates/paragraph-title-icon.pt', layer=IPyAMSLayer)
+class ParagraphContainerExtFileLinksAction(Viewlet):
+    """Paragraph container external files links column"""
+
+    action_class = 'action extfiles nowrap width-40'
     icon_class = 'fa fa-fw fa-file-text-o'
     icon_hint = _("External files")
 
-    cssClasses = {'td': 'action extfiles nowrap'}
-
     url = 'extfile-links.html'
     modal_target = True
 
-    weight = 10
-
-    def renderCell(self, item):
-        if not IExtFileLinksContainerTarget.providedBy(item):
-            return ''
-        action = '{action} <span class="count">{{count}}</span>'.format(
-            action=super(ParagraphContainerExtFileLinksColumn, self).renderCell(item))
-        length = len(IExtFileLinksContainer(item).files or ())
-        if length:
-            action = action.format(count='({0})'.format(length))
-        else:
-            action = action.format(count='')
-        return action
+    @property
+    def count(self):
+        return len(IExtFileLinksContainer(self.context).files or ())
 
 
-@adapter_config(name='links', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
-                provides=IColumn)
-class ParagraphContainerLinkLinksColumn(ActionColumn):
-    """Paragraphs container links links column"""
+@viewlet_config(name='links', context=ILinkLinksContainerTarget, layer=IPyAMSLayer, view=ParagraphContainerTable,
+                manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=20)
+@template_config(template='templates/paragraph-title-icon.pt', layer=IPyAMSLayer)
+class ParagraphContainerLinkLinksAction(Viewlet):
+    """Paragraph container links links column"""
 
+    action_class = 'action links nowrap width-40'
     icon_class = 'fa fa-fw fa-link'
     icon_hint = _("Useful links")
 
-    cssClasses = {'td': 'action links nowrap'}
-
     url = 'link-links.html'
     modal_target = True
 
-    weight = 15
-
-    def renderCell(self, item):
-        if not ILinkLinksContainerTarget.providedBy(item):
-            return ''
-        action = '{action} <span class="count">{{count}}</span>'.format(
-            action=super(ParagraphContainerLinkLinksColumn, self).renderCell(item))
-        length = len(ILinkLinksContainer(item).links or ())
-        if length:
-            action = action.format(count='({0})'.format(length))
-        else:
-            action = action.format(count='')
-        return action
+    @property
+    def count(self):
+        return len(ILinkLinksContainer(self.context).links or ())
 
 
-@adapter_config(name='gallery', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
-                provides=IColumn)
-class ParagraphContainerGalleryLinksColumn(ActionColumn):
-    """Paragraphs container gallery links column"""
+@viewlet_config(name='gallery', context=IGalleryLinksContainerTarget, layer=IPyAMSLayer, view=ParagraphContainerTable,
+                manager=IParagraphTitleToolbar, permission=VIEW_SYSTEM_PERMISSION, weight=30)
+@template_config(template='templates/paragraph-title-icon.pt', layer=IPyAMSLayer)
+class ParagraphContainerGalleryLinksAction(Viewlet):
+    """Paragraph container gallery links column"""
 
+    action_class = 'action galleries nowrap width-40'
     icon_class = 'fa fa-fw fa-picture-o'
     icon_hint = _("Images galleries")
 
-    cssClasses = {'td': 'action galleries nowrap'}
-
     url = 'gallery-links.html'
     modal_target = True
 
-    weight = 20
-
-    def renderCell(self, item):
-        if not IGalleryLinksContainerTarget.providedBy(item):
-            return ''
-        action = '{action} <span class="count">{{count}}</span>'.format(
-            action=super(ParagraphContainerGalleryLinksColumn, self).renderCell(item))
-        length = len(IGalleryLinksContainer(item).galleries or ())
-        if length:
-            action = action.format(count='({0})'.format(length))
-        else:
-            action = action.format(count='')
-        return action
+    @property
+    def count(self):
+        return len(IGalleryLinksContainer(self.context).galleries or ())
 
 
 @adapter_config(name='name', context=(IParagraphContainerTarget, IPyAMSLayer, ParagraphContainerTable),
@@ -283,12 +265,20 @@
                super(ParagraphContainerTitleColumn, self).renderHeadCell()
 
     def renderCell(self, item):
-        return '<div><span class="small hint" title="{title}" data-ams-hint-gravity="e"' \
+        registry = self.request.registry
+        provider = registry.queryMultiAdapter((item, self.request, self.table), IContentProvider,
+                                              name='pyams_paragraph.title_toolbar')
+        if provider is not None:
+            provider.update()
+            provider = provider.render()
+        else:
+            provider = ''
+        return '<div>{provider}<span class="small hint" title="{title}" data-ams-hint-gravity="e"' \
                '      data-ams-stop-propagation="true" ' \
                '      data-ams-click-handler="PyAMS_content.paragraphs.switchEditor">' \
                '    <i class="fa fa-plus-square-o"></i>' \
-               '</span> '.format(
-                    title=self.request.localizer.translate(_("Click to open/close paragraph editor"))) + \
+               '</span> '.format(provider=provider,
+                                 title=self.request.localizer.translate(_("Click to open/close paragraph editor"))) + \
                '<span class="title">{0}</span>'.format(super(ParagraphContainerTitleColumn, self).renderCell(item)) + \
                '</div><div class="inner-table-form editor margin-x-10 margin-bottom-0"></div>'
 
--- a/src/pyams_content/component/paragraph/zmi/html.py	Thu Apr 21 18:10:03 2016 +0200
+++ b/src/pyams_content/component/paragraph/zmi/html.py	Thu Apr 21 18:11:18 2016 +0200
@@ -108,7 +108,7 @@
         content = get_parent(self.context, IWfSharedContent)
         return II18n(content).query_attribute('title', request=self.request)
 
-    legend = _("Edit paragraph properties")
+    legend = _("Edit HTML paragraph properties")
     dialog_class = 'modal-max'
     icon_css_class = 'fa fa-fw fa-html5'
     label_css_class = 'control-label col-md-2'
@@ -132,7 +132,7 @@
     """HTML paragraph inner edit form"""
 
     legend = None
-    main_group_legend = _("HTML paragraph properties")
+    main_group_legend = _("HTML paragraph")
     main_group_class = 'inner'
 
     @property
--- a/src/pyams_content/component/paragraph/zmi/illustration.py	Thu Apr 21 18:10:03 2016 +0200
+++ b/src/pyams_content/component/paragraph/zmi/illustration.py	Thu Apr 21 18:11:18 2016 +0200
@@ -117,7 +117,7 @@
     """Illustration inner edit form"""
 
     legend = None
-    main_group_legend = _("Illustration properties")
+    main_group_legend = _("Illustration")
     main_group_class = 'inner'
 
     @property
--- a/src/pyams_content/component/paragraph/zmi/interfaces.py	Thu Apr 21 18:10:03 2016 +0200
+++ b/src/pyams_content/component/paragraph/zmi/interfaces.py	Thu Apr 21 18:11:18 2016 +0200
@@ -17,9 +17,14 @@
 
 # import interfaces
 from pyams_form.interfaces.form import IInnerForm
+from pyams_viewlet.interfaces import IViewletManager
 
 # import packages
 
 
+class IParagraphTitleToolbar(IViewletManager):
+    """Paragraph title toolbar viewlet manager"""
+
+
 class IParagraphInnerEditor(IInnerForm):
     """Paragraph inner editor form interface"""
--- a/src/pyams_content/component/paragraph/zmi/summary.py	Thu Apr 21 18:10:03 2016 +0200
+++ b/src/pyams_content/component/paragraph/zmi/summary.py	Thu Apr 21 18:11:18 2016 +0200
@@ -43,7 +43,7 @@
     """Paragraphs container summary"""
 
     weight = 20
-    tab_label = _("Paragraphs")
+    tab_label = _("Quick preview")
     tab_target = 'paragraphs-summary.html'
 
     fields = field.Fields(Interface)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/zmi/templates/paragraph-title-icon.pt	Thu Apr 21 18:11:18 2016 +0200
@@ -0,0 +1,14 @@
+<div tal:attributes="class string:${view.action_class} pull-left">
+	<a class="hint"
+	   tal:attributes="title view.icon_hint;
+					   href extension:absolute_url(context, view.url);
+					   data-toggle 'modal' if view.modal_target else None;"
+	   data-ams-stop-propagation="true" data-ams-hint-gravity="s" data-ams-hint-offset="2">
+		<i tal:attributes="class view.icon_class"></i>
+	</a>
+	<span class="count">
+		<tal:if define="count view.count" condition="count">
+			(<span tal:content="count"></span>)
+		</tal:if>
+	</span>
+</div>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_content/component/paragraph/zmi/templates/paragraph-title-toolbar.pt	Thu Apr 21 18:11:18 2016 +0200
@@ -0,0 +1,4 @@
+<div class="title-toolbar pull-right">
+	<tal:loop repeat="viewlet view.viewlets"
+			  content="structure viewlet.render()" />
+</div>