From e18392ac0f791567666f1ad2cc9bcee4d318d67b Mon Sep 17 00:00:00 2001 From: Helmut Merz Date: Thu, 26 May 2011 10:26:50 +0200 Subject: [PATCH] Provide actions on selected objects of a search result. - delete and change state actions - show/hide actions - display search results again after execution of action - show info message - permission checks --- browser/loops.css | 11 +++-- browser/skin/lobo/lobo.css | 11 +++-- expert/browser/configure.zcml | 67 +++++++++++++++----------- expert/browser/search.pt | 88 ++++++++++++++++++++++++++--------- expert/browser/search.py | 50 +++++++++++++++----- expert/configure.zcml | 12 ----- 6 files changed, 157 insertions(+), 82 deletions(-) diff --git a/browser/loops.css b/browser/loops.css index 4ca8eb1..a28fd08 100644 --- a/browser/loops.css +++ b/browser/loops.css @@ -416,6 +416,13 @@ img.notselected { font-weight: bold; } +.message { + font-weight: bold; + background-color: #c3d9ff; + padding: 4px; + margin-bottom: 4px; +} + /* comments */ div.comment { @@ -440,10 +447,6 @@ div.comment { padding: 2px; } -.searchForm input.submit { - font-weight: bold; -} - /* blog */ .blog .description { diff --git a/browser/skin/lobo/lobo.css b/browser/skin/lobo/lobo.css index 31c0482..ea68852 100644 --- a/browser/skin/lobo/lobo.css +++ b/browser/skin/lobo/lobo.css @@ -417,6 +417,13 @@ img.notselected { font-weight: bold; } +.message { + font-weight: bold; + background-color: #c3d9ff; + padding: 4px; + margin-bottom: 4px; +} + /* lobo layout-specific classes */ .legend { @@ -447,10 +454,6 @@ div.comment { padding: 2px; } -.searchForm input.submit { - font-weight: bold; -} - /* blog */ .blog .description { diff --git a/expert/browser/configure.zcml b/expert/browser/configure.zcml index cca5154..4d71dfa 100644 --- a/expert/browser/configure.zcml +++ b/expert/browser/configure.zcml @@ -6,41 +6,52 @@ i18n_domain="loops"> + name="action_query.html" + for="loops.interfaces.IConcept + zope.publisher.interfaces.browser.IBrowserRequest" + provides="zope.interface.Interface" + factory="loops.expert.browser.base.BaseQueryView" + permission="zope.View" /> + name="search.html" + for="loops.interfaces.INode" + class="loops.expert.browser.search.QuickSearchResults" + permission="zope.View" /> + name="search" + for="loops.interfaces.IConcept + zope.publisher.interfaces.browser.IBrowserRequest" + provides="zope.interface.Interface" + factory="loops.expert.browser.search.Search" + permission="zope.View" /> + name="listConceptsForComboBox.js" + for="loops.interfaces.ILoopsObject" + class="loops.expert.browser.search.Search" + attribute="listConcepts" + permission="zope.View" /> + name="searchresults.html" + for="loops.interfaces.ILoopsObject" + class="loops.expert.browser.search.SearchResults" + permission="zope.View" /> + + + + diff --git a/expert/browser/search.pt b/expert/browser/search.pt index d513e2f..50cfee4 100644 --- a/expert/browser/search.pt +++ b/expert/browser/search.pt @@ -33,11 +33,15 @@ tal:content="item/title"> Search +
-
-
-
+ +
+
@@ -56,25 +60,22 @@
+ i18n:attributes="value" /> - -
-
- - - +
+
+ + + +
-
@@ -105,13 +106,16 @@ + targetUrl python:view.getUrlForTarget(row); + selected_uids request/selection|python:[]"> + tal:attributes="value uid; + checked python: + uid in selected_uids" /> @@ -149,13 +153,8 @@ -
-
+
-
@@ -395,4 +394,49 @@ param not in ['type', 'text', 'concept', 'state']" />  + +
+
+ Show Actions
+ +
+ + \ No newline at end of file diff --git a/expert/browser/search.py b/expert/browser/search.py index facab32..ae4b3b1 100644 --- a/expert/browser/search.py +++ b/expert/browser/search.py @@ -36,7 +36,7 @@ from loops.common import adapted, AdapterBase from loops.expert.concept import ConceptQuery, FullQuery from loops.interfaces import IResource from loops.organize.personal.browser.filter import FilterView -from loops.security.common import canWriteObject +from loops.security.common import canWriteObject, checkPermission from loops import util from loops.util import _ @@ -89,7 +89,8 @@ class Search(BaseView): @Lazy def showActions(self): - return canWriteObject(self.context) + return checkPermission('loops.ManageSite', self.context) + #return canWriteObject(self.context) @property def rowNum(self): @@ -270,9 +271,8 @@ class Search(BaseView): return True -#class SearchResults(BaseView): class SearchResults(NodeView): - """ Provides results as inner HTML """ + """ Provides results as inner HTML - not used any more (?)""" @Lazy def search_macros(self): @@ -331,13 +331,39 @@ class ActionExecutor(FormController): form = self.request.form actions = [k for k in form.keys() if k.startswith('action.')] if actions: + action = actions[0].split('.', 1)[1] uids = form.get('selection', []) - action = actions[0] - if action == 'action.delete': - print '*** delete', uids - return True - for uid in uids: - obj = util.getObjectForUid(uid) - parent = getParent(obj) - del parent[getName(obj)] + if uids: + method = self.actions.get(action) + if method: + method(self, uids) return True + + def delete(self, uids): + self.request.form['message'] = _( + u'The objects selected have been deleted.') + for uid in uids: + obj = util.getObjectForUid(uid) + if not canWriteObject(obj): + continue + parent = getParent(obj) + del parent[getName(obj)] + + def change_state(self, uids): + stdefs = dict([(k.split('.', 1)[1], v) + for k, v in self.request.form.items() + if k.startswith('trans.') and self.request.form[k] != '-']) + if not stdefs: + return + for uid in uids: + obj = util.getObjectForUid(uid) + if not canWriteObject(obj): + continue + for stdef, trans in stdefs.items(): + stf = component.getAdapter(obj, IStateful, name=stdef) + if trans in [t.name for t in stf.getAvailableTransitions()]: + stf.doTransition(trans) + self.request.form['message'] = _( + u'The state of the objects selected has been changed.') + + actions = dict(delete=delete, change_state=change_state) diff --git a/expert/configure.zcml b/expert/configure.zcml index aee13f7..3eff3c3 100644 --- a/expert/configure.zcml +++ b/expert/configure.zcml @@ -13,18 +13,6 @@ set_schema="loops.expert.concept.IQueryConcept" /> - - - -