web/views/workflow.py
changeset 3890 d7a270f50f54
parent 3659 993997b4b41d
parent 3868 161a5f7d1190
child 3998 94cc7cad3d2d
equal deleted inserted replaced
3810:5b75fd66c80e 3890:d7a270f50f54
    14 from logilab.mtconverter import xml_escape
    14 from logilab.mtconverter import xml_escape
    15 from logilab.common.graph import escape, GraphGenerator, DotBackend
    15 from logilab.common.graph import escape, GraphGenerator, DotBackend
    16 
    16 
    17 from cubicweb import Unauthorized, view
    17 from cubicweb import Unauthorized, view
    18 from cubicweb.selectors import (implements, has_related_entities, one_line_rset,
    18 from cubicweb.selectors import (implements, has_related_entities, one_line_rset,
    19                                 relation_possible, match_form_params)
    19                                 relation_possible, match_form_params,
       
    20                                 entity_implements)
    20 from cubicweb.interfaces import IWorkflowable
    21 from cubicweb.interfaces import IWorkflowable
    21 from cubicweb.view import EntityView
    22 from cubicweb.view import EntityView
    22 from cubicweb.schema import display_name
    23 from cubicweb.schema import display_name
    23 from cubicweb.web import uicfg, stdmsgs, action, component, form, action
    24 from cubicweb.web import uicfg, stdmsgs, action, component, form, action
    24 from cubicweb.web import formfields as ff, formwidgets as fwdgs
    25 from cubicweb.web import formfields as ff, formwidgets as fwdgs
    25 from cubicweb.web.views import TmpFileViewMixin, forms, primary
    26 from cubicweb.web.views import TmpFileViewMixin, forms, primary, autoform
    26 
    27 
    27 _pvs = uicfg.primaryview_section
    28 _pvs = uicfg.primaryview_section
    28 _pvs.tag_subject_of(('Workflow', 'initial_state', '*'), 'hidden')
    29 _pvs.tag_subject_of(('Workflow', 'initial_state', '*'), 'hidden')
    29 _pvs.tag_object_of(('*', 'state_of', 'Workflow'), 'hidden')
    30 _pvs.tag_object_of(('*', 'state_of', 'Workflow'), 'hidden')
    30 _pvs.tag_object_of(('*', 'transition_of', 'Workflow'), 'hidden')
    31 _pvs.tag_object_of(('*', 'transition_of', 'Workflow'), 'hidden')
    48 
    49 
    49 class ChangeStateForm(forms.CompositeEntityForm):
    50 class ChangeStateForm(forms.CompositeEntityForm):
    50     __regid__ = 'changestate'
    51     __regid__ = 'changestate'
    51 
    52 
    52     form_renderer_id = 'base' # don't want EntityFormRenderer
    53     form_renderer_id = 'base' # don't want EntityFormRenderer
    53     form_buttons = [fwdgs.SubmitButton(stdmsgs.YES),
    54     form_buttons = [fwdgs.SubmitButton(),
    54                     fwdgs.Button(stdmsgs.NO, cwaction='cancel')]
    55                     fwdgs.Button(stdmsgs.BUTTON_CANCEL, cwaction='cancel')]
    55 
    56 
    56 
    57 
    57 class ChangeStateFormView(form.FormViewMixIn, view.EntityView):
    58 class ChangeStateFormView(form.FormViewMixIn, view.EntityView):
    58     __regid__ = 'statuschange'
    59     __regid__ = 'statuschange'
    59     title = _('status change')
    60     title = _('status change')
   167             yield self.build_action(self._cw._('view history'), wfurl)
   168             yield self.build_action(self._cw._('view history'), wfurl)
   168 
   169 
   169 
   170 
   170 # workflow entity types views ##################################################
   171 # workflow entity types views ##################################################
   171 
   172 
       
   173 _pvs = uicfg.primaryview_section
       
   174 _pvs.tag_subject_of(('Workflow', 'initial_state', '*'), 'hidden')
       
   175 _pvs.tag_object_of(('*', 'state_of', 'Workflow'), 'hidden')
       
   176 _pvs.tag_object_of(('*', 'transition_of', 'Workflow'), 'hidden')
       
   177 
       
   178 _abaa = uicfg.actionbox_appearsin_addmenu
       
   179 _abaa.tag_subject_of(('BaseTransition', 'condition', 'RQLExpression'), False)
       
   180 _abaa.tag_subject_of(('State', 'allowed_transition', 'BaseTransition'), False)
       
   181 _abaa.tag_object_of(('SubWorkflowExitPoint', 'destination_state', 'State'),
       
   182                     False)
       
   183 _abaa.tag_object_of(('State', 'state_of', 'Workflow'), True)
       
   184 _abaa.tag_object_of(('BaseTransition', 'transition_of', 'Workflow'), False)
       
   185 _abaa.tag_object_of(('Transition', 'transition_of', 'Workflow'), True)
       
   186 _abaa.tag_object_of(('WorkflowTransition', 'transition_of', 'Workflow'), True)
       
   187 
       
   188 class WorkflowPrimaryView(primary.PrimaryView):
       
   189     __select__ = implements('Workflow')
       
   190 
       
   191     def render_entity_attributes(self, entity):
       
   192         self.w(entity.view('reledit', rtype='description'))
       
   193         self.w(u'<img src="%s" alt="%s"/>' % (
       
   194             xml_escape(entity.absolute_url(vid='wfgraph')),
       
   195             xml_escape(self.req._('graphical workflow for %s') % entity.name)))
       
   196 
       
   197 
   172 class CellView(view.EntityView):
   198 class CellView(view.EntityView):
   173     __regid__ = 'cell'
   199     __regid__ = 'cell'
   174     __select__ = implements('TrInfo')
   200     __select__ = implements('TrInfo')
   175 
   201 
   176     def cell_call(self, row, col, cellvid=None):
   202     def cell_call(self, row, col, cellvid=None):
   185     def cell_call(self, row, col):
   211     def cell_call(self, row, col):
   186         self.w(xml_escape(self._cw.view('textincontext', self.cw_rset,
   212         self.w(xml_escape(self._cw.view('textincontext', self.cw_rset,
   187                                         row=row, col=col)))
   213                                         row=row, col=col)))
   188 
   214 
   189 
   215 
   190 class WorkflowPrimaryView(primary.PrimaryView):
   216 # workflow entity types edition ################################################
   191     __select__ = implements('Workflow')
   217 
   192 
   218 _afs = uicfg.autoform_section
   193     def render_entity_attributes(self, entity):
   219 _afs.tag_subject_of(('TrInfo', 'to_state', '*'), 'generated')
   194         self.w(entity.view('reledit', rtype='description'))
   220 _afs.tag_subject_of(('TrInfo', 'from_state', '*'), 'generated')
   195         self.w(u'<img src="%s" alt="%s"/>' % (
   221 _afs.tag_object_of(('State', 'allowed_transition', '*'), 'primary')
   196             xml_escape(entity.absolute_url(vid='wfgraph')),
   222 _afs.tag_subject_of(('State', 'allowed_transition', '*'), 'primary')
   197             xml_escape(self._cw._('graphical workflow for %s') % entity.name)))
   223 
       
   224 def workflow_items_for_relation(req, wfeid, wfrelation, targetrelation):
       
   225     wf = req.entity_from_eid(wfeid)
       
   226     rschema = req.vreg.schema[targetrelation]
       
   227     return sorted((e.view('combobox'), e.eid)
       
   228                   for e in getattr(wf, 'reverse_%s' % wfrelation)
       
   229                   if rschema.has_perm(req, 'add', toeid=e.eid))
       
   230 
       
   231 
       
   232 class TransitionEditionForm(autoform.AutomaticEntityForm):
       
   233     __select__ = entity_implements('Transition')
       
   234 
       
   235     def workflow_states_for_relation(self, targetrelation):
       
   236         eids = self.edited_entity.linked_to('transition_of', 'subject')
       
   237         if eids:
       
   238             return workflow_items_for_relation(self.req, eids[0], 'state_of',
       
   239                                                targetrelation)
       
   240         return []
       
   241 
       
   242     def subject_destination_state_vocabulary(self, rtype, limit=None):
       
   243         if not self.edited_entity.has_eid():
       
   244             return self.workflow_states_for_relation('destination_state')
       
   245         return self.subject_relation_vocabulary(rtype, limit)
       
   246 
       
   247     def object_allowed_transition_vocabulary(self, rtype, limit=None):
       
   248         if not self.edited_entity.has_eid():
       
   249             return self.workflow_states_for_relation('allowed_transition')
       
   250         return self.subject_relation_vocabulary(rtype, limit)
       
   251 
       
   252 
       
   253 class StateEditionForm(autoform.AutomaticEntityForm):
       
   254     __select__ = entity_implements('State')
       
   255 
       
   256     def subject_allowed_transition_vocabulary(self, rtype, limit=None):
       
   257         if not self.edited_entity.has_eid():
       
   258             eids = self.edited_entity.linked_to('state_of', 'subject')
       
   259             if eids:
       
   260                 return workflow_items_for_relation(self.req, eids[0], 'transition_of',
       
   261                                                    'allowed_transition')
       
   262         return []
   198 
   263 
   199 
   264 
   200 # workflow images ##############################################################
   265 # workflow images ##############################################################
   201 
   266 
   202 class WorkflowDotPropsHandler(object):
   267 class WorkflowDotPropsHandler(object):