mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Improvements, fixes and tweaks to Share Search component and services:
- Much improved layout and CSS (as per visuals) - I18N of various messages in Search component and removal of hardcoded message strings from repo search service output - Code cleanup of repo search service and removal of obsolete data values - Fixes to a number of encoding issues passing search terms on URL to search page and service URLs - Blogs, forums, wiki and Calendar entries now shown with appropriate (placeholder!) icons and "Type" field - "Type" details field added to all results - Support for AND, OR and NOT between multiple search terms (note that OR is default as before) - Searches such as "alfresco and enterprise" or "alfresco not eating" are supported - Support for * and ? within terms - Searches such as "alf*" and "*look" and "a?fes?o" are supported - Much improved error handling and reslience for broken query strings or failed parsing json.status.ftl fixed to output valid JSON - was not parsing git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10773 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -98,7 +98,7 @@ function getDocumentItem(siteId, containerId, restOfPath, node)
|
|||||||
{
|
{
|
||||||
// PENDING: how to handle comments? the document should
|
// PENDING: how to handle comments? the document should
|
||||||
// be returned instead
|
// be returned instead
|
||||||
|
|
||||||
// check whether we already processed this document
|
// check whether we already processed this document
|
||||||
if (checkProcessed(siteId + containerId, "" + node.nodeRef.toString()))
|
if (checkProcessed(siteId + containerId, "" + node.nodeRef.toString()))
|
||||||
{
|
{
|
||||||
@@ -107,42 +107,33 @@ function getDocumentItem(siteId, containerId, restOfPath, node)
|
|||||||
addToProcessed(siteId + containerId, "" + node.nodeRef.toString());
|
addToProcessed(siteId + containerId, "" + node.nodeRef.toString());
|
||||||
|
|
||||||
// check whether this is a folder or a file
|
// check whether this is a folder or a file
|
||||||
|
var item = null;
|
||||||
if (node.isContainer)
|
if (node.isContainer)
|
||||||
{
|
{
|
||||||
var item = {};
|
item = {};
|
||||||
item.site = getSiteData(siteId);
|
item.site = getSiteData(siteId);
|
||||||
item.container = containerId;
|
item.container = containerId;
|
||||||
item.nodeRef = node.nodeRef.toString();
|
item.nodeRef = node.nodeRef.toString();
|
||||||
item.type = "folder";
|
item.type = "folder";
|
||||||
item.icon32 = node.icon32;
|
|
||||||
item.qnamePath = node.qnamePath;
|
|
||||||
item.tags = (node.tags != null) ? node.tags : [];
|
item.tags = (node.tags != null) ? node.tags : [];
|
||||||
item.name = node.name;
|
item.name = node.name;
|
||||||
item.displayName = "Folder: " + node.name; // PENDING: node.name.replace(message("coci_service.working_copy_label"), ''); // ${item.name?replace(workingCopyLabel, "")?html}",
|
item.displayName = node.name; // PENDING: node.name.replace(message("coci_service.working_copy_label"), ''); // ${item.name?replace(workingCopyLabel, "")?html}",
|
||||||
item.browseUrl = containerId + "#path=" + encodeURIComponent(getSpaceNamePath(siteId, containerId, node));
|
item.browseUrl = containerId + "#path=" + encodeURIComponent(getSpaceNamePath(siteId, containerId, node));
|
||||||
return item;
|
|
||||||
// PENDING - return a folder result
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
else if (node.isDocument)
|
else if (node.isDocument)
|
||||||
{
|
{
|
||||||
var item = {};
|
item = {};
|
||||||
item.site = getSiteData(siteId);
|
item.site = getSiteData(siteId);
|
||||||
item.container = containerId;
|
item.container = containerId;
|
||||||
item.nodeRef = node.nodeRef.toString();
|
item.nodeRef = node.nodeRef.toString();
|
||||||
item.type = "file";
|
item.type = "file";
|
||||||
item.icon32 = node.icon32;
|
|
||||||
item.qnamePath = node.qnamePath;
|
|
||||||
item.tags = (node.tags != null) ? node.tags : [];
|
item.tags = (node.tags != null) ? node.tags : [];
|
||||||
item.name = node.name;
|
item.name = node.name;
|
||||||
item.displayName = "Document: " + node.name; // PENDING: node.name.replace(message("coci_service.working_copy_label"), ''); // ${item.name?replace(workingCopyLabel, "")?html}",
|
item.displayName = node.name; // PENDING: node.name.replace(message("coci_service.working_copy_label"), ''); // ${item.name?replace(workingCopyLabel, "")?html}",
|
||||||
item.browseUrl = "document-details?nodeRef=" + node.nodeRef.toString();
|
item.browseUrl = "document-details?nodeRef=" + node.nodeRef.toString();
|
||||||
return item;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getBlogPostItem(siteId, containerId, restOfPath, node)
|
function getBlogPostItem(siteId, containerId, restOfPath, node)
|
||||||
@@ -181,12 +172,10 @@ function getBlogPostItem(siteId, containerId, restOfPath, node)
|
|||||||
item.container = containerId;
|
item.container = containerId;
|
||||||
item.nodeRef = child.nodeRef.toString();
|
item.nodeRef = child.nodeRef.toString();
|
||||||
item.type = "blogpost";
|
item.type = "blogpost";
|
||||||
item.icon32 = child.icon32;
|
|
||||||
item.qnamePath = child.qnamePath;
|
|
||||||
item.tags = (child.tags != null) ? child.tags : [];
|
item.tags = (child.tags != null) ? child.tags : [];
|
||||||
item.name = child.name;
|
item.name = child.name;
|
||||||
item.displayName = "Blog post: " + child.properties["cm:title"];
|
item.displayName = child.properties["cm:title"];
|
||||||
item.browseUrl = "blog-postview?container=" + containerId + "&postId=" + child.name;
|
item.browseUrl = "blog-postview?container=" + containerId + "&postId=" + child.name;
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -211,23 +200,20 @@ function getForumPostItem(siteId, containerId, restOfPath, node)
|
|||||||
}
|
}
|
||||||
addToProcessed(siteId + containerId, "" + topicNode.nodeRef.toString());
|
addToProcessed(siteId + containerId, "" + topicNode.nodeRef.toString());
|
||||||
|
|
||||||
|
|
||||||
// find the first post, which contains the post title
|
// find the first post, which contains the post title
|
||||||
// PENDING: error prone
|
// PENDING: error prone
|
||||||
var postNode = topicNode.childAssocs["cm:contains"][0];
|
var postNode = topicNode.childAssocs["cm:contains"][0];
|
||||||
|
|
||||||
// child is our blog post
|
// child is our forum post
|
||||||
var item = {};
|
var item = {};
|
||||||
item.site = getSiteData(siteId);
|
item.site = getSiteData(siteId);
|
||||||
item.container = containerId;
|
item.container = containerId;
|
||||||
item.nodeRef = topicNode.nodeRef.toString();
|
item.nodeRef = topicNode.nodeRef.toString();
|
||||||
item.type = "topicpost";
|
item.type = "topicpost";
|
||||||
item.icon32 = topicNode.icon32;
|
|
||||||
item.qnamePath = topicNode.qnamePath;
|
|
||||||
item.tags = (topicNode.tags != null) ? topicNode.tags : [];
|
item.tags = (topicNode.tags != null) ? topicNode.tags : [];
|
||||||
item.name = topicNode.name;
|
item.name = topicNode.name;
|
||||||
item.displayName = "Forum topic: " + postNode.properties["cm:title"];
|
item.displayName = postNode.properties["cm:title"];
|
||||||
item.browseUrl = "discussions-topicview?container=" + containerId + "&topicId=" + topicNode.name;
|
item.browseUrl = "discussions-topicview?container=" + containerId + "&topicId=" + topicNode.name;
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@@ -252,11 +238,9 @@ function getCalendarItem(siteId, containerId, restOfPath, node)
|
|||||||
item.container = containerId;
|
item.container = containerId;
|
||||||
item.nodeRef = node.nodeRef.toString();
|
item.nodeRef = node.nodeRef.toString();
|
||||||
item.type = "calendarevent";
|
item.type = "calendarevent";
|
||||||
item.icon32 = node.icon32;
|
|
||||||
item.qnamePath = node.qnamePath;
|
|
||||||
item.tags = (node.tags != null) ? node.tags : [];
|
item.tags = (node.tags != null) ? node.tags : [];
|
||||||
item.name = node.name;
|
item.name = node.name;
|
||||||
item.displayName = "Calendar event: " + node.properties["ia:whatEvent"];
|
item.displayName = node.properties["ia:whatEvent"];
|
||||||
item.browseUrl = containerId; // this is "calendar"
|
item.browseUrl = containerId; // this is "calendar"
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
@@ -265,7 +249,7 @@ function getCalendarItem(siteId, containerId, restOfPath, node)
|
|||||||
function getWikiItem(siteId, containerId, restOfPath, node)
|
function getWikiItem(siteId, containerId, restOfPath, node)
|
||||||
{
|
{
|
||||||
// only process documents
|
// only process documents
|
||||||
if (! node.isDocument)
|
if (!node.isDocument)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -282,11 +266,9 @@ function getWikiItem(siteId, containerId, restOfPath, node)
|
|||||||
item.container = containerId;
|
item.container = containerId;
|
||||||
item.nodeRef = node.nodeRef.toString();
|
item.nodeRef = node.nodeRef.toString();
|
||||||
item.type = "wikipage";
|
item.type = "wikipage";
|
||||||
item.icon32 = node.icon32;
|
|
||||||
item.qnamePath = node.qnamePath;
|
|
||||||
item.tags = (node.tags != null) ? node.tags : [];
|
item.tags = (node.tags != null) ? node.tags : [];
|
||||||
item.name = node.name;
|
item.name = node.name;
|
||||||
item.displayName = "Wiki page: " + node.properties["cm:name"]; // cm:title at some point?
|
item.displayName = node.properties["cm:name"]; // cm:title at some point?
|
||||||
item.browseUrl = "wiki-page?title=" + node.properties["cm:name"];
|
item.browseUrl = "wiki-page?title=" + node.properties["cm:name"];
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
@@ -336,12 +318,14 @@ function splitQNamePath(node)
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmp = path.substring(SITES_SPACE_QNAME_PATH.length);
|
var tmp = path.substring(SITES_SPACE_QNAME_PATH.length);
|
||||||
var pos = tmp.indexOf('/');
|
var pos = tmp.indexOf('/');
|
||||||
if (pos < 1)
|
if (pos < 1)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var siteId = tmp.substring(0, pos);
|
var siteId = tmp.substring(0, pos);
|
||||||
siteId = siteId.substring(siteId.indexOf(":") + 1);
|
siteId = siteId.substring(siteId.indexOf(":") + 1);
|
||||||
tmp = tmp.substring(pos + 1);
|
tmp = tmp.substring(pos + 1);
|
||||||
@@ -350,6 +334,7 @@ function splitQNamePath(node)
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
var containerId = tmp.substring(0, pos);
|
var containerId = tmp.substring(0, pos);
|
||||||
containerId = containerId.substring(containerId.indexOf(":") + 1);
|
containerId = containerId.substring(containerId.indexOf(":") + 1);
|
||||||
var restOfPath = tmp.substring(pos + 1);
|
var restOfPath = tmp.substring(pos + 1);
|
||||||
@@ -364,7 +349,7 @@ function splitQNamePath(node)
|
|||||||
*/
|
*/
|
||||||
function processResults(nodes, maxResults)
|
function processResults(nodes, maxResults)
|
||||||
{
|
{
|
||||||
var results = new Array();
|
var results = new Array(nodes.length);
|
||||||
|
|
||||||
var added = 0;
|
var added = 0;
|
||||||
for (var x=0; x < nodes.length && added < maxResults; x++)
|
for (var x=0; x < nodes.length && added < maxResults; x++)
|
||||||
@@ -372,16 +357,14 @@ function processResults(nodes, maxResults)
|
|||||||
// for each node we extract the site/container qname path and then
|
// for each node we extract the site/container qname path and then
|
||||||
// let the per-container helper function decide what to do
|
// let the per-container helper function decide what to do
|
||||||
var parts = splitQNamePath(nodes[x]);
|
var parts = splitQNamePath(nodes[x]);
|
||||||
if (parts == null)
|
if (parts != null)
|
||||||
{
|
{
|
||||||
continue;
|
var item = getItem(parts[0], parts[1], parts[2], nodes[x]);
|
||||||
}
|
if (item != null)
|
||||||
|
{
|
||||||
var item = getItem(parts[0], parts[1], parts[2], nodes[x]);
|
results.push(item);
|
||||||
if (item != null)
|
added++;
|
||||||
{
|
}
|
||||||
results.push(item);
|
|
||||||
added++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,7 +373,12 @@ function processResults(nodes, maxResults)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create collection of documents */
|
/**
|
||||||
|
* Return Search results with the given search terms
|
||||||
|
* Terms are split on whitespace characters.
|
||||||
|
*
|
||||||
|
* AND, OR and NOT are supported keyboard as their Lucene equivilent.
|
||||||
|
*/
|
||||||
function getSearchResults(term, maxResults, siteId, containerId)
|
function getSearchResults(term, maxResults, siteId, containerId)
|
||||||
{
|
{
|
||||||
var path = SITES_SPACE_QNAME_PATH; // "/app:company_home/st:sites/";
|
var path = SITES_SPACE_QNAME_PATH; // "/app:company_home/st:sites/";
|
||||||
@@ -410,32 +398,64 @@ function getSearchResults(term, maxResults, siteId, containerId)
|
|||||||
{
|
{
|
||||||
path += "*/";
|
path += "*/";
|
||||||
}
|
}
|
||||||
|
|
||||||
var luceneQuery = "+PATH:\"" + path + "/*\"";
|
var luceneQuery = ""
|
||||||
if (term != null && term.length > 0)
|
if (term != null && term.length != 0)
|
||||||
{
|
{
|
||||||
// TODO: do smarter term pre-processing. For now we simply take all words,
|
// TODO: Perform smarter term processing. For now we simply split on whitespace
|
||||||
// which ignores * and quotes
|
// which ignores quoted phrases that may be present.
|
||||||
var terms = term.split(/\W/);
|
var terms = term.split(/\s/);
|
||||||
|
|
||||||
for (var x=0; x < terms.length; x++)
|
for (var x=0; x < terms.length; x++)
|
||||||
{
|
{
|
||||||
var t = terms[x];
|
var t = terms[x];
|
||||||
if (t.length < 1)
|
// remove quotes - TODO: add support for quoted terms later
|
||||||
|
t = t.replace(/\"/g, "");
|
||||||
|
if (t.length != 0)
|
||||||
{
|
{
|
||||||
continue;
|
switch (t.toLowerCase())
|
||||||
|
{
|
||||||
|
case "and":
|
||||||
|
if (x < terms.length - 1 && terms[x + 1].length != 0)
|
||||||
|
{
|
||||||
|
luceneQuery += "AND ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "or":
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "not":
|
||||||
|
if (x < terms.length - 1 && terms[x + 1].length != 0)
|
||||||
|
{
|
||||||
|
luceneQuery += "NOT ";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
luceneQuery += "(TEXT:\"" + t + "\"" + // full text
|
||||||
|
" @cm\\:name:\"" + t + "\"" + // name property
|
||||||
|
" PATH:\"/cm:taggable/cm:" + search.ISO9075Encode(t) + "/member\"" + // tags
|
||||||
|
") ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
luceneQuery += " +(" +
|
|
||||||
" TEXT:\"" + t + "\"" + // full text
|
|
||||||
" @cm\\:name:\"*" + t + "*\"" + // name property
|
|
||||||
" PATH:\"/cm:taggable/cm:" + search.ISO9075Encode(t) + "/member\"" +
|
|
||||||
" )";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var nodes = search.luceneSearch(luceneQuery);
|
var nodes;
|
||||||
|
|
||||||
|
// if we processed the search terms, then suffix the PATH query
|
||||||
|
if (luceneQuery.length != 0)
|
||||||
|
{
|
||||||
|
luceneQuery = "+PATH:\"" + path + "/*\" +(" + luceneQuery + ")";
|
||||||
|
nodes = search.luceneSearch(luceneQuery);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// failed to process the search string - empty list returned
|
||||||
|
nodes = new Array();
|
||||||
|
}
|
||||||
|
|
||||||
return processResults(nodes, maxResults);
|
return processResults(nodes, maxResults);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,7 +468,6 @@ function main()
|
|||||||
var maxResults = (args["maxResults"] != undefined) ? parseInt(args["maxResults"]) : DEFAULT_MAX_RESULTS;
|
var maxResults = (args["maxResults"] != undefined) ? parseInt(args["maxResults"]) : DEFAULT_MAX_RESULTS;
|
||||||
|
|
||||||
model.data = getSearchResults(term, maxResults, siteId, containerId);
|
model.data = getSearchResults(term, maxResults, siteId, containerId);
|
||||||
var x=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main();
|
main();
|
@@ -6,15 +6,10 @@
|
|||||||
{
|
{
|
||||||
"index": ${item_index},
|
"index": ${item_index},
|
||||||
"nodeRef" : "${item.nodeRef}",
|
"nodeRef" : "${item.nodeRef}",
|
||||||
"qnamePath" : "${item.qnamePath}",
|
|
||||||
"type": "${item.type}",
|
"type": "${item.type}",
|
||||||
"icon32": "${item.icon32}",
|
|
||||||
"name" : "${item.name!''}",
|
"name" : "${item.name!''}",
|
||||||
"displayName": "${item.displayName!''}",
|
"displayName": "${item.displayName!''}",
|
||||||
"tags" : [<#list item.tags as tag>"${tag}"<#if tag_has_next>,</#if></#list>],
|
"tags" : [<#list item.tags as tag>"${tag}"<#if tag_has_next>,</#if></#list>],
|
||||||
<#if item.downloadUrl??>
|
|
||||||
"downloadUrl" : "${item.downloadUrl}",
|
|
||||||
</#if>
|
|
||||||
<#if item.browseUrl??>
|
<#if item.browseUrl??>
|
||||||
"browseUrl" : "${item.browseUrl}",
|
"browseUrl" : "${item.browseUrl}",
|
||||||
</#if>
|
</#if>
|
||||||
@@ -27,4 +22,4 @@
|
|||||||
</#list>
|
</#list>
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
</#escape>
|
</#escape>
|
Reference in New Issue
Block a user