"""views for Project entities
:organization: Logilab
:copyright: 2006-2011 LOGILAB S.A. (Paris, FRANCE), license is LGPL.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
"""
__docformat__ = "restructuredtext en"
_ = unicode
from datetime import datetime
from logilab.mtconverter import xml_escape
from logilab.common import table as _table
from cubicweb.view import EntityView, EntityStartupView
from cubicweb.predicates import (is_instance, has_related_entities, none_rset,
score_entity, paginated_rset)
from cubicweb import tags
from cubicweb.web import component
from cubicweb.web.views import uicfg, tabs, baseviews, tableview, navigation
from cubes.tracker.views import fixed_orderby_rql
_pvdc = uicfg.primaryview_display_ctrl
_pvdc.tag_attribute(('Project', 'description'), {'showlabel': False})
# primary view and tabs ########################################################
class ProjectPrimaryView(tabs.TabbedPrimaryView):
__select__ = is_instance('Project')
tabs = [_('projectinfo_tab'), _('projecttickets_tab'), 'activitystream']
default_tab = 'projectinfo_tab'
# configure projectinfotab
_pvs = uicfg.primaryview_section
_pvs.tag_attribute(('Project', 'name'), 'hidden')
_pvs.tag_attribute(('Project', 'summary'), 'hidden')
# XXX keep '*', not Project to match other target types added in eg forge
_pvs.tag_object_of(('*', 'version_of', 'Project'), 'hidden')
_pvs.tag_object_of(('*', 'concerns', 'Project'), 'hidden')
_pvs.tag_subject_of(('Project', 'uses', '*'), 'attributes')
_pvs.tag_object_of(('Project', 'uses', '*'), 'hidden')
_pvs.tag_object_of(('Project', 'subproject_of', '*'), 'hidden')
_pvs.tag_subject_of(('*', 'subproject_of', 'Project'), 'hidden')
class ProjectInfoTab(tabs.PrimaryTab):
__regid__ = 'projectinfo_tab'
__select__ = is_instance('Project')
title = None # should not appear in possible views
class ProjectTicketsTab(EntityView):
__regid__ = 'projecttickets_tab'
__select__ = is_instance('Project')
title = None # should not appear in possible views
def entity_call(self, entity):
display_all = int(self._cw.form.get('display_all', 0))
divid = self.__regid__ + unicode(entity.eid)
url = self._cw.ajax_replace_url(divid, eid=entity.eid,
vid=self.__regid__,
display_all=int(not display_all))
if display_all:
rql = self.tickets_rql()
msg = u'<a href="%%s">%s</a>.' % self._cw._('Show only active tickets')
else:
rql = self.active_tickets_rql()
msg = self._cw._('Only active tickets are displayed. '
'<a href="%s">Show all tickets</a>.')
self.w(u'<div id="%s">' % divid)
self.w(msg % xml_escape(url))
rset = self._cw.execute(rql, {'x': entity.eid})
self.wview('tracker.tickets.table', rset, 'null')
self.w(u'</div>')
SORT_DEFS = (('in_state', 'S'), ('num', 'VN'), ('type', 'TT'), ('priority', 'TP'))
TICKET_DEFAULT_STATE_RESTR = 'S name IN ("created","identified","released","scheduled")'
def tickets_rql(self):
# prefetch everything we can for optimization
return ('Any T,TTI,TT,TP,TD,TDF,TCD,TMD,S,SN,V,VN,U,UL,TDU %s WHERE '
'T title TTI, T type TT, T priority TP, '
'T description TD, T description_format TDF, '
'T creation_date TCD, T modification_date TMD, '
'T in_state S, S name SN, '
'T done_in V?, V num VN, '
'T assigned_to TDU?, '
'T created_by U?, U login UL, '
'T concerns P, P eid %%(x)s'
% fixed_orderby_rql(self.SORT_DEFS))
def active_tickets_rql(self):
return self.tickets_rql() + ', ' + self.TICKET_DEFAULT_STATE_RESTR
class TicketsNavigation(navigation.SortedNavigation):
__select__ = (navigation.SortedNavigation.__select__
& ~paginated_rset(4) & is_instance('Ticket'))
def sort_on(self):
col, attrname = super(TicketsNavigation, self).sort_on()
if col == 6:
# sort on state, we don't want that
return None, None
return col, attrname
class RelativeDateColRenderer(tableview.EntityTableColRenderer):
def render_cell(self, w, rownum):
value = datetime.now() - getattr(self.entity(rownum), self.colid)
w(self._cw.printable_value('Interval', value))
class ProjectTicketsTable(tableview.EntityTableView):
__regid__ = 'tracker.tickets.table'
__select__ = is_instance('Ticket')
columns = ['ticket', 'type', 'priority', 'in_state', 'done_in',
'creation_date', 'modification_date', 'created_by', 'assigned_to']
column_renderers = {
'ticket': tableview.MainEntityColRenderer(),
'creation_date': RelativeDateColRenderer(header=_('created')),
'modification_date': RelativeDateColRenderer(header=_('modified')),
'created_by': tableview.RelatedEntityColRenderer(
getrelated=lambda x: x.creator),
'in_state': tableview.EntityTableColRenderer(
renderfunc=lambda w,x: w(x.cw_adapt_to('IWorkflowable').printable_state)),
'done_in': tableview.RelatedEntityColRenderer(
getrelated=lambda x: x.done_in and x.done_in[0] or None),
'assigned_to': tableview.RelatedEntityColRenderer(
getrelated=lambda x: x.assigned_to and x.assigned_to[0] or None),
}
layout_args = {
'display_filter': 'top',
'hide_filter': False,
'add_view_actions': True,
}
# contextual components ########################################################
class ProjectRoadmapComponent(component.EntityCtxComponent):
"""display the latest published version and in preparation version"""
__regid__ = 'roadmap'
__select__ = (component.EntityCtxComponent.__select__ &
is_instance('Project') &
has_related_entities('version_of', 'object'))
context = 'navcontenttop'
order = 10
def render_body(self, w):
if getattr(self.entity, 'summary', None):
w(u'<div id="summary">%s</div>' % xml_escape(self.entity.summary))
self.entity.view('roadmap', w=w)
class ProjectTreeComponent(component.EntityCtxComponent):
"""display project/subprojects tree"""
__regid__ = 'projecttree'
__select__ = (component.EntityCtxComponent.__select__ &
is_instance('Project') &
score_entity(lambda x: x.cw_adapt_to('ITree').children()))
title = _('Project tree')
context = 'navcontentbottom'
def render_body(self, w):
rset = self.entity.cw_adapt_to('ITree').children(entities=False)
treeid = 'project_tree_%s' % self.entity.eid
self._cw.view('treeview', rset=rset, treeid=treeid,
initial_thru_ajax=True, w=w)
# secondary views ##############################################################
class ProjectRoadmapView(EntityView):
"""display the latest published version and in preparation version"""
__regid__ = 'roadmap'
__select__ = (is_instance('Project') &
has_related_entities('version_of', 'object'))
title = None # should not appear in possible views
rql = ('Any V,DATE ORDERBY version_sort_value(N) '
'WHERE V num N, V prevision_date DATE, V version_of X, '
'V in_state S, S name IN ("planned", "dev", "ready"), '
'X eid %(x)s')
def cell_call(self, row, col):
self._cw.add_css('cubes.tracker.css')
self.w(u'<div class="section">')
entity = self.cw_rset.get_entity(row, col)
currentversion = entity.latest_version()
if currentversion:
self.w(self._cw._('latest published version:'))
self.w(u' ')
currentversion.view('incontext', w=self.w)
挣扎的蓝藻
- 粉丝: 8w+
- 资源: 15万+
评论0