Yellow Pages: view task_candidates for listing persons with knowledge required for task.
This commit is contained in:
parent
5f072547b1
commit
d21c4a28ea
8 changed files with 114 additions and 28 deletions
|
@ -6,6 +6,8 @@ $Id$
|
||||||
1.1
|
1.1
|
||||||
---
|
---
|
||||||
|
|
||||||
|
- yellow pages: view task_candidates for selecting persons with required
|
||||||
|
knowledge for task
|
||||||
- improve 'move' and 'delegate' actions: create new run, store source and
|
- improve 'move' and 'delegate' actions: create new run, store source and
|
||||||
target work items, keep state when moving
|
target work items, keep state when moving
|
||||||
- keep access trail (history) in session
|
- keep access trail (history) in session
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2011 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -58,14 +58,13 @@ actions.register('editTopic', 'portlet', DialogAction,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class MyKnowledge(BaseView):
|
class MyKnowledge(ConceptView):
|
||||||
|
|
||||||
#template = NamedTemplate('loops.knowledge_macros')
|
|
||||||
template = ViewPageTemplateFile('knowledge_macros.pt')
|
template = ViewPageTemplateFile('knowledge_macros.pt')
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return self.template.macros['requirements']
|
return self.template.macros['requirement_providers']
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def person(self):
|
def person(self):
|
||||||
|
@ -91,3 +90,12 @@ class MyKnowledge(BaseView):
|
||||||
'providers': (BaseView(p.context, request) for p in prov)}
|
'providers': (BaseView(p.context, request) for p in prov)}
|
||||||
for req, prov in providers)
|
for req, prov in providers)
|
||||||
|
|
||||||
|
|
||||||
|
class Candidates(ConceptView):
|
||||||
|
|
||||||
|
template = ViewPageTemplateFile('knowledge_macros.pt')
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def macro(self):
|
||||||
|
return self.template.macros['requirement_candidates']
|
||||||
|
|
||||||
|
|
|
@ -74,8 +74,15 @@
|
||||||
zope.publisher.interfaces.browser.IBrowserRequest"
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
provides="zope.interface.Interface"
|
provides="zope.interface.Interface"
|
||||||
factory="loops.knowledge.browser.MyKnowledge"
|
factory="loops.knowledge.browser.MyKnowledge"
|
||||||
permission="zope.View"
|
permission="zope.View" />
|
||||||
/>
|
|
||||||
|
<zope:adapter
|
||||||
|
name="task_candidates"
|
||||||
|
for="loops.interfaces.IConcept
|
||||||
|
zope.publisher.interfaces.browser.IBrowserRequest"
|
||||||
|
provides="zope.interface.Interface"
|
||||||
|
factory="loops.knowledge.browser.Candidates"
|
||||||
|
permission="zope.View" />
|
||||||
|
|
||||||
<!-- other adapters -->
|
<!-- other adapters -->
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,6 @@ from loops.schema.base import Relation, RelationSet
|
||||||
|
|
||||||
_ = MessageFactory('loops')
|
_ = MessageFactory('loops')
|
||||||
|
|
||||||
# TODO: separate interfaces for viewing and changing methods!
|
|
||||||
|
|
||||||
|
|
||||||
class IPerson(IBasePerson, IKnowing, ILoopsAdapter):
|
class IPerson(IBasePerson, IKnowing, ILoopsAdapter):
|
||||||
""" A person, including knowledge/learning management features.
|
""" A person, including knowledge/learning management features.
|
||||||
|
@ -54,6 +52,12 @@ class ITask(IBaseTask, IRequirementProfile, ILoopsAdapter):
|
||||||
""" A task, also acting as a knowledge requirement profile.
|
""" A task, also acting as a knowledge requirement profile.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
requirements = RelationSet(
|
||||||
|
title=_(u'Requirements'),
|
||||||
|
description=_(u'The knowledge required for this task.'),
|
||||||
|
#target_types=('topic',), # set via global option knowledge.element
|
||||||
|
required=False)
|
||||||
|
|
||||||
|
|
||||||
class ITopic(IConceptSchema, IKnowledgeElement, ILoopsAdapter):
|
class ITopic(IConceptSchema, IKnowledgeElement, ILoopsAdapter):
|
||||||
""" Just a topic, some general classification concept.
|
""" Just a topic, some general classification concept.
|
||||||
|
|
|
@ -150,6 +150,11 @@ class Task(BaseTask, KnowledgeAdapterMixin):
|
||||||
|
|
||||||
implements(ITask)
|
implements(ITask)
|
||||||
|
|
||||||
|
_adapterAttributes = BasePerson._adapterAttributes + ('requirements',)
|
||||||
|
_noexportAttributes = ('requirements',)
|
||||||
|
|
||||||
|
requirements = ParentRelationSetProperty('requires')
|
||||||
|
|
||||||
def getRequirements(self):
|
def getRequirements(self):
|
||||||
return (IKnowledgeElement(c)
|
return (IKnowledgeElement(c)
|
||||||
for c in self.context.getParents((self.requiresPred,)))
|
for c in self.context.getParents((self.requiresPred,)))
|
||||||
|
@ -160,6 +165,26 @@ class Task(BaseTask, KnowledgeAdapterMixin):
|
||||||
def removeRequirement(self, obj):
|
def removeRequirement(self, obj):
|
||||||
self.context.deassignParent(obj.context, (self.requiresPred,))
|
self.context.deassignParent(obj.context, (self.requiresPred,))
|
||||||
|
|
||||||
|
def getCandidates(self):
|
||||||
|
result = []
|
||||||
|
candidates = []
|
||||||
|
reqs = list(self.requirements)
|
||||||
|
for req in reqs:
|
||||||
|
for p in req.getKnowers():
|
||||||
|
if p not in candidates:
|
||||||
|
candidates.append(p)
|
||||||
|
item = dict(person=p, required=[], other=[], fit=0.0)
|
||||||
|
for k in p.knowledge:
|
||||||
|
if k in reqs:
|
||||||
|
item['required'].append(k)
|
||||||
|
item['fit'] += 1.0
|
||||||
|
else:
|
||||||
|
item['other'].append(k)
|
||||||
|
result.append(item)
|
||||||
|
for item in result:
|
||||||
|
item['fit'] /= len(reqs)
|
||||||
|
return sorted(result, key=lambda x: (-x['fit'], x['person'].title))
|
||||||
|
|
||||||
|
|
||||||
class ConceptKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin):
|
class ConceptKnowledgeProvider(AdapterBase, KnowledgeAdapterMixin):
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
<metal:listing define-macro="requirements">
|
<html i18n:domain="loops">
|
||||||
|
|
||||||
|
|
||||||
|
<metal:providers define-macro="requirement_providers">
|
||||||
|
<metal:block use-macro="view/concept_macros/conceptdata" />
|
||||||
<div>
|
<div>
|
||||||
<h3 tal:attributes="class string:content-$level;
|
|
||||||
ondblclick item/openEditWindow">
|
|
||||||
<span i18n:translate="">Concept</span>:
|
|
||||||
<span tal:content="item/title">Title</span>
|
|
||||||
</h3>
|
|
||||||
<metal:listing define-macro="requirementslisting2">
|
<metal:listing define-macro="requirementslisting2">
|
||||||
<div tal:attributes="class string:content-$level;
|
<h3>Requirements</h3>
|
||||||
ondblclick python: item.openEditWindow('configure.html')">
|
|
||||||
<h4>Requirements</h4>
|
|
||||||
<table class="listing">
|
<table class="listing">
|
||||||
<tr>
|
<tr>
|
||||||
<th i18n:translate="">Requirement</th>
|
<th i18n:translate="">Requirement</th>
|
||||||
|
@ -16,20 +13,48 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr tal:repeat="related item/myKnowledgeProvidersForTask">
|
<tr tal:repeat="related item/myKnowledgeProvidersForTask">
|
||||||
<td>
|
<td>
|
||||||
<a href="#"
|
<a tal:attributes="href
|
||||||
tal:attributes="href string:${view/url}/.target${related/required/uniqueId}"
|
string:${view/url}/.target${related/required/uniqueId}"
|
||||||
tal:content="related/required/title">Concept Title</a>
|
tal:content="related/required/title">Concept Title</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<tal:provider repeat="prov related/providers">
|
<tal:provider repeat="prov related/providers">
|
||||||
<a href="#"
|
<a tal:attributes="href string:${view/url}/.target${prov/uniqueId}"
|
||||||
tal:attributes="href string:${view/url}/.target${prov/uniqueId}"
|
|
||||||
tal:content="prov/title">Provider Title</a>
|
tal:content="prov/title">Provider Title</a>
|
||||||
</tal:provider>
|
</tal:provider>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
|
||||||
</metal:listing>
|
</metal:listing>
|
||||||
</div>
|
</div>
|
||||||
</metal:listing>
|
</metal:providers>
|
||||||
|
|
||||||
|
|
||||||
|
<metal:candidates define-macro="requirement_candidates">
|
||||||
|
<metal:block use-macro="view/concept_macros/conceptdata" />
|
||||||
|
<h3 i18n:translate="">Candidates for Task</h3>
|
||||||
|
<table class="listing">
|
||||||
|
<tr>
|
||||||
|
<th i18n:translate="">Candidate</th>
|
||||||
|
<th i18n:translate=""
|
||||||
|
title="coverage"
|
||||||
|
i18n:attributes="title description_fit">Fit</th>
|
||||||
|
<th i18n:translate="">Knowledge</th>
|
||||||
|
</tr>
|
||||||
|
<tr tal:repeat="candidate item/adapted/getCandidates">
|
||||||
|
<td tal:define="person candidate/person">
|
||||||
|
<b tal:omit-tag="python:candidate['fit'] < 1.0">
|
||||||
|
<a tal:attributes="href python:view.getUrlForTarget(person.context)"
|
||||||
|
tal:content="person/title" /></b></td>
|
||||||
|
<td tal:content="candidate/fit" />
|
||||||
|
<td>
|
||||||
|
<tal:knowledge tal:repeat="ke candidate/required">
|
||||||
|
<a tal:attributes="href python:view.getUrlForTarget(ke.context)"
|
||||||
|
tal:content="ke/title" /><tal:sep condition="not:repeat/ke/end">, </tal:sep>
|
||||||
|
</tal:knowledge></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</metal:candidates>
|
||||||
|
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ msgstr ""
|
||||||
|
|
||||||
"Project-Id-Version: $Id$\n"
|
"Project-Id-Version: $Id$\n"
|
||||||
"POT-Creation-Date: 2007-05-22 12:00 CET\n"
|
"POT-Creation-Date: 2007-05-22 12:00 CET\n"
|
||||||
"PO-Revision-Date: 2011-03-07 12:00 CET\n"
|
"PO-Revision-Date: 2011-04-30 12:00 CET\n"
|
||||||
"Last-Translator: Helmut Merz <helmutm@cy55.de>\n"
|
"Last-Translator: Helmut Merz <helmutm@cy55.de>\n"
|
||||||
"Language-Team: loops developers <helmutm@cy55.de>\n"
|
"Language-Team: loops developers <helmutm@cy55.de>\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
|
@ -498,10 +498,25 @@ msgid "End date"
|
||||||
msgstr "Ende"
|
msgstr "Ende"
|
||||||
|
|
||||||
msgid "Knowledge"
|
msgid "Knowledge"
|
||||||
msgstr "Wissen"
|
msgstr "Kompetenzen"
|
||||||
|
|
||||||
|
msgid "Requirements"
|
||||||
|
msgstr "Anforderungen"
|
||||||
|
|
||||||
msgid "The knowledge elements for this person."
|
msgid "The knowledge elements for this person."
|
||||||
msgstr "Die Wissenselemente für diese Person."
|
msgstr "Die Kompetenzen dieser Person."
|
||||||
|
|
||||||
|
msgid "Candidates for Task"
|
||||||
|
msgstr "Kandidaten für Aufgabe"
|
||||||
|
|
||||||
|
msgid "Candidate"
|
||||||
|
msgstr "Kandidat"
|
||||||
|
|
||||||
|
msgid "Fit"
|
||||||
|
msgstr "DG"
|
||||||
|
|
||||||
|
msgid "description_fit"
|
||||||
|
msgstr "Deckungsgrad"
|
||||||
|
|
||||||
msgid "Create loops Note"
|
msgid "Create loops Note"
|
||||||
msgstr "loops-Notiz anlegen"
|
msgstr "loops-Notiz anlegen"
|
||||||
|
|
Loading…
Add table
Reference in a new issue