improve option-controlled filtering by states, + checkbox for showing all items
This commit is contained in:
parent
757a1cd60c
commit
8d24a40724
9 changed files with 80 additions and 22 deletions
|
@ -54,6 +54,7 @@ from zope.traversing.api import getName, getParent
|
||||||
from cybertools.ajax.dojo import dojoMacroTemplate
|
from cybertools.ajax.dojo import dojoMacroTemplate
|
||||||
from cybertools.browser.view import GenericView
|
from cybertools.browser.view import GenericView
|
||||||
from cybertools.meta.interfaces import IOptions
|
from cybertools.meta.interfaces import IOptions
|
||||||
|
from cybertools.meta.element import Element
|
||||||
from cybertools.relation.interfaces import IRelationRegistry
|
from cybertools.relation.interfaces import IRelationRegistry
|
||||||
from cybertools.stateful.interfaces import IStateful
|
from cybertools.stateful.interfaces import IStateful
|
||||||
from cybertools.text import mimetypes
|
from cybertools.text import mimetypes
|
||||||
|
@ -132,7 +133,6 @@ class BaseView(GenericView, I18NView):
|
||||||
actions = {}
|
actions = {}
|
||||||
portlet_actions = []
|
portlet_actions = []
|
||||||
parts = ()
|
parts = ()
|
||||||
filter_input = ()
|
|
||||||
icon = None
|
icon = None
|
||||||
modeName = 'view'
|
modeName = 'view'
|
||||||
isToplevel = False
|
isToplevel = False
|
||||||
|
@ -186,6 +186,15 @@ class BaseView(GenericView, I18NView):
|
||||||
return '%s/.%s-%s' % (baseUrl, targetId, normalizeForUrl(title))
|
return '%s/.%s-%s' % (baseUrl, targetId, normalizeForUrl(title))
|
||||||
return '%s/.%s' % (baseUrl, targetId)
|
return '%s/.%s' % (baseUrl, targetId)
|
||||||
|
|
||||||
|
def filterInput(self):
|
||||||
|
result = []
|
||||||
|
for name in self.getOptions('filter_input'):
|
||||||
|
view = component.queryMultiAdapter(
|
||||||
|
(self.context, self.request), name='filter_input.' + name)
|
||||||
|
if view is not None:
|
||||||
|
result.append(view)
|
||||||
|
return result
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def principalId(self):
|
def principalId(self):
|
||||||
principal = self.request.principal
|
principal = self.request.principal
|
||||||
|
@ -574,11 +583,18 @@ class BaseView(GenericView, I18NView):
|
||||||
def globalOptions(self):
|
def globalOptions(self):
|
||||||
return IOptions(self.loopsRoot)
|
return IOptions(self.loopsRoot)
|
||||||
|
|
||||||
def getOptions(self, key):
|
def getOptions(self, keys):
|
||||||
for opt in (self.options, self.typeOptions, self.globalOptions):
|
for opt in (self.options, self.typeOptions, self.globalOptions):
|
||||||
value = opt[key]
|
if isinstance(opt, DummyOptions):
|
||||||
if not isinstance(value, DummyOptions):
|
continue
|
||||||
return value
|
#import pdb; pdb.set_trace()
|
||||||
|
v = opt
|
||||||
|
for key in keys.split('.'):
|
||||||
|
if isinstance(v, list):
|
||||||
|
break
|
||||||
|
v = getattr(v, key)
|
||||||
|
if not isinstance(v, DummyOptions):
|
||||||
|
return v
|
||||||
|
|
||||||
def getPredicateOptions(self, relation):
|
def getPredicateOptions(self, relation):
|
||||||
return IOptions(adapted(relation.predicate), None) or DummyOptions()
|
return IOptions(adapted(relation.predicate), None) or DummyOptions()
|
||||||
|
|
|
@ -361,7 +361,7 @@ class ConceptView(BaseView):
|
||||||
options = IOptions(adapted(r.predicate), None)
|
options = IOptions(adapted(r.predicate), None)
|
||||||
if options is not None and options('hide_children'):
|
if options is not None and options('hide_children'):
|
||||||
continue
|
continue
|
||||||
filterOptions = self.getOptions('filter')
|
filterOptions = self.getOptions('filter.states')
|
||||||
if not fv.check(r.context, filterOptions):
|
if not fv.check(r.context, filterOptions):
|
||||||
continue
|
continue
|
||||||
yield r
|
yield r
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
|
|
||||||
<metal:data define-macro="conceptdata">
|
<metal:data define-macro="conceptdata">
|
||||||
<div tal:attributes="class string:content-$level;">
|
<div tal:attributes="class string:content-$level;">
|
||||||
<metal:block use-macro="view/concept_macros/filter_input" />
|
|
||||||
<metal:block use-macro="view/concept_macros/concepttitle" />
|
<metal:block use-macro="view/concept_macros/concepttitle" />
|
||||||
<metal:slot define-slot="fields">
|
<metal:slot define-slot="fields">
|
||||||
<metal:block use-macro="view/concept_macros/conceptfields" />
|
<metal:block use-macro="view/concept_macros/conceptfields" />
|
||||||
|
@ -31,12 +30,14 @@
|
||||||
|
|
||||||
|
|
||||||
<metal:selection define-macro="filter_input">
|
<metal:selection define-macro="filter_input">
|
||||||
<div tal:define="criteria item/filter"
|
<div tal:define="criteria item/filterInput"
|
||||||
tal:condition="criteria">
|
tal:condition="criteria">
|
||||||
<form method="get" name="filter" id="form-filter">
|
<form method="get" name="filter" id="form-filter">
|
||||||
<span tal:repeat="crit criteria">
|
<span tal:repeat="crit criteria">
|
||||||
<metal:input use-macro="crit/macro" />
|
<metal:input use-macro="crit/macro" />
|
||||||
</span>
|
</span>
|
||||||
|
<input type="submit" name="show" value="Show"
|
||||||
|
tal:condition="nothing" />
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</metal:selection>
|
</metal:selection>
|
||||||
|
@ -61,6 +62,7 @@
|
||||||
string:$resourceBase/cybertools.icons/table.png" />
|
string:$resourceBase/cybertools.icons/table.png" />
|
||||||
</a>
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
<metal:block use-macro="view/concept_macros/filter_input" />
|
||||||
</metal:title>
|
</metal:title>
|
||||||
<p tal:define="description description|item/renderedDescription"
|
<p tal:define="description description|item/renderedDescription"
|
||||||
tal:condition="description">
|
tal:condition="description">
|
||||||
|
|
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: 2012-11-22 12:00 CET\n"
|
"PO-Revision-Date: 2012-11-24 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"
|
||||||
|
@ -882,6 +882,9 @@ msgstr "nach"
|
||||||
|
|
||||||
# state definitions
|
# state definitions
|
||||||
|
|
||||||
|
msgid "Show all"
|
||||||
|
msgstr "Alle anzeigen"
|
||||||
|
|
||||||
msgid "Restrict to objects with certain states"
|
msgid "Restrict to objects with certain states"
|
||||||
msgstr "Auf Objekte mit bestimmtem Status beschränken"
|
msgstr "Auf Objekte mit bestimmtem Status beschränken"
|
||||||
|
|
||||||
|
|
|
@ -108,17 +108,30 @@ class FilterView(NodeView):
|
||||||
result.setdefault(obj.getType(), set([])).add(obj)
|
result.setdefault(obj.getType(), set([])).add(obj)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
def checkOptions(self, obj, options):
|
||||||
|
if isinstance(options, list):
|
||||||
|
return True
|
||||||
|
form = self.request.form
|
||||||
|
if form.get('filter.states') == 'all':
|
||||||
|
return True
|
||||||
|
filterStates = options
|
||||||
|
for std in filterStates.keys():
|
||||||
|
formStates = form.get('filter.states.' + std)
|
||||||
|
if formStates == 'all':
|
||||||
|
continue
|
||||||
|
stf = component.getAdapter(obj, IStateful, name=std)
|
||||||
|
if formStates:
|
||||||
|
if stf.state not in formStates.split(','):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if stf.state not in getattr(filterStates, std):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def check(self, obj, options=None):
|
def check(self, obj, options=None):
|
||||||
if options:
|
if options is not None:
|
||||||
for std in options.states.keys():
|
if not self.checkOptions(obj, options):
|
||||||
stf = component.getAdapter(obj, IStateful, name=std)
|
return False
|
||||||
formStates = self.request.form.get('states.' + std)
|
|
||||||
if formStates:
|
|
||||||
if stf.state not in formStates.split(','):
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
if stf.state not in getattr(options.states, std):
|
|
||||||
return False
|
|
||||||
fs = self.filterStructure
|
fs = self.filterStructure
|
||||||
if not fs:
|
if not fs:
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -35,6 +35,8 @@ from loops.security.common import checkPermission
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
|
||||||
|
|
||||||
|
template = ViewPageTemplateFile('view_macros.pt')
|
||||||
|
|
||||||
statefulActions = ('classification_quality',
|
statefulActions = ('classification_quality',
|
||||||
'simple_publishing',
|
'simple_publishing',
|
||||||
'task_states',)
|
'task_states',)
|
||||||
|
@ -78,7 +80,7 @@ for std in statefulActions:
|
||||||
#class StateQuery(ConceptView):
|
#class StateQuery(ConceptView):
|
||||||
class StateQuery(BaseView):
|
class StateQuery(BaseView):
|
||||||
|
|
||||||
template = ViewPageTemplateFile('view_macros.pt')
|
template = template
|
||||||
|
|
||||||
form_action = 'execute_search_action'
|
form_action = 'execute_search_action'
|
||||||
|
|
||||||
|
@ -145,3 +147,15 @@ class StateQuery(BaseView):
|
||||||
uids = q.apply()
|
uids = q.apply()
|
||||||
return self.viewIterator(getObjects(uids, self.loopsRoot))
|
return self.viewIterator(getObjects(uids, self.loopsRoot))
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
class FilterAllStates(BaseView):
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def macros(self):
|
||||||
|
return template.macros
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def macro(self):
|
||||||
|
return self.macros['filter_allstates']
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,12 @@
|
||||||
class="loops.organize.stateful.browser.StateQuery"
|
class="loops.organize.stateful.browser.StateQuery"
|
||||||
permission="zope.View" />
|
permission="zope.View" />
|
||||||
|
|
||||||
|
<browser:page
|
||||||
|
for="loops.interfaces.IConcept"
|
||||||
|
name="filter_input.allstates"
|
||||||
|
class="loops.organize.stateful.browser.FilterAllStates"
|
||||||
|
permission="zope.View" />
|
||||||
|
|
||||||
<!-- event handlers -->
|
<!-- event handlers -->
|
||||||
|
|
||||||
<zope:subscriber handler="loops.organize.stateful.base.handleTransition" />
|
<zope:subscriber handler="loops.organize.stateful.base.handleTransition" />
|
||||||
|
|
|
@ -2,8 +2,12 @@
|
||||||
|
|
||||||
|
|
||||||
<metal:input define-macro="filter_allstates">
|
<metal:input define-macro="filter_allstates">
|
||||||
<input type="checkbox" name="filter.allstates" value="yes"
|
<input type="checkbox" name="filter.states" value="all" id="filter-states"
|
||||||
tal:attributes="checked crit/checked" />
|
onclick="submit()"
|
||||||
|
tal:attributes="checked python:
|
||||||
|
request.form.get('filter.states') == 'all'" />
|
||||||
|
<label for="filter-states"
|
||||||
|
i18n:translate="">Show all</label>
|
||||||
</metal:input>
|
</metal:input>
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue