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 5ac7dee..50cfee4 100644 --- a/expert/browser/search.pt +++ b/expert/browser/search.pt @@ -33,11 +33,15 @@ tal:content="item/title"> Search +
-
-
-
+ +
+
@@ -56,23 +60,24 @@
+ i18n:attributes="value" /> - -
-
- - - +
+
+ + + +
+
+

Search results

@@ -80,6 +85,12 @@ i18n:attributes="summary"> + + Title Type + targetUrl python:view.getUrlForTarget(row); + selected_uids request/selection|python:[]"> + + @@ -134,6 +153,7 @@ +
@@ -374,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 20af753..f368042 100644 --- a/expert/browser/search.py +++ b/expert/browser/search.py @@ -28,6 +28,7 @@ from zope.app.pagetemplate import ViewPageTemplateFile from zope.cachedescriptors.property import Lazy from zope.traversing.api import getName, getParent +from cybertools.browser.form import FormController from cybertools.stateful.interfaces import IStateful, IStatesDefinition from loops.browser.common import BaseView from loops.browser.node import NodeView @@ -35,6 +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, checkPermission from loops import util from loops.util import _ @@ -45,6 +47,8 @@ search_template = ViewPageTemplateFile('search.pt') class QuickSearchResults(NodeView): """ Provides results listing """ + showActions = False + @Lazy def search_macros(self): return self.controller.getTemplateMacros('search', search_template) @@ -72,6 +76,7 @@ class QuickSearchResults(NodeView): class Search(BaseView): + form_action = 'execute_search_action' maxRowNum = 0 @Lazy @@ -82,6 +87,11 @@ class Search(BaseView): def macro(self): return self.search_macros['search'] + @Lazy + def showActions(self): + return checkPermission('loops.ManageSite', self.context) + #return canWriteObject(self.context) + @property def rowNum(self): """ Return the rowNum to be used for identifying the current search @@ -261,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): @@ -315,3 +324,46 @@ class SearchResults(NodeView): result = sorted(result, key=lambda x: x.title.lower()) return self.viewIterator(result) + +class ActionExecutor(FormController): + + def update(self): + 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', []) + 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 dd24ee9..3eff3c3 100644 --- a/expert/configure.zcml +++ b/expert/configure.zcml @@ -13,12 +13,6 @@ set_schema="loops.expert.concept.IQueryConcept" /> - -