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" />
|
<div metal:use-macro="views/node_macros/object_actions" />
|
||||||
</tal:actions>
|
</tal:actions>
|
||||||
<h1 tal:attributes="ondblclick item/openEditWindow">
|
<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>
|
tal:content="item/title">Title</a>
|
||||||
</h1>
|
</h1>
|
||||||
<p tal:define="description description|item/renderedDescription"
|
<p tal:define="description description|item/renderedDescription"
|
||||||
|
|
|
@ -298,8 +298,9 @@ div.menu-1, div.menu-2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
.listing .object-actions {
|
.listing .object-actions {
|
||||||
|
float: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
text-align: left;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-action {
|
.icon-action {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<tal:show i18n:domain="zope">
|
<tal:show i18n:domain="loops">
|
||||||
<html metal:use-macro="context/@@skin_macros/page">
|
<html metal:use-macro="context/@@skin_macros/page">
|
||||||
<head></head>
|
<head></head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -105,9 +105,10 @@ class NodeView(BaseView):
|
||||||
cm.register('top_actions', 'top_actions', name='multi_actions',
|
cm.register('top_actions', 'top_actions', name='multi_actions',
|
||||||
subMacros=[i18n_macros.macros['language_switch']])
|
subMacros=[i18n_macros.macros['language_switch']])
|
||||||
if self.globalOptions('expert.quicksearch'):
|
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',
|
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',
|
cm.register('portlet_left', 'navigation', title='Navigation',
|
||||||
subMacro=node_macros.macros['menu'])
|
subMacro=node_macros.macros['menu'])
|
||||||
if canWrite(self.context, 'title') or (
|
if canWrite(self.context, 'title') or (
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
<tal:actions condition="view/showObjectActions">
|
<tal:actions condition="view/showObjectActions">
|
||||||
<div metal:use-macro="views/node_macros/object_actions" />
|
<div metal:use-macro="views/node_macros/object_actions" />
|
||||||
</tal: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"
|
<p tal:define="description description|item/description"
|
||||||
tal:condition="description">
|
tal:condition="description">
|
||||||
<i tal:content="description">Description</i></p>
|
<i tal:content="description">Description</i></p>
|
||||||
|
|
|
@ -13,11 +13,18 @@
|
||||||
</div>
|
</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"
|
<div metal:define-macro="search_results" id="search.results"
|
||||||
tal:define="item nocall:view">
|
tal:define="item nocall:view">
|
||||||
<fieldset class="box">
|
<fieldset class="box">
|
||||||
<metal:results define-macro="results">
|
|
||||||
<h2 i18n:translate="">Search results</h2>
|
<h2 i18n:translate="">Search results</h2>
|
||||||
|
<metal:results define-macro="results">
|
||||||
<table class="listing" summary="Search results"
|
<table class="listing" summary="Search results"
|
||||||
i18n:attributes="summary">
|
i18n:attributes="summary">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -36,11 +43,11 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tal:items tal:repeat="row item/results">
|
<tal:items tal:repeat="row item/results">
|
||||||
<tal:item define="class python: repeat['row'].odd() and 'even' or 'odd';
|
<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">
|
<tr tal:attributes="class class">
|
||||||
<td>
|
<td>
|
||||||
<a tal:attributes="href
|
<a tal:attributes="href string:$targetUrl?version=this;
|
||||||
string:${view/url}/.target${row/uniqueId}?version=this;
|
|
||||||
title description">
|
title description">
|
||||||
<img tal:define="icon row/icon"
|
<img tal:define="icon row/icon"
|
||||||
tal:condition="icon"
|
tal:condition="icon"
|
||||||
|
@ -55,7 +62,8 @@
|
||||||
<a href="#"
|
<a href="#"
|
||||||
tal:content="versionId"
|
tal:content="versionId"
|
||||||
tal:omit-tag="python: versionId and versionId=='1.1'"
|
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>
|
</td>
|
||||||
</tal:version>
|
</tal:version>
|
||||||
<td class="nowrap number">
|
<td class="nowrap number">
|
||||||
|
|
|
@ -34,15 +34,19 @@ from loops import util
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
|
||||||
|
|
||||||
search_macros = ViewPageTemplateFile('search.pt')
|
searchMacrosTemplate = ViewPageTemplateFile('search.pt')
|
||||||
|
|
||||||
|
|
||||||
class SearchResults(NodeView):
|
class SearchResults(NodeView):
|
||||||
""" Provides results listing """
|
""" Provides results listing """
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def search_macros(self):
|
||||||
|
return searchMacrosTemplate.macros
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def macro(self):
|
def macro(self):
|
||||||
return search_macros.macros['search_results']
|
return self.search_macros['quicksearch_view']
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def item(self):
|
def item(self):
|
||||||
|
@ -52,7 +56,7 @@ class SearchResults(NodeView):
|
||||||
def results(self):
|
def results(self):
|
||||||
form = self.request.form
|
form = self.request.form
|
||||||
text = form.get('search.text')
|
text = form.get('search.text')
|
||||||
type = self.globalOptions('expert.quicksearch')[0]
|
type = self.globalOptions('expert.quicksearch')
|
||||||
result = FullQuery(self).query(text=text, type=type,
|
result = FullQuery(self).query(text=text, type=type,
|
||||||
useTitle=True, useFull=True,)
|
useTitle=True, useFull=True,)
|
||||||
return self.viewIterator(result)
|
return self.viewIterator(result)
|
||||||
|
|
|
@ -124,11 +124,14 @@ class FullQuery(BaseQuery):
|
||||||
return ScoredSet(result, scores)
|
return ScoredSet(result, scores)
|
||||||
if text or type != 'loops:*': # TODO: this may be highly inefficient!
|
if text or type != 'loops:*': # TODO: this may be highly inefficient!
|
||||||
cat = self.catalog
|
cat = self.catalog
|
||||||
if type.endswith('*'):
|
if isinstance(type, basestring):
|
||||||
start = type[:-1]
|
type = [type]
|
||||||
|
for tp in type:
|
||||||
|
if tp.endswith('*'):
|
||||||
|
start = tp[:-1]
|
||||||
end = start + '\x7f'
|
end = start + '\x7f'
|
||||||
else:
|
else:
|
||||||
start = end = type
|
start = end = tp
|
||||||
criteria = {'loops_type': (start, end),}
|
criteria = {'loops_type': (start, end),}
|
||||||
if useFull and text:
|
if useFull and text:
|
||||||
criteria['loops_text'] = text
|
criteria['loops_text'] = text
|
||||||
|
|
|
@ -201,8 +201,10 @@ class BaseWorkItemsView(object):
|
||||||
def baseCriteria(self):
|
def baseCriteria(self):
|
||||||
result = {}
|
result = {}
|
||||||
form = self.request.form
|
form = self.request.form
|
||||||
tsFrom = parseDate(form.get('wi_from') or self.options.wi_from)
|
tsFrom = parseDate(form.get('wi_from') or
|
||||||
tsTo = parseDate(form.get('wi_to') or self.options.wi_to)
|
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:
|
if tsTo:
|
||||||
tsTo += 3600 * 24 - 1 # include full end date
|
tsTo += 3600 * 24 - 1 # include full end date
|
||||||
if tsFrom or tsTo:
|
if tsFrom or tsTo:
|
||||||
|
|
|
@ -44,6 +44,10 @@ relation_macros = ViewPageTemplateFile('relation_macros.pt')
|
||||||
|
|
||||||
class BaseRelationFieldInstance(object):
|
class BaseRelationFieldInstance(object):
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
def selection_view(self):
|
||||||
|
return getattr(self.context, 'selection_view', 'listConceptsForComboBox.js')
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
def typesParams(self):
|
def typesParams(self):
|
||||||
result = []
|
result = []
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
tal:define="fieldInstance field/getFieldInstance;
|
tal:define="fieldInstance field/getFieldInstance;
|
||||||
types fieldInstance/typesParams">
|
types fieldInstance/typesParams">
|
||||||
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
<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" >
|
jsId string:${name}_search_store" >
|
||||||
</div>
|
</div>
|
||||||
<div tal:attributes="id string:${name}_values">
|
<div tal:attributes="id string:${name}_values">
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
tal:define="fieldInstance field/getFieldInstance;
|
tal:define="fieldInstance field/getFieldInstance;
|
||||||
types fieldInstance/typesParams">
|
types fieldInstance/typesParams">
|
||||||
<div dojoType="dojox.data.QueryReadStore" jsId="conceptSearch"
|
<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" >
|
jsId string:${name}_search_store" >
|
||||||
</div>
|
</div>
|
||||||
<div tal:define="obj data/?name"
|
<div tal:define="obj data/?name"
|
||||||
|
|
|
@ -35,7 +35,7 @@ from cybertools.relation.interfaces import IRelationRegistry
|
||||||
from cybertools.typology.interfaces import ITypeManager
|
from cybertools.typology.interfaces import ITypeManager
|
||||||
from loops.browser.common import BaseView
|
from loops.browser.common import BaseView
|
||||||
from loops.browser.node import NodeView
|
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.expert.concept import ConceptQuery, FullQuery
|
||||||
from loops import util
|
from loops import util
|
||||||
from loops.util import _
|
from loops.util import _
|
||||||
|
@ -108,18 +108,19 @@ class Search(BaseView):
|
||||||
if not isinstance(types, (list, tuple)):
|
if not isinstance(types, (list, tuple)):
|
||||||
types = [types]
|
types = [types]
|
||||||
for type in types:
|
for type in types:
|
||||||
result = ConceptQuery(self).query(title=title or None, type=type,
|
result = self.executeQuery(title=title or None, type=type,
|
||||||
exclude=('system',))
|
exclude=('system',))
|
||||||
for o in result:
|
for o in result:
|
||||||
if o.getLoopsRoot() == self.loopsRoot:
|
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('*'):
|
if title and title.endswith('*'):
|
||||||
title = title[:-1]
|
title = title[:-1]
|
||||||
sort = ((title and name.startswith(title) and '0' or '1')
|
sort = ((title and name.startswith(title) and '0' or '1')
|
||||||
+ name.lower())
|
+ name.lower())
|
||||||
if o.conceptType is None:
|
if o.conceptType is None:
|
||||||
raise ValueError('Concept Type missing for %r.' % name)
|
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,
|
'name': name,
|
||||||
'id': util.getUidForObject(o),
|
'id': util.getUidForObject(o),
|
||||||
'sort': sort})
|
'sort': sort})
|
||||||
|
@ -127,13 +128,24 @@ class Search(BaseView):
|
||||||
if not title:
|
if not title:
|
||||||
data.insert(0, {'label': '', 'name': '', 'id': ''})
|
data.insert(0, {'label': '', 'name': '', 'id': ''})
|
||||||
json = []
|
json = []
|
||||||
for item in data:
|
for item in data[:20]:
|
||||||
json.append("{label: '%s', name: '%s', id: '%s'}" %
|
json.append("{label: '%s', name: '%s', id: '%s'}" %
|
||||||
(item['label'], item['name'], item['id']))
|
(item['label'], item['name'], item['id']))
|
||||||
json = "{identifier: 'id', items: [%s]}" % ', '.join(json)
|
json = "{identifier: 'id', items: [%s]}" % ', '.join(json)
|
||||||
#print '***', json
|
#print '***', json
|
||||||
return 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):
|
def submitReplacing(self, targetId, formId, view):
|
||||||
self.registerDojo()
|
self.registerDojo()
|
||||||
return 'submitReplacing("%s", "%s", "%s"); return false;' % (
|
return 'submitReplacing("%s", "%s", "%s"); return false;' % (
|
||||||
|
|
Loading…
Add table
Reference in a new issue