src/pyams_content/component/paragraph/zmi/milestone.py
changeset 1353 5940373ec65c
parent 1243 837612af4dc3
equal deleted inserted replaced
1352:8242968d86b1 1353:5940373ec65c
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
    10 # FOR A PARTICULAR PURPOSE.
    10 # FOR A PARTICULAR PURPOSE.
    11 #
    11 #
    12 
       
    13 __docformat__ = 'restructuredtext'
       
    14 
    12 
    15 import json
    13 import json
    16 
    14 
    17 from pyramid.decorator import reify
    15 from pyramid.decorator import reify
    18 from pyramid.view import view_config
    16 from pyramid.view import view_config
    21 from z3c.table.column import GetAttrColumn
    19 from z3c.table.column import GetAttrColumn
    22 from z3c.table.interfaces import IColumn, IValues
    20 from z3c.table.interfaces import IColumn, IValues
    23 from zope.interface import Interface, implementer
    21 from zope.interface import Interface, implementer
    24 from zope.schema.vocabulary import getVocabularyRegistry
    22 from zope.schema.vocabulary import getVocabularyRegistry
    25 
    23 
    26 from pyams_content.component.paragraph.interfaces import CONTENT_PARAGRAPHS_VOCABULARY, IParagraphContainerTarget
    24 from pyams_content.component.paragraph.interfaces import CONTENT_PARAGRAPHS_VOCABULARY, \
       
    25     IParagraphContainerTarget
    27 from pyams_content.component.paragraph.interfaces.milestone import IMilestone, IMilestoneContainer, \
    26 from pyams_content.component.paragraph.interfaces.milestone import IMilestone, IMilestoneContainer, \
    28     IMilestoneContainerTarget, IMilestoneParagraph, MILESTONE_PARAGRAPH_TYPE
    27     IMilestoneContainerTarget, IMilestoneParagraph, MILESTONE_PARAGRAPH_TYPE
    29 from pyams_content.component.paragraph.milestone import Milestone, MilestoneParagraph
    28 from pyams_content.component.paragraph.milestone import Milestone, MilestoneParagraph
    30 from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, BaseParagraphAJAXEditForm, \
    29 from pyams_content.component.paragraph.zmi import BaseParagraphAJAXAddForm, \
    31     BaseParagraphAddForm, BaseParagraphAddMenu, BaseParagraphPropertiesEditForm, IParagraphInnerEditFormButtons
    30     BaseParagraphAJAXEditForm, BaseParagraphAddForm, BaseParagraphAddMenu, \
       
    31     BaseParagraphPropertiesEditForm, IParagraphInnerEditFormButtons
    32 from pyams_content.component.paragraph.zmi import IParagraphContainerView
    32 from pyams_content.component.paragraph.zmi import IParagraphContainerView
    33 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    33 from pyams_content.component.paragraph.zmi.interfaces import IParagraphInnerEditor
    34 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
    34 from pyams_content.interfaces import MANAGE_CONTENT_PERMISSION
       
    35 from pyams_content.reference.pictograms.zmi.widget import PictogramSelectFieldWidget
    35 from pyams_content.shared.common import IWfSharedContent
    36 from pyams_content.shared.common import IWfSharedContent
    36 from pyams_form.form import AJAXAddForm, ajax_config
    37 from pyams_form.form import AJAXAddForm, ajax_config
    37 from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
    38 from pyams_form.interfaces.form import IInnerForm, IInnerSubForm
    38 from pyams_form.security import ProtectedFormObjectMixin
    39 from pyams_form.security import ProtectedFormObjectMixin
    39 from pyams_i18n.column import I18nAttrColumn
    40 from pyams_i18n.column import I18nAttrColumn
    40 from pyams_i18n.interfaces import II18n
    41 from pyams_i18n.interfaces import II18n
    41 from pyams_pagelet.pagelet import pagelet_config
    42 from pyams_pagelet.pagelet import pagelet_config
    42 from pyams_skin.container import switch_element_visibility
    43 from pyams_skin.container import switch_element_visibility
    43 from pyams_skin.event import get_json_switched_table_refresh_event, get_json_table_row_refresh_event, \
    44 from pyams_skin.event import get_json_switched_table_refresh_event, \
    44     get_json_widget_refresh_event
    45     get_json_table_row_refresh_event, get_json_widget_refresh_event
    45 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
    46 from pyams_skin.interfaces.viewlet import IToolbarAddingMenu, IWidgetTitleViewletManager
    46 from pyams_skin.layer import IPyAMSLayer
    47 from pyams_skin.layer import IPyAMSLayer
    47 from pyams_skin.table import BaseTable, I18nColumn, SorterColumn, TrashColumn, VisibilitySwitcherColumn
    48 from pyams_skin.table import BaseTable, I18nColumn, SorterColumn, TrashColumn, \
       
    49     VisibilitySwitcherColumn
    48 from pyams_skin.viewlet.toolbar import ToolbarAction
    50 from pyams_skin.viewlet.toolbar import ToolbarAction
    49 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
    51 from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
    50 from pyams_utils.traversing import get_parent
    52 from pyams_utils.traversing import get_parent
    51 from pyams_utils.url import absolute_url
    53 from pyams_utils.url import absolute_url
    52 from pyams_viewlet.viewlet import viewlet_config
    54 from pyams_viewlet.viewlet import viewlet_config
    53 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    55 from pyams_zmi.form import AdminDialogAddForm, AdminDialogEditForm
    54 from pyams_zmi.zmi.table import InnerTableView
    56 from pyams_zmi.zmi.table import InnerTableView
    55 
    57 
       
    58 
       
    59 __docformat__ = 'restructuredtext'
       
    60 
    56 from pyams_content import _
    61 from pyams_content import _
    57 
    62 
    58 
    63 
    59 class IMilestonesView(Interface):
    64 class IMilestonesView(Interface):
    60     """Milestones view marker interface"""
    65     """Milestones view marker interface"""
    62 
    67 
    63 class IMilestonesParentForm(Interface):
    68 class IMilestonesParentForm(Interface):
    64     """Milestones parent form marker interface"""
    69     """Milestones parent form marker interface"""
    65 
    70 
    66 
    71 
    67 @viewlet_config(name='add-milestone-paragraph.menu', context=IParagraphContainerTarget, view=IParagraphContainerView,
    72 @viewlet_config(name='add-milestone-paragraph.menu', context=IParagraphContainerTarget,
    68                 layer=IPyAMSLayer, manager=IToolbarAddingMenu, weight=600)
    73                 view=IParagraphContainerView, layer=IPyAMSLayer, manager=IToolbarAddingMenu,
       
    74                 weight=600)
    69 class MilestoneParagraphAddMenu(BaseParagraphAddMenu):
    75 class MilestoneParagraphAddMenu(BaseParagraphAddMenu):
    70     """Milestone paragraph add menu"""
    76     """Milestone paragraph add menu"""
    71 
    77 
    72     label = _("Milestones...")
    78     label = _("Milestones...")
    73     label_css_class = 'fa fa-fw ' + MilestoneParagraph.icon_class
    79     label_css_class = 'fa fa-fw ' + MilestoneParagraph.icon_class
    74     url = 'add-milestone-paragraph.html'
    80     url = 'add-milestone-paragraph.html'
    75     paragraph_type = MILESTONE_PARAGRAPH_TYPE
    81     paragraph_type = MILESTONE_PARAGRAPH_TYPE
    76 
    82 
    77 
    83 
    78 @pagelet_config(name='add-milestone-paragraph.html', context=IParagraphContainerTarget, layer=IPyAMSLayer,
    84 @pagelet_config(name='add-milestone-paragraph.html', context=IParagraphContainerTarget,
       
    85                 layer=IPyAMSLayer,
    79                 permission=MANAGE_CONTENT_PERMISSION)
    86                 permission=MANAGE_CONTENT_PERMISSION)
    80 @ajax_config(name='add-milestone-paragraph.json', context=IParagraphContainerTarget, layer=IPyAMSLayer,
    87 @ajax_config(name='add-milestone-paragraph.json', context=IParagraphContainerTarget,
       
    88              layer=IPyAMSLayer,
    81              base=BaseParagraphAJAXAddForm)
    89              base=BaseParagraphAJAXAddForm)
    82 class MilestoneParagraphAddForm(BaseParagraphAddForm):
    90 class MilestoneParagraphAddForm(BaseParagraphAddForm):
    83     """Milestone paragraph add form"""
    91     """Milestone paragraph add form"""
    84 
    92 
    85     legend = _("Add new milestone paragraph")
    93     legend = _("Add new milestone paragraph")
   115                 .append(get_json_widget_refresh_event(self.context, self.request,
   123                 .append(get_json_widget_refresh_event(self.context, self.request,
   116                                                       MilestoneParagraphInnerEditForm, 'renderer'))
   124                                                       MilestoneParagraphInnerEditForm, 'renderer'))
   117         return output
   125         return output
   118 
   126 
   119 
   127 
   120 @adapter_config(context=(IMilestoneParagraph, IPyAMSLayer), provides=IParagraphInnerEditor)
   128 @adapter_config(context=(IMilestoneParagraph, IPyAMSLayer),
       
   129                 provides=IParagraphInnerEditor)
   121 @ajax_config(name='inner-properties.json', context=IMilestoneParagraph, layer=IPyAMSLayer,
   130 @ajax_config(name='inner-properties.json', context=IMilestoneParagraph, layer=IPyAMSLayer,
   122              base=BaseParagraphAJAXEditForm)
   131              base=BaseParagraphAJAXEditForm)
   123 @implementer(IInnerForm, IMilestonesParentForm)
   132 @implementer(IInnerForm, IMilestonesParentForm)
   124 class MilestoneParagraphInnerEditForm(MilestoneParagraphPropertiesEditForm):
   133 class MilestoneParagraphInnerEditForm(MilestoneParagraphPropertiesEditForm):
   125     """Milestone paragraph inner edit form"""
   134     """Milestone paragraph inner edit form"""
   176     @reify
   185     @reify
   177     def values(self):
   186     def values(self):
   178         return list(super(MilestonesTable, self).values)
   187         return list(super(MilestonesTable, self).values)
   179 
   188 
   180 
   189 
   181 @adapter_config(context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable), provides=IValues)
   190 @adapter_config(context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
       
   191                 provides=IValues)
   182 class MilestonesTableValuesAdapter(ContextRequestViewAdapter):
   192 class MilestonesTableValuesAdapter(ContextRequestViewAdapter):
   183     """Milestones table values adapter"""
   193     """Milestones table values adapter"""
   184 
   194 
   185     @property
   195     @property
   186     def values(self):
   196     def values(self):
   187         return IMilestoneContainer(self.context).values()
   197         return IMilestoneContainer(self.context).values()
   188 
   198 
   189 
   199 
   190 @adapter_config(name='sorter', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable), provides=IColumn)
   200 @adapter_config(name='sorter',
       
   201                 context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
       
   202                 provides=IColumn)
   191 class MilestonesTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
   203 class MilestonesTableSorterColumn(ProtectedFormObjectMixin, SorterColumn):
   192     """Milestones table sorter column"""
   204     """Milestones table sorter column"""
   193 
   205 
   194 
   206 
   195 @view_config(name='set-milestones-order.json', context=IMilestoneContainer, request_type=IPyAMSLayer,
   207 @view_config(name='set-milestones-order.json', context=IMilestoneContainer,
   196              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   208              request_type=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION,
       
   209              renderer='json', xhr=True)
   197 def set_milestones_order(request):
   210 def set_milestones_order(request):
   198     """Update milestones order"""
   211     """Update milestones order"""
   199     order = list(map(str, json.loads(request.params.get('names'))))
   212     order = list(map(str, json.loads(request.params.get('names'))))
   200     request.context.updateOrder(order)
   213     request.context.updateOrder(order)
   201     return {'status': 'success'}
   214     return {'status': 'success'}
   202 
   215 
   203 
   216 
   204 @adapter_config(name='show-hide', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
   217 @adapter_config(name='show-hide',
       
   218                 context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
   205                 provides=IColumn)
   219                 provides=IColumn)
   206 class MilestonesTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
   220 class MilestonesTableShowHideColumn(ProtectedFormObjectMixin, VisibilitySwitcherColumn):
   207     """Milestones container visibility switcher column"""
   221     """Milestones container visibility switcher column"""
   208 
   222 
   209 
   223 
   210 @view_config(name='switch-milestone-visibility.json', context=IMilestoneContainer, request_type=IPyAMSLayer,
   224 @view_config(name='switch-milestone-visibility.json', context=IMilestoneContainer,
   211              permission=MANAGE_CONTENT_PERMISSION, renderer='json', xhr=True)
   225              request_type=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION,
       
   226              renderer='json', xhr=True)
   212 def switch_milestone_visibility(request):
   227 def switch_milestone_visibility(request):
   213     """Set milestone visibility"""
   228     """Set milestone visibility"""
   214     return switch_element_visibility(request, IMilestoneContainer)
   229     return switch_element_visibility(request, IMilestoneContainer)
   215 
   230 
   216 
   231 
   217 @adapter_config(name='name', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable), provides=IColumn)
   232 @adapter_config(name='name',
       
   233                 context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
       
   234                 provides=IColumn)
   218 class MilestonesTableNameColumn(I18nColumn, I18nAttrColumn):
   235 class MilestonesTableNameColumn(I18nColumn, I18nAttrColumn):
   219     """Milestones table name column"""
   236     """Milestones table name column"""
   220 
   237 
   221     _header = _("Title")
   238     _header = _("Title")
   222     attrName = 'title'
   239     attrName = 'title'
   224 
   241 
   225     def getValue(self, obj):
   242     def getValue(self, obj):
   226         return super(MilestonesTableNameColumn, self).getValue(obj) or '--'
   243         return super(MilestonesTableNameColumn, self).getValue(obj) or '--'
   227 
   244 
   228 
   245 
   229 @adapter_config(name='info', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable), provides=IColumn)
   246 @adapter_config(name='info',
       
   247                 context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
       
   248                 provides=IColumn)
   230 class MilestonesTableInfoColumn(I18nColumn, I18nAttrColumn):
   249 class MilestonesTableInfoColumn(I18nColumn, I18nAttrColumn):
   231     """Milestones table information column"""
   250     """Milestones table information column"""
   232 
   251 
   233     _header = _("Associated label")
   252     _header = _("Associated label")
   234     attrName = 'label'
   253     attrName = 'label'
   236 
   255 
   237     def getValue(self, obj):
   256     def getValue(self, obj):
   238         return super(MilestonesTableInfoColumn, self).getValue(obj) or '--'
   257         return super(MilestonesTableInfoColumn, self).getValue(obj) or '--'
   239 
   258 
   240 
   259 
   241 @adapter_config(name='anchor', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable), provides=IColumn)
   260 @adapter_config(name='anchor', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
       
   261                 provides=IColumn)
   242 class MilestonesTableAnchorColumn(I18nColumn, GetAttrColumn):
   262 class MilestonesTableAnchorColumn(I18nColumn, GetAttrColumn):
   243     """Milestones table anchor column"""
   263     """Milestones table anchor column"""
   244 
   264 
   245     _header = _("Anchor")
   265     _header = _("Anchor")
   246     weight = 30
   266     weight = 30
   258             return vocabulary.getTermByToken(obj.anchor).title
   278             return vocabulary.getTermByToken(obj.anchor).title
   259         except LookupError:
   279         except LookupError:
   260             return self.request.localizer.translate(_("(missing paragraph)")).format(obj.anchor)
   280             return self.request.localizer.translate(_("(missing paragraph)")).format(obj.anchor)
   261 
   281 
   262 
   282 
   263 @adapter_config(name='trash', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable), provides=IColumn)
   283 @adapter_config(name='trash', context=(IMilestoneContainerTarget, IPyAMSLayer, MilestonesTable),
       
   284                 provides=IColumn)
   264 class MilestonesTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
   285 class MilestonesTableTrashColumn(ProtectedFormObjectMixin, TrashColumn):
   265     """Milestones table trash column"""
   286     """Milestones table trash column"""
   266 
   287 
   267 
   288 
   268 @adapter_config(name='milestones', context=(IMilestoneContainerTarget, IPyAMSLayer, IMilestonesParentForm),
   289 @adapter_config(name='milestones',
       
   290                 context=(IMilestoneContainerTarget, IPyAMSLayer, IMilestonesParentForm),
   269                 provides=IInnerSubForm)
   291                 provides=IInnerSubForm)
   270 @implementer(IMilestonesView)
   292 @implementer(IMilestonesView)
   271 class MilestonesView(InnerTableView):
   293 class MilestonesView(InnerTableView):
   272     """Milestones view"""
   294     """Milestones view"""
   273 
   295 
   279 
   301 
   280 #
   302 #
   281 # Milestones forms
   303 # Milestones forms
   282 #
   304 #
   283 
   305 
   284 @viewlet_config(name='add-milestone.action', context=IMilestoneContainerTarget, layer=IPyAMSLayer, view=IMilestonesView,
   306 @viewlet_config(name='add-milestone.action', context=IMilestoneContainerTarget, layer=IPyAMSLayer,
   285                 manager=IWidgetTitleViewletManager, permission=MANAGE_CONTENT_PERMISSION, weight=1)
   307                 view=IMilestonesView, manager=IWidgetTitleViewletManager,
       
   308                 permission=MANAGE_CONTENT_PERMISSION, weight=1)
   286 class MilestoneAddAction(ToolbarAction):
   309 class MilestoneAddAction(ToolbarAction):
   287     """Milestone add action"""
   310     """Milestone add action"""
   288 
   311 
   289     label = _("Add milestone")
   312     label = _("Add milestone")
   290     label_css_class = 'fa fa-fw fa-plus'
   313     label_css_class = 'fa fa-fw fa-plus'
   301 
   324 
   302     legend = _("Add new milestone")
   325     legend = _("Add new milestone")
   303     icon_css_class = 'fa fa-fw fa-arrow-h'
   326     icon_css_class = 'fa fa-fw fa-arrow-h'
   304 
   327 
   305     fields = field.Fields(IMilestone).omit('__parent__', '__name__', 'visible')
   328     fields = field.Fields(IMilestone).omit('__parent__', '__name__', 'visible')
       
   329     fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
       
   330 
   306     edit_permission = MANAGE_CONTENT_PERMISSION
   331     edit_permission = MANAGE_CONTENT_PERMISSION
   307 
   332 
   308     def updateWidgets(self, prefix=None):
   333     def updateWidgets(self, prefix=None):
   309         super(MilestoneAddForm, self).updateWidgets(prefix)
   334         super(MilestoneAddForm, self).updateWidgets(prefix)
   310         if 'label' in self.widgets:
   335         if 'label' in self.widgets:
   318 
   343 
   319     def get_ajax_output(self, changes):
   344     def get_ajax_output(self, changes):
   320         return {
   345         return {
   321             'status': 'success',
   346             'status': 'success',
   322             'message': self.request.localizer.translate(_("Milestone was correctly added")),
   347             'message': self.request.localizer.translate(_("Milestone was correctly added")),
   323             'events': [get_json_switched_table_refresh_event(self.context, self.request, MilestonesTable)]
   348             'events': [
       
   349                 get_json_switched_table_refresh_event(self.context, self.request, MilestonesTable)]
   324         }
   350         }
   325 
   351 
   326 
   352 
   327 @pagelet_config(name='properties.html', context=IMilestone, layer=IPyAMSLayer, permission=MANAGE_CONTENT_PERMISSION)
   353 @pagelet_config(name='properties.html', context=IMilestone, layer=IPyAMSLayer,
       
   354                 permission=MANAGE_CONTENT_PERMISSION)
   328 @ajax_config(name='properties.json', context=IMilestone, layer=IPyAMSLayer)
   355 @ajax_config(name='properties.json', context=IMilestone, layer=IPyAMSLayer)
   329 class MilestonePropertiesEditForm(AdminDialogEditForm):
   356 class MilestonePropertiesEditForm(AdminDialogEditForm):
   330     """Milestone properties edit form"""
   357     """Milestone properties edit form"""
   331 
   358 
   332     prefix = 'milestone_properties.'
   359     prefix = 'milestone_properties.'
   333 
   360 
   334     legend = _("Edit milestone properties")
   361     legend = _("Edit milestone properties")
   335     icon_css_class = 'fa fa-fw fa-arrows-h'
   362     icon_css_class = 'fa fa-fw fa-arrows-h'
   336 
   363 
   337     fields = field.Fields(IMilestone).omit('__parent__', '__name__', 'visible')
   364     fields = field.Fields(IMilestone).omit('__parent__', '__name__', 'visible')
       
   365     fields['pictogram_name'].widgetFactory = PictogramSelectFieldWidget
       
   366 
   338     edit_permission = MANAGE_CONTENT_PERMISSION
   367     edit_permission = MANAGE_CONTENT_PERMISSION
   339 
   368 
   340     def updateWidgets(self, prefix=None):
   369     def updateWidgets(self, prefix=None):
   341         super(MilestonePropertiesEditForm, self).updateWidgets(prefix)
   370         super(MilestonePropertiesEditForm, self).updateWidgets(prefix)
   342         if 'label' in self.widgets:
   371         if 'label' in self.widgets:
   344 
   373 
   345     def get_ajax_output(self, changes):
   374     def get_ajax_output(self, changes):
   346         output = super(self.__class__, self).get_ajax_output(changes)
   375         output = super(self.__class__, self).get_ajax_output(changes)
   347         if changes:
   376         if changes:
   348             target = get_parent(self.context, IMilestoneContainerTarget)
   377             target = get_parent(self.context, IMilestoneContainerTarget)
   349             output.setdefault('events', []).append(get_json_table_row_refresh_event(target, self.request,
   378             output.setdefault('events', []).append(
   350                                                                                     MilestonesTable, self.context))
   379                 get_json_table_row_refresh_event(target, self.request,
       
   380                                                  MilestonesTable, self.context))
   351         return output
   381         return output