web/views/workflow.py
changeset 3451 6b46d73823f5
parent 3377 dd9d292b6a6d
child 3460 e4843535db25
equal deleted inserted replaced
3448:495862266785 3451:6b46d73823f5
    54     title = _('status change')
    54     title = _('status change')
    55     __select__ = (one_line_rset() & implements(IWorkflowable)
    55     __select__ = (one_line_rset() & implements(IWorkflowable)
    56                   & match_form_params('treid'))
    56                   & match_form_params('treid'))
    57 
    57 
    58     def cell_call(self, row, col):
    58     def cell_call(self, row, col):
    59         entity = self.rset.get_entity(row, col)
    59         entity = self.cw_rset.get_entity(row, col)
    60         transition = self.req.entity_from_eid(self.req.form['treid'])
    60         transition = self._cw.entity_from_eid(self._cw.form['treid'])
    61         dest = transition.destination()
    61         dest = transition.destination()
    62         _ = self.req._
    62         _ = self._cw._
    63         # specify both rset/row/col and entity in case implements selector (and
    63         # specify both rset/row/col and entity in case implements selector (and
    64         # not entity_implements) is used on custom form
    64         # not entity_implements) is used on custom form
    65         form = self.vreg['forms'].select(
    65         form = self._cw.vreg['forms'].select(
    66             'changestate', self.req, rset=self.rset, row=row, col=col,
    66             'changestate', self._cw, rset=self.cw_rset, row=row, col=col,
    67             entity=entity, transition=transition,
    67             entity=entity, transition=transition,
    68             redirect_path=self.redirectpath(entity))
    68             redirect_path=self.redirectpath(entity))
    69         self.w(form.error_message())
    69         self.w(form.error_message())
    70         self.w(u'<h4>%s %s</h4>\n' % (_(transition.name),
    70         self.w(u'<h4>%s %s</h4>\n' % (_(transition.name),
    71                                       entity.view('oneline')))
    71                                       entity.view('oneline')))
    72         msg = _('status will change from %(st1)s to %(st2)s') % {
    72         msg = _('status will change from %(st1)s to %(st2)s') % {
    73             'st1': _(entity.current_state.name),
    73             'st1': _(entity.current_state.name),
    74             'st2': _(dest.name)}
    74             'st2': _(dest.name)}
    75         self.w(u'<p>%s</p>\n' % msg)
    75         self.w(u'<p>%s</p>\n' % msg)
    76         trinfo = self.vreg['etypes'].etype_class('TrInfo')(self.req)
    76         trinfo = self._cw.vreg['etypes'].etype_class('TrInfo')(self._cw)
    77         self.initialize_varmaker()
    77         trinfo.eid = self._cw.varmaker.next()
    78         trinfo.eid = self.varmaker.next()
    78         subform = self._cw.vreg['forms'].select('edition', self._cw, entity=trinfo,
    79         subform = self.vreg['forms'].select('edition', self.req, entity=trinfo,
       
    80                                             mainform=False)
    79                                             mainform=False)
    81         subform.field_by_name('by_transition').widget = fwdgs.HiddenInput()
    80         subform.field_by_name('by_transition').widget = fwdgs.HiddenInput()
    82         form.form_add_subform(subform)
    81         form.form_add_subform(subform)
    83         self.w(form.form_render(wf_info_for=entity.eid,
    82         self.w(form.form_render(wf_info_for=entity.eid,
    84                                 by_transition=transition.eid))
    83                                 by_transition=transition.eid))
    91     __regid__ = 'wfhistory'
    90     __regid__ = 'wfhistory'
    92     __select__ = relation_possible('wf_info_for', role='object')
    91     __select__ = relation_possible('wf_info_for', role='object')
    93     title = _('Workflow history')
    92     title = _('Workflow history')
    94 
    93 
    95     def cell_call(self, row, col, view=None):
    94     def cell_call(self, row, col, view=None):
    96         _ = self.req._
    95         _ = self._cw._
    97         eid = self.rset[row][col]
    96         eid = self.cw_rset[row][col]
    98         sel = 'Any FS,TS,WF,D'
    97         sel = 'Any FS,TS,WF,D'
    99         rql = ' ORDERBY D DESC WHERE WF wf_info_for X,'\
    98         rql = ' ORDERBY D DESC WHERE WF wf_info_for X,'\
   100               'WF from_state FS, WF to_state TS, WF comment C,'\
    99               'WF from_state FS, WF to_state TS, WF comment C,'\
   101               'WF creation_date D'
   100               'WF creation_date D'
   102         if self.vreg.schema.eschema('CWUser').has_perm(self.req, 'read'):
   101         if self._cw.vreg.schema.eschema('CWUser').has_perm(self._cw, 'read'):
   103             sel += ',U,C'
   102             sel += ',U,C'
   104             rql += ', WF owned_by U?'
   103             rql += ', WF owned_by U?'
   105             displaycols = range(5)
   104             displaycols = range(5)
   106             headers = (_('from_state'), _('to_state'), _('comment'), _('date'),
   105             headers = (_('from_state'), _('to_state'), _('comment'), _('date'),
   107                        _('CWUser'))
   106                        _('CWUser'))
   109             sel += ',C'
   108             sel += ',C'
   110             displaycols = range(4)
   109             displaycols = range(4)
   111             headers = (_('from_state'), _('to_state'), _('comment'), _('date'))
   110             headers = (_('from_state'), _('to_state'), _('comment'), _('date'))
   112         rql = '%s %s, X eid %%(x)s' % (sel, rql)
   111         rql = '%s %s, X eid %%(x)s' % (sel, rql)
   113         try:
   112         try:
   114             rset = self.req.execute(rql, {'x': eid}, 'x')
   113             rset = self._cw.execute(rql, {'x': eid}, 'x')
   115         except Unauthorized:
   114         except Unauthorized:
   116             return
   115             return
   117         if rset:
   116         if rset:
   118             self.wview('table', rset, title=_(self.title), displayactions=False,
   117             self.wview('table', rset, title=_(self.title), displayactions=False,
   119                        displaycols=displaycols, headers=headers)
   118                        displaycols=displaycols, headers=headers)
   125     __select__ = WFHistoryView.__select__ & component.EntityVComponent.__select__
   124     __select__ = WFHistoryView.__select__ & component.EntityVComponent.__select__
   126     context = 'navcontentbottom'
   125     context = 'navcontentbottom'
   127     title = _('Workflow history')
   126     title = _('Workflow history')
   128 
   127 
   129     def cell_call(self, row, col, view=None):
   128     def cell_call(self, row, col, view=None):
   130         self.wview('wfhistory', self.rset, row=row, col=col, view=view)
   129         self.wview('wfhistory', self.cw_rset, row=row, col=col, view=view)
   131 
   130 
   132 
   131 
   133 # workflow actions #############################################################
   132 # workflow actions #############################################################
   134 
   133 
   135 class WorkflowActions(action.Action):
   134 class WorkflowActions(action.Action):
   140 
   139 
   141     submenu = _('workflow')
   140     submenu = _('workflow')
   142     order = 10
   141     order = 10
   143 
   142 
   144     def fill_menu(self, box, menu):
   143     def fill_menu(self, box, menu):
   145         entity = self.rset.get_entity(self.row or 0, self.col or 0)
   144         entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
   146         menu.label = u'%s: %s' % (self.req._('state'), entity.printable_state)
   145         menu.label = u'%s: %s' % (self._cw._('state'), entity.printable_state)
   147         menu.append_anyway = True
   146         menu.append_anyway = True
   148         super(WorkflowActions, self).fill_menu(box, menu)
   147         super(WorkflowActions, self).fill_menu(box, menu)
   149 
   148 
   150     def actual_actions(self):
   149     def actual_actions(self):
   151         entity = self.rset.get_entity(self.row or 0, self.col or 0)
   150         entity = self.cw_rset.get_entity(self.cw_row or 0, self.cw_col or 0)
   152         hastr = False
   151         hastr = False
   153         for tr in entity.possible_transitions():
   152         for tr in entity.possible_transitions():
   154             url = entity.absolute_url(vid='statuschange', treid=tr.eid)
   153             url = entity.absolute_url(vid='statuschange', treid=tr.eid)
   155             yield self.build_action(self.req._(tr.name), url)
   154             yield self.build_action(self._cw._(tr.name), url)
   156             hastr = True
   155             hastr = True
   157         # don't propose to see wf if user can't pass any transition
   156         # don't propose to see wf if user can't pass any transition
   158         if hastr:
   157         if hastr:
   159             wfurl = entity.current_workflow.absolute_url()
   158             wfurl = entity.current_workflow.absolute_url()
   160             yield self.build_action(self.req._('view workflow'), wfurl)
   159             yield self.build_action(self._cw._('view workflow'), wfurl)
   161         if entity.workflow_history:
   160         if entity.workflow_history:
   162             wfurl = entity.absolute_url(vid='wfhistory')
   161             wfurl = entity.absolute_url(vid='wfhistory')
   163             yield self.build_action(self.req._('view history'), wfurl)
   162             yield self.build_action(self._cw._('view history'), wfurl)
   164 
   163 
   165 
   164 
   166 # workflow entity types views ##################################################
   165 # workflow entity types views ##################################################
   167 
   166 
   168 class CellView(view.EntityView):
   167 class CellView(view.EntityView):
   169     __regid__ = 'cell'
   168     __regid__ = 'cell'
   170     __select__ = implements('TrInfo')
   169     __select__ = implements('TrInfo')
   171 
   170 
   172     def cell_call(self, row, col, cellvid=None):
   171     def cell_call(self, row, col, cellvid=None):
   173         self.w(self.rset.get_entity(row, col).view('reledit', rtype='comment'))
   172         self.w(self.cw_rset.get_entity(row, col).view('reledit', rtype='comment'))
   174 
   173 
   175 
   174 
   176 class StateInContextView(view.EntityView):
   175 class StateInContextView(view.EntityView):
   177     """convenience trick, State's incontext view should not be clickable"""
   176     """convenience trick, State's incontext view should not be clickable"""
   178     __regid__ = 'incontext'
   177     __regid__ = 'incontext'
   179     __select__ = implements('State')
   178     __select__ = implements('State')
   180 
   179 
   181     def cell_call(self, row, col):
   180     def cell_call(self, row, col):
   182         self.w(xml_escape(self.view('textincontext', self.rset,
   181         self.w(xml_escape(self.view('textincontext', self.cw_rset,
   183                                      row=row, col=col)))
   182                                      row=row, col=col)))
   184 
   183 
   185 
   184 
   186 class WorkflowPrimaryView(primary.PrimaryView):
   185 class WorkflowPrimaryView(primary.PrimaryView):
   187     __select__ = implements('Workflow')
   186     __select__ = implements('Workflow')
   188 
   187 
   189     def render_entity_attributes(self, entity):
   188     def render_entity_attributes(self, entity):
   190         self.w(entity.view('reledit', rtype='description'))
   189         self.w(entity.view('reledit', rtype='description'))
   191         self.w(u'<img src="%s" alt="%s"/>' % (
   190         self.w(u'<img src="%s" alt="%s"/>' % (
   192             xml_escape(entity.absolute_url(vid='wfgraph')),
   191             xml_escape(entity.absolute_url(vid='wfgraph')),
   193             xml_escape(self.req._('graphical workflow for %s') % entity.name)))
   192             xml_escape(self._cw._('graphical workflow for %s') % entity.name)))
   194 
   193 
   195 
   194 
   196 # workflow images ##############################################################
   195 # workflow images ##############################################################
   197 
   196 
   198 class WorkflowDotPropsHandler(object):
   197 class WorkflowDotPropsHandler(object):
   254     __select__ = implements('Workflow')
   253     __select__ = implements('Workflow')
   255     content_type = 'image/png'
   254     content_type = 'image/png'
   256 
   255 
   257     def _generate(self, tmpfile):
   256     def _generate(self, tmpfile):
   258         """display schema information for an entity"""
   257         """display schema information for an entity"""
   259         entity = self.rset.get_entity(self.row, self.col)
   258         entity = self.cw_rset.get_entity(self.cw_row, self.cw_col)
   260         visitor = WorkflowVisitor(entity)
   259         visitor = WorkflowVisitor(entity)
   261         prophdlr = WorkflowDotPropsHandler(self.req)
   260         prophdlr = WorkflowDotPropsHandler(self._cw)
   262         generator = GraphGenerator(DotBackend('workflow', 'LR',
   261         generator = GraphGenerator(DotBackend('workflow', 'LR',
   263                                               ratio='compress', size='30,12'))
   262                                               ratio='compress', size='30,12'))
   264         return generator.generate(visitor, prophdlr, tmpfile)
   263         return generator.generate(visitor, prophdlr, tmpfile)
   265 
   264