src/pyams_content/component/paragraph/zmi/keynumber.py
changeset 671 b6ca6378a8f8
parent 599 7f97d8cae72e
child 680 508a73cab999
equal deleted inserted replaced
670:fecfd4969c4f 671:b6ca6378a8f8
    12 
    12 
    13 __docformat__ = 'restructuredtext'
    13 __docformat__ = 'restructuredtext'
    14 
    14 
    15 
    15 
    16 # import standard library
    16 # import standard library
    17 import json
       
    18 
    17 
    19 # import interfaces
    18 # import interfaces
    20 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer
    19 from pyams_content.component.paragraph.interfaces import IParagraphContainerTarget, IParagraphContainer
    21 from pyams_content.component.paragraph.interfaces.keynumber import KEYNUMBER_PARAGRAPH_TYPE, IKeyNumberParagraph, \
    20 from pyams_content.component.paragraph.interfaces.keynumber import KEYNUMBER_PARAGRAPH_TYPE, IKeyNumberParagraph
    22     IKeyNumberContainer, IKeyNumberContainerTarget, IKeyNumber
       
    23 from pyams_content.component.paragraph.zmi import IParagraphContainerView, IParagraphEditFormButtons
    21 from pyams_content.component.paragraph.zmi import IParagraphContainerView, IParagraphEditFormButtons
    24 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    22 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    25 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    23 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    26 from pyams_content.shared.common import IWfSharedContent
    24 from pyams_content.shared.common import IWfSharedContent
    27 from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
    25 from pyams_form.interfaces.form import IInnerForm
    28 from pyams_i18n.interfaces import II18n
    26 from pyams_i18n.interfaces import II18n
    29 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
    27 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu
    30 from pyams_skin.layer import IPyAMSLayer
    28 from pyams_skin.layer import IPyAMSLayer
    31 from z3c.form.interfaces import INPUT_MODE
    29 from z3c.form.interfaces import INPUT_MODE
    32 from z3c.table.interfaces import IValues, IColumn
       
    33 
    30 
    34 # import packages
    31 # import packages
    35 from pyams_content.component.paragraph.keynumber import KeyNumberParagraph, KeyNumber
    32 from pyams_content.component.keynumber.zmi import IKeyNumbersParentForm
       
    33 from pyams_content.component.paragraph.keynumber import KeyNumberParagraph
    36 from pyams_content.component.paragraph.zmi import BaseParagraphAddMenu, BaseParagraphAJAXAddForm, \
    34 from pyams_content.component.paragraph.zmi import BaseParagraphAddMenu, BaseParagraphAJAXAddForm, \
    37     BaseParagraphPropertiesEditForm, BaseParagraphAJAXEditForm
    35     BaseParagraphPropertiesEditForm, BaseParagraphAJAXEditForm
    38 from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
    36 from pyams_content.features.renderer.zmi.widget import RendererFieldWidget
    39 from pyams_form.form import AJAXAddForm, ajax_config
    37 from pyams_form.form import ajax_config
    40 from pyams_form.security import ProtectedFormObjectMixin
       
    41 from pyams_i18n.column import I18nAttrColumn
       
    42 from pyams_pagelet.pagelet import pagelet_config
    38 from pyams_pagelet.pagelet import pagelet_config
    43 from pyams_skin.container import switch_element_visibility
    39 from pyams_skin.event import get_json_widget_refresh_event
    44 from pyams_skin.event import get_json_widget_refresh_event, get_json_switched_table_refresh_event, \
    40 from pyams_utils.adapter import adapter_config
    45     get_json_table_row_refresh_event
       
    46 from pyams_skin.table import BaseTable, SorterColumn, I18nColumn, VisibilitySwitcherColumn, TrashColumn
       
    47 from pyams_skin.viewlet.toolbar import ToolbarAction
       
    48 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
       
    49 from pyams_utils.traversing import get_parent
    41 from pyams_utils.traversing import get_parent
    50 from pyams_utils.url import absolute_url
       
    51 from pyams_viewlet.viewlet import viewlet_config
    42 from pyams_viewlet.viewlet import viewlet_config
    52 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    43 from pyams_zmi.form import AdminDialogAddForm
    53 from pyams_zmi.zmi.table import InnerTableView
       
    54 from pyramid.decorator import reify
       
    55 from pyramid.view import view_config
       
    56 from z3c.form import field, button
    44 from z3c.form import field, button
    57 from z3c.table.column import GetAttrColumn
       
    58 from zope.interface import implementer, Interface
    45 from zope.interface import implementer, Interface
    59 
    46 
    60 from pyams_content import _
    47 from pyams_content import _
    61 
       
    62 
       
    63 class IKeyNumbersView(Interface):
       
    64     """Key numbers view marker interface"""
       
    65 
       
    66 
       
    67 class IKeyNumbersParentForm(Interface):
       
    68     """Key numbers parent form marker interface"""
       
    69 
    48 
    70 
    49 
    71 @viewlet_config(name='add-keynumber-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
    50 @viewlet_config(name='add-keynumber-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
    72                 layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=600)
    51                 layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=600)
    73 class KeyNumberParagraphAddMenu(BaseParagraphAddMenu):
    52 class KeyNumberParagraphAddMenu(BaseParagraphAddMenu):
   143         updated = changes.get(IKeyNumberParagraph, ())
   122         updated = changes.get(IKeyNumberParagraph, ())
   144         if 'renderer' in updated:
   123         if 'renderer' in updated:
   145             output.setdefault('events', []).append(
   124             output.setdefault('events', []).append(
   146                 get_json_widget_refresh_event(self.context, self.request, KeyNumberParagraphInnerEditForm, 'renderer'))
   125                 get_json_widget_refresh_event(self.context, self.request, KeyNumberParagraphInnerEditForm, 'renderer'))
   147         return output
   126         return output
   148 
       
   149 
       
   150 #
       
   151 # Key number items table view
       
   152 #
       
   153 
       
   154 class KeyNumbersTable(ProtectedFormObjectMixin, BaseTable):
       
   155     """Key numbers view inner table"""
       
   156 
       
   157     prefix = 'keynumbers'
       
   158 
       
   159     hide_header = True
       
   160     sortOn = None
       
   161 
       
   162     @property
       
   163     def cssClasses(self):
       
   164         classes = ['table', 'table-bordered', 'table-striped', 'table-hover', 'table-tight']
       
   165         permission = self.permission
       
   166         if (not permission) or self.request.has_permission(permission, self.context):
       
   167             classes.append('table-dnd')
       
   168         return {'table': ' '.join(classes)}
       
   169 
       
   170     @property
       
   171     def data_attributes(self):
       
   172         attributes = super(KeyNumbersTable, self).data_attributes
       
   173         attributes['table'] = {
       
   174             'id': self.id,
       
   175             'data-ams-location': absolute_url(IKeyNumberContainer(self.context), self.request),
       
   176             'data-ams-tablednd-drag-handle': 'td.sorter',
       
   177             'data-ams-tablednd-drop-target': 'set-keynumbers-order.json',
       
   178             'data-ams-visibility-switcher': 'switch-keynumber-visibility.json'
       
   179         }
       
   180         return attributes
       
   181 
       
   182     @reify
       
   183     def values(self):
       
   184         return list(super(KeyNumbersTable, self).values)
       
   185 
       
   186 
       
   187 @adapter_config(context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IValues)
       
   188 class KeyNumbersTableValuesAdapter(ContextRequestViewAdapter):
       
   189     """Key numbers table values adapter"""
       
   190 
       
   191     @property
       
   192     def values(self):
       
   193         return IKeyNumberContainer(self.context).values()
       
   194 
       
   195 
       
   196 @adapter_config(name='sorter', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
       
   197 class KeyNumbersTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
       
   198     """Key numbers table sorter column"""
       
   199 
       
   200 
       
   201 @view_config(name='set-keynumbers-order.json', context=IKeyNumberContainer, request_type=IPyAMSLayer,
       
   202              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   203 def set_keynumbers_order(request):
       
   204     """Update key numbers order"""
       
   205     order = list(map(str, json.loads(request.params.get('names'))))
       
   206     request.context.updateOrder(order)
       
   207     return {'status': 'success'}
       
   208 
       
   209 
       
   210 @adapter_config(name='show-hide', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable),
       
   211                 provides=IColumn)
       
   212 class KeyNumbersTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
       
   213     """Key numbers container visibility switcher column"""
       
   214 
       
   215 
       
   216 @view_config(name='switch-keynumber-visibility.json', context=IKeyNumberContainer, request_type=IPyAMSLayer,
       
   217              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
       
   218 def switch_keynumber_visibility(request):
       
   219     """Switch key number visibility"""
       
   220     return switch_element_visibility(request, IKeyNumberContainer)
       
   221 
       
   222 
       
   223 @adapter_config(name='label', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
       
   224 class KeyNumbersTableLabelColumn(I18nColumn, I18nAttrColumn):
       
   225     """Key numbers table label column"""
       
   226 
       
   227     _header = _('key-number-label', default="Header")
       
   228     attrName = 'label'
       
   229     weight = 10
       
   230 
       
   231     def getValue(self, obj):
       
   232         return super(KeyNumbersTableLabelColumn, self).getValue(obj) or '--'
       
   233 
       
   234 
       
   235 @adapter_config(name='name', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
       
   236 class KeyNumbersTableNameColumn(I18nColumn, GetAttrColumn):
       
   237     """Key numbers table number column"""
       
   238 
       
   239     _header = _("Number")
       
   240     attrName = 'number'
       
   241     weight = 20
       
   242 
       
   243 
       
   244 @adapter_config(name='unit', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
       
   245 class KeyNumbersTableUnitColumn(I18nColumn, I18nAttrColumn):
       
   246     """Key numbers table unit column"""
       
   247 
       
   248     _header = _('key-number-unit', default="Unit")
       
   249     attrName = 'unit'
       
   250     weight = 30
       
   251 
       
   252     def getValue(self, obj):
       
   253         return super(KeyNumbersTableUnitColumn, self).getValue(obj) or '--'
       
   254 
       
   255 
       
   256 @adapter_config(name='text', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
       
   257 class KeyNumbersTableTextColumn(I18nColumn, I18nAttrColumn):
       
   258     """Key numbers table text column"""
       
   259 
       
   260     _header = _("Associated text")
       
   261     attrName = 'text'
       
   262     weight = 40
       
   263 
       
   264     def getValue(self, obj):
       
   265         return super(KeyNumbersTableTextColumn, self).getValue(obj) or '--'
       
   266 
       
   267 
       
   268 @adapter_config(name='trash', context=(IKeyNumberContainerTarget, IPyAMSLayer, KeyNumbersTable), provides=IColumn)
       
   269 class KeyNumbersTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
       
   270     """Key numbers table trash column"""
       
   271 
       
   272 
       
   273 @adapter_config(name='keynumbers', context=(IKeyNumberContainerTarget, IPyAMSLayer, IKeyNumbersParentForm),
       
   274                 provides=IInnerSubForm)
       
   275 @implementer(IKeyNumbersView)
       
   276 class KeyNumbersView(InnerTableView):
       
   277     """Key numbers view"""
       
   278 
       
   279     title = _("Key numbers")
       
   280 
       
   281     table_class = KeyNumbersTable
       
   282     weight = 110
       
   283 
       
   284 
       
   285 #
       
   286 # Key numbers forms
       
   287 #
       
   288 
       
   289 @viewlet_config(name='add-keynumber.action', context=IKeyNumberContainerTarget, layer=IPyAMSLayer, view=IKeyNumbersView,
       
   290                 manager=IWidgetTitleViewletManager, permission=MANAGE_CONTENT_PERMISSION, weight=1)
       
   291 class KeyNumberAddAction(ToolbarAction):
       
   292     """Key number add action"""
       
   293 
       
   294     label = _("Add keynumber")
       
   295     label_css_class = 'fa fa-fw fa-plus'
       
   296     url = 'add-keynumber.html'
       
   297     modal_target = True
       
   298 
       
   299 
       
   300 @pagelet_config(name='add-keynumber.html', context=IKeyNumberContainerTarget, layer=IPyAMSLayer,
       
   301                 permission=MANAGE_CONTENT_PERMISSION)
       
   302 @ajax_config(name='add-keynumber.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
       
   303              base=AJAXAddForm)
       
   304 class KeyNumberAddForm(AdminDialogAddForm):
       
   305     """Key number add form"""
       
   306 
       
   307     legend = _("Add new keynumber")
       
   308     icon_css_class = 'fa fa-fw fa-dashboard'
       
   309 
       
   310     fields = field.Fields(IKeyNumber).omit('__parent__', '__name__', 'visible')
       
   311     edit_permission = MANAGE_CONTENT_PERMISSION
       
   312 
       
   313     def create(self, data):
       
   314         return KeyNumber()
       
   315 
       
   316     def add(self, object):
       
   317         IKeyNumberContainer(self.context).append(object)
       
   318 
       
   319     def get_ajax_output(self, changes):
       
   320         return {
       
   321             'status': 'success',
       
   322             'message': self.request.localizer.translate(_("Key number was correctly added")),
       
   323             'events': [get_json_switched_table_refresh_event(self.context, self.request, KeyNumbersTable), ]
       
   324         }
       
   325 
       
   326 
       
   327 @pagelet_config(name='properties.html', context=IKeyNumber, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
       
   328 @ajax_config(name='properties.json', context=IKeyNumber, layer=IPyAMSLayer)
       
   329 class KeyNumberPropertiesEditForm(AdminDialogEditForm):
       
   330     """Key number properties edit form"""
       
   331 
       
   332     prefix = 'keynumber_properties.'
       
   333 
       
   334     legend = _("Edit keynumber properties")
       
   335     icon_css_class = 'fa fa-fw fa-dashboard'
       
   336 
       
   337     fields = field.Fields(IKeyNumber).omit('__parent__', '__name__', 'visible')
       
   338     edit_permission = MANAGE_CONTENT_PERMISSION
       
   339 
       
   340     def get_ajax_output(self, changes):
       
   341         output = super(self.__class__, self).get_ajax_output(changes)
       
   342         updated = changes.get(IKeyNumber, ())
       
   343         if updated:
       
   344             target = get_parent(self.context, IKeyNumberContainerTarget)
       
   345             output.setdefault('events', []).append(
       
   346                 get_json_table_row_refresh_event(target, self.request, KeyNumbersTable, self.context))
       
   347         return output