quicksearch improvements; make search process in relation widget more flexible
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@3250 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
parent
9248fa988f
commit
ec7dd9391d
12 changed files with 88 additions and 49 deletions
|
@ -24,7 +24,9 @@
|
|||
<div metal:use-macro="views/node_macros/object_actions" />
|
||||
</tal:actions>
|
||||
<h1 tal:attributes="ondblclick item/openEditWindow">
|
||||
<a name="top"
|
||||
<a name="top" />
|
||||
<a tal:omit-tag="python: level > 1"
|
||||
tal:attributes="href request/URL"
|
||||
tal:content="item/title">Title</a>
|
||||
</h1>
|
||||
<p tal:define="description description|item/renderedDescription"
|
||||
|
|
|
@ -298,8 +298,9 @@ div.menu-1, div.menu-2 {
|
|||
}
|
||||
|
||||
.listing .object-actions {
|
||||
float: none;
|
||||
padding: 0;
|
||||
text-align: left;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.icon-action {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<tal:show i18n:domain="zope">
|
||||
<tal:show i18n:domain="loops">
|
||||
<html metal:use-macro="context/@@skin_macros/page">
|
||||
<head></head>
|
||||
<body>
|
||||
|
|
|
@ -105,9 +105,10 @@ class NodeView(BaseView):
|
|||
cm.register('top_actions', 'top_actions', name='multi_actions',
|
||||
subMacros=[i18n_macros.macros['language_switch']])
|
||||
if self.globalOptions('expert.quicksearch'):
|
||||
from loops.expert.browser.search import search_macros
|
||||
from loops.expert.browser.search import searchMacrosTemplate
|
||||
cm.register('top_actions', 'top_quicksearch', name='multi_actions',
|
||||
subMacros=[search_macros.macros['quicksearch']], priority=20)
|
||||
subMacros=[searchMacrosTemplate.macros['quicksearch']],
|
||||
priority=20)
|
||||
cm.register('portlet_left', 'navigation', title='Navigation',
|
||||
subMacro=node_macros.macros['menu'])
|
||||
if canWrite(self.context, 'title') or (
|
||||
|
|
|
@ -6,7 +6,9 @@
|
|||
<tal:actions condition="view/showObjectActions">
|
||||
<div metal:use-macro="views/node_macros/object_actions" />
|
||||
</tal:actions>
|
||||
<h1 tal:content="item/title">Title</h1>
|
||||
<h1><a tal:omit-tag="python: level > 1"
|
||||
tal:attributes="href request/URL"
|
||||
tal:content="item/title">Title</a></h1>
|
||||
<p tal:define="description description|item/description"
|
||||
tal:condition="description">
|
||||
<i tal:content="description">Description</i></p>
|
||||
|
|
|
@ -13,11 +13,18 @@
|
|||
</div>
|
||||
|
||||
|
||||
<div metal:define-macro="quicksearch_view" id="search.results"
|
||||
tal:define="item nocall:view">
|
||||
<h1 i18n:translate="">Search results</h1><br />
|
||||
<metal:results use-macro="item/search_macros/results" />
|
||||
</div>
|
||||
|
||||
|
||||
<div metal:define-macro="search_results" id="search.results"
|
||||
tal:define="item nocall:view">
|
||||
<fieldset class="box">
|
||||
<h2 i18n:translate="">Search results</h2>
|
||||
<metal:results define-macro="results">
|
||||
<h2 i18n:translate="">Search results</h2>
|
||||
<table class="listing" summary="Search results"
|
||||
i18n:attributes="summary">
|
||||
<thead>
|
||||
|
@ -36,11 +43,11 @@
|
|||
<tbody>
|
||||
<tal:items tal:repeat="row item/results">
|
||||
<tal:item define="class python: repeat['row'].odd() and 'even' or 'odd';
|
||||
description row/description">
|
||||
description row/description;
|
||||
targetUrl python:view.getUrlForTarget(row)">
|
||||
<tr tal:attributes="class class">
|
||||
<td>
|
||||
<a tal:attributes="href
|
||||
string:${view/url}/.target${row/uniqueId}?version=this;
|
||||
<a tal:attributes="href string:$targetUrl?version=this;
|
||||
title description">
|
||||
<img tal:define="icon row/icon"
|
||||
tal:condition="icon"
|
||||
|
@ -55,7 +62,8 @@
|
|||
<a href="#"
|
||||
tal:content="versionId"
|
||||
tal:omit-tag="python: versionId and versionId=='1.1'"
|
||||
tal:attributes="href string:${view/url}/.target${row/uniqueId}?loops.viewName=listversions">1.1</a>
|
||||
tal:attributes="href
|
||||
string:$targetUrl?loops.viewName=listversions">1.1</a>
|
||||
</td>
|
||||
</tal:version>
|
||||
<td class="nowrap number">
|
||||
|
|
|
@ -34,15 +34,19 @@ from loops import util
|
|||
from loops.util import _
|
||||
|
||||
|
||||
search_macros = ViewPageTemplateFile('search.pt')
|
||||
searchMacrosTemplate = ViewPageTemplateFile('search.pt')
|
||||
|
||||
|
||||
class SearchResults(NodeView):
|
||||
""" Provides results listing """
|
||||
|
||||
@Lazy
|
||||
def search_macros(self):
|
||||
return searchMacrosTemplate.macros
|
||||
|
||||
@Lazy
|
||||
def macro(self):
|
||||
return search_macros.macros['search_results']
|
||||
return self.search_macros['quicksearch_view']
|
||||
|
||||
@Lazy
|
||||
def item(self):
|
||||
|
@ -52,7 +56,7 @@ class SearchResults(NodeView):
|
|||
def results(self):
|
||||
form = self.request.form
|
||||
text = form.get('search.text')
|
||||
type = self.globalOptions('expert.quicksearch')[0]
|
||||
type = self.globalOptions('expert.quicksearch')
|
||||
result = FullQuery(self).query(text=text, type=type,
|
||||
useTitle=True, useFull=True,)
|
||||
return self.viewIterator(result)
|
||||
|
|
|
@ -124,31 +124,34 @@ class FullQuery(BaseQuery):
|
|||
return ScoredSet(result, scores)
|
||||
if text or type != 'loops:*': # TODO: this may be highly inefficient!
|
||||
cat = self.catalog
|
||||
if type.endswith('*'):
|
||||
start = type[:-1]
|
||||
end = start + '\x7f'
|
||||
else:
|
||||
start = end = type
|
||||
criteria = {'loops_type': (start, end),}
|
||||
if useFull and text:
|
||||
criteria['loops_text'] = text
|
||||
r1 = cat.apply(criteria) #r1 = set(cat.searchResults(**criteria))
|
||||
else:
|
||||
r1 = IFBucket() #r1 = set()
|
||||
if useTitle and text:
|
||||
if 'loops_text' in criteria:
|
||||
del criteria['loops_text']
|
||||
criteria['loops_title'] = text
|
||||
r2 = cat.apply(criteria) #r2 = set(cat.searchResults(**criteria))
|
||||
else:
|
||||
r2 = IFBucket() #r2 = set()
|
||||
if not r1 and not r2:
|
||||
r1 = cat.apply(criteria) # search only for type
|
||||
x, uids = weightedUnion(r1, r2) #result = r1.union(r2)
|
||||
for r, score in uids.items():
|
||||
obj = intids.getObject(r)
|
||||
result.add(obj)
|
||||
scores[obj] = score
|
||||
if isinstance(type, basestring):
|
||||
type = [type]
|
||||
for tp in type:
|
||||
if tp.endswith('*'):
|
||||
start = tp[:-1]
|
||||
end = start + '\x7f'
|
||||
else:
|
||||
start = end = tp
|
||||
criteria = {'loops_type': (start, end),}
|
||||
if useFull and text:
|
||||
criteria['loops_text'] = text
|
||||
r1 = cat.apply(criteria) #r1 = set(cat.searchResults(**criteria))
|
||||
else:
|
||||
r1 = IFBucket() #r1 = set()
|
||||
if useTitle and text:
|
||||
if 'loops_text' in criteria:
|
||||
del criteria['loops_text']
|
||||
criteria['loops_title'] = text
|
||||
r2 = cat.apply(criteria) #r2 = set(cat.searchResults(**criteria))
|
||||
else:
|
||||
r2 = IFBucket() #r2 = set()
|
||||
if not r1 and not r2:
|
||||
r1 = cat.apply(criteria) # search only for type
|
||||
x, uids = weightedUnion(r1, r2) #result = r1.union(r2)
|
||||
for r, score in uids.items():
|
||||
obj = intids.getObject(r)
|
||||
result.add(obj)
|
||||
scores[obj] = score
|
||||
if rc is not None:
|
||||
if result:
|
||||
result = result.intersection(rc)
|
||||
|
|
|
@ -201,8 +201,10 @@ class BaseWorkItemsView(object):
|
|||
def baseCriteria(self):
|
||||
result = {}
|
||||
form = self.request.form
|
||||
tsFrom = parseDate(form.get('wi_from') or self.options.wi_from)
|
||||
tsTo = parseDate(form.get('wi_to') or self.options.wi_to)
|
||||
tsFrom = parseDate(form.get('wi_from') or
|
||||
self.options.wi_from or self.typeOptions.wi_from)
|
||||
tsTo = parseDate(form.get('wi_to') or
|
||||
self.options.wi_to or self.typeOptions.wi_to)
|
||||
if tsTo:
|
||||
tsTo += 3600 * 24 - 1 # include full end date
|
||||
if tsFrom or tsTo:
|
||||
|
|
|
@ -44,6 +44,10 @@ relation_macros = ViewPageTemplateFile('relation_macros.pt')
|
|||
|
||||
class BaseRelationFieldInstance(object):
|
||||
|
||||
@Lazy
|
||||
def selection_view(self):
|
||||
return getattr(self.context, 'selection_view', 'listConceptsForComboBox.js')
|
||||
|
||||
@Lazy
|
||||
def typesParams(self):
|
||||
result = []
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
tal:define="fieldInstance field/getFieldInstance;
|
||||
types fieldInstance/typesParams">
|
||||
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
||||
tal:attributes="url string:listConceptsForComboBox.js$types;
|
||||
tal:attributes="url string:${fieldInstance/selection_view}$types;
|
||||
jsId string:${name}_search_store" >
|
||||
</div>
|
||||
<div tal:attributes="id string:${name}_values">
|
||||
|
@ -38,7 +38,7 @@
|
|||
tal:define="fieldInstance field/getFieldInstance;
|
||||
types fieldInstance/typesParams">
|
||||
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
||||
tal:attributes="url string:listConceptsForComboBox.js$types;
|
||||
tal:attributes="url string:${fieldInstance/selection_view}$types;
|
||||
jsId string:${name}_search_store" >
|
||||
</div>
|
||||
<div tal:define="obj data/?name"
|
||||
|
|
|
@ -35,7 +35,7 @@ from cybertools.relation.interfaces import IRelationRegistry
|
|||
from cybertools.typology.interfaces import ITypeManager
|
||||
from loops.browser.common import BaseView
|
||||
from loops.browser.node import NodeView
|
||||
from loops.common import adapted
|
||||
from loops.common import adapted, AdapterBase
|
||||
from loops.expert.concept import ConceptQuery, FullQuery
|
||||
from loops import util
|
||||
from loops.util import _
|
||||
|
@ -108,18 +108,19 @@ class Search(BaseView):
|
|||
if not isinstance(types, (list, tuple)):
|
||||
types = [types]
|
||||
for type in types:
|
||||
result = ConceptQuery(self).query(title=title or None, type=type,
|
||||
exclude=('system',))
|
||||
result = self.executeQuery(title=title or None, type=type,
|
||||
exclude=('system',))
|
||||
for o in result:
|
||||
if o.getLoopsRoot() == self.loopsRoot:
|
||||
name = adapted(o, self.languageInfo).title
|
||||
adObj = adapted(o, self.languageInfo)
|
||||
name = self.getRowName(adObj)
|
||||
if title and title.endswith('*'):
|
||||
title = title[:-1]
|
||||
sort = ((title and name.startswith(title) and '0' or '1')
|
||||
+ name.lower())
|
||||
if o.conceptType is None:
|
||||
raise ValueError('Concept Type missing for %r.' % name)
|
||||
data.append({'label': '%s (%s)' % (name, o.conceptType.title),
|
||||
data.append({'label': self.getRowLabel(adObj, name),
|
||||
'name': name,
|
||||
'id': util.getUidForObject(o),
|
||||
'sort': sort})
|
||||
|
@ -127,13 +128,24 @@ class Search(BaseView):
|
|||
if not title:
|
||||
data.insert(0, {'label': '', 'name': '', 'id': ''})
|
||||
json = []
|
||||
for item in data:
|
||||
for item in data[:20]:
|
||||
json.append("{label: '%s', name: '%s', id: '%s'}" %
|
||||
(item['label'], item['name'], item['id']))
|
||||
json = "{identifier: 'id', items: [%s]}" % ', '.join(json)
|
||||
#print '***', json
|
||||
return json
|
||||
|
||||
def executeQuery(self, **kw):
|
||||
return ConceptQuery(self).query(**kw)
|
||||
|
||||
def getRowName(self, obj):
|
||||
return obj.title
|
||||
|
||||
def getRowLabel(self, obj, name):
|
||||
if isinstance(obj, AdapterBase):
|
||||
obj = obj.context
|
||||
return '%s (%s)' % (name, obj.conceptType.title)
|
||||
|
||||
def submitReplacing(self, targetId, formId, view):
|
||||
self.registerDojo()
|
||||
return 'submitReplacing("%s", "%s", "%s"); return false;' % (
|
||||
|
|
Loading…
Add table
Reference in a new issue