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.browser.view import GenericView
|
||||
from cybertools.meta.interfaces import IOptions
|
||||
from cybertools.meta.element import Element
|
||||
from cybertools.relation.interfaces import IRelationRegistry
|
||||
from cybertools.stateful.interfaces import IStateful
|
||||
from cybertools.text import mimetypes
|
||||
|
@ -132,7 +133,6 @@ class BaseView(GenericView, I18NView):
|
|||
actions = {}
|
||||
portlet_actions = []
|
||||
parts = ()
|
||||
filter_input = ()
|
||||
icon = None
|
||||
modeName = 'view'
|
||||
isToplevel = False
|
||||
|
@ -186,6 +186,15 @@ class BaseView(GenericView, I18NView):
|
|||
return '%s/.%s-%s' % (baseUrl, targetId, normalizeForUrl(title))
|
||||
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
|
||||
def principalId(self):
|
||||
principal = self.request.principal
|
||||
|
@ -574,11 +583,18 @@ class BaseView(GenericView, I18NView):
|
|||
def globalOptions(self):
|
||||
return IOptions(self.loopsRoot)
|
||||
|
||||
def getOptions(self, key):
|
||||
def getOptions(self, keys):
|
||||
for opt in (self.options, self.typeOptions, self.globalOptions):
|
||||
value = opt[key]
|
||||
if not isinstance(value, DummyOptions):
|
||||
return value
|
||||
if isinstance(opt, DummyOptions):
|
||||
continue
|
||||
#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):
|
||||
return IOptions(adapted(relation.predicate), None) or DummyOptions()
|
||||
|
|
|
@ -361,7 +361,7 @@ class ConceptView(BaseView):
|
|||
options = IOptions(adapted(r.predicate), None)
|
||||
if options is not None and options('hide_children'):
|
||||
continue
|
||||
filterOptions = self.getOptions('filter')
|
||||
filterOptions = self.getOptions('filter.states')
|
||||
if not fv.check(r.context, filterOptions):
|
||||
continue
|
||||
yield r
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
<metal:data define-macro="conceptdata">
|
||||
<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:slot define-slot="fields">
|
||||
<metal:block use-macro="view/concept_macros/conceptfields" />
|
||||
|
@ -31,12 +30,14 @@
|
|||
|
||||
|
||||
<metal:selection define-macro="filter_input">
|
||||
<div tal:define="criteria item/filter"
|
||||
<div tal:define="criteria item/filterInput"
|
||||
tal:condition="criteria">
|
||||
<form method="get" name="filter" id="form-filter">
|
||||
<span tal:repeat="crit criteria">
|
||||
<metal:input use-macro="crit/macro" />
|
||||
</span>
|
||||
<input type="submit" name="show" value="Show"
|
||||
tal:condition="nothing" />
|
||||
</form>
|
||||
</div>
|
||||
</metal:selection>
|
||||
|
@ -61,6 +62,7 @@
|
|||
string:$resourceBase/cybertools.icons/table.png" />
|
||||
</a>
|
||||
</h1>
|
||||
<metal:block use-macro="view/concept_macros/filter_input" />
|
||||
</metal:title>
|
||||
<p tal:define="description description|item/renderedDescription"
|
||||
tal:condition="description">
|
||||
|
|
Binary file not shown.
|
@ -3,7 +3,7 @@ msgstr ""
|
|||
|
||||
"Project-Id-Version: $Id$\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"
|
||||
"Language-Team: loops developers <helmutm@cy55.de>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
@ -882,6 +882,9 @@ msgstr "nach"
|
|||
|
||||
# state definitions
|
||||
|
||||
msgid "Show all"
|
||||
msgstr "Alle anzeigen"
|
||||
|
||||
msgid "Restrict to objects with certain states"
|
||||
msgstr "Auf Objekte mit bestimmtem Status beschränken"
|
||||
|
||||
|
|
|
@ -108,17 +108,30 @@ class FilterView(NodeView):
|
|||
result.setdefault(obj.getType(), set([])).add(obj)
|
||||
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):
|
||||
if options:
|
||||
for std in options.states.keys():
|
||||
stf = component.getAdapter(obj, IStateful, name=std)
|
||||
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
|
||||
if options is not None:
|
||||
if not self.checkOptions(obj, options):
|
||||
return False
|
||||
fs = self.filterStructure
|
||||
if not fs:
|
||||
return True
|
||||
|
|
|
@ -35,6 +35,8 @@ from loops.security.common import checkPermission
|
|||
from loops.util import _
|
||||
|
||||
|
||||
template = ViewPageTemplateFile('view_macros.pt')
|
||||
|
||||
statefulActions = ('classification_quality',
|
||||
'simple_publishing',
|
||||
'task_states',)
|
||||
|
@ -78,7 +80,7 @@ for std in statefulActions:
|
|||
#class StateQuery(ConceptView):
|
||||
class StateQuery(BaseView):
|
||||
|
||||
template = ViewPageTemplateFile('view_macros.pt')
|
||||
template = template
|
||||
|
||||
form_action = 'execute_search_action'
|
||||
|
||||
|
@ -145,3 +147,15 @@ class StateQuery(BaseView):
|
|||
uids = q.apply()
|
||||
return self.viewIterator(getObjects(uids, self.loopsRoot))
|
||||
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"
|
||||
permission="zope.View" />
|
||||
|
||||
<browser:page
|
||||
for="loops.interfaces.IConcept"
|
||||
name="filter_input.allstates"
|
||||
class="loops.organize.stateful.browser.FilterAllStates"
|
||||
permission="zope.View" />
|
||||
|
||||
<!-- event handlers -->
|
||||
|
||||
<zope:subscriber handler="loops.organize.stateful.base.handleTransition" />
|
||||
|
|
|
@ -2,8 +2,12 @@
|
|||
|
||||
|
||||
<metal:input define-macro="filter_allstates">
|
||||
<input type="checkbox" name="filter.allstates" value="yes"
|
||||
tal:attributes="checked crit/checked" />
|
||||
<input type="checkbox" name="filter.states" value="all" id="filter-states"
|
||||
onclick="submit()"
|
||||
tal:attributes="checked python:
|
||||
request.form.get('filter.states') == 'all'" />
|
||||
<label for="filter-states"
|
||||
i18n:translate="">Show all</label>
|
||||
</metal:input>
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue