improve option-controlled filtering by states, + checkbox for showing all items

This commit is contained in:
Helmut Merz 2012-11-24 09:42:21 +01:00
parent 757a1cd60c
commit 8d24a40724
9 changed files with 80 additions and 22 deletions

View file

@ -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()

View file

@ -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

View file

@ -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.

View file

@ -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"

View file

@ -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

View file

@ -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']

View file

@ -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" />

View file

@ -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>