mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
. Saved Searches UI improvements as suggested by Linton
. Fix to quoted term search to allow quoted string of a single word only e.g. "baboon" (not very useful, but should at least work…!) . Checkpoint of the Templating language enhancements ready for the addition of saved search support git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2124 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -281,13 +281,17 @@ show_results_categories=Show me results in the categories
|
|||||||
include_sub_categories=Include sub-categories
|
include_sub_categories=Include sub-categories
|
||||||
also_search_results=More search options
|
also_search_results=More search options
|
||||||
additional_options=Additional options
|
additional_options=Additional options
|
||||||
save_search=Save Search
|
save_new_search=Save New Search
|
||||||
saved_searches=Saved Searches
|
save_edit_search=Save Modified Search
|
||||||
|
saved_searches=Saved Search Options
|
||||||
title_save_search=Save Search Query
|
title_save_search=Save Search Query
|
||||||
save_search_description=Save a search query for use again later
|
save_search_description=Save a search query for use again later
|
||||||
search_props=Saved Search Properties
|
search_props=Saved Search Properties
|
||||||
select_saved_search=Select a Saved Search...
|
select_saved_search=Select a Saved Search...
|
||||||
saved_search_warning=This operation will attempt to overwrite the existing saved search ''{0}''
|
saved_search_warning=This operation will attempt to overwrite the existing saved search ''{0}''
|
||||||
|
user_searches=Your Searches
|
||||||
|
global_searches=Public Searches
|
||||||
|
save_search_global=Save as a public search available to all users.
|
||||||
|
|
||||||
# Forum messages
|
# Forum messages
|
||||||
forums=Forum Space
|
forums=Forum Space
|
||||||
|
@@ -19,13 +19,10 @@ package org.alfresco.web.app.servlet;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -34,22 +31,16 @@ import javax.transaction.UserTransaction;
|
|||||||
|
|
||||||
import org.alfresco.error.AlfrescoRuntimeException;
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.template.DateCompareMethod;
|
|
||||||
import org.alfresco.repo.template.HasAspectMethod;
|
|
||||||
import org.alfresco.repo.template.I18NMessageMethod;
|
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.StoreRef;
|
import org.alfresco.service.cmr.repository.StoreRef;
|
||||||
import org.alfresco.service.cmr.repository.TemplateException;
|
import org.alfresco.service.cmr.repository.TemplateException;
|
||||||
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
|
||||||
import org.alfresco.service.cmr.repository.TemplateNode;
|
import org.alfresco.service.cmr.repository.TemplateNode;
|
||||||
import org.alfresco.service.cmr.repository.TemplateService;
|
import org.alfresco.service.cmr.repository.TemplateService;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.bean.LoginBean;
|
import org.alfresco.web.bean.LoginBean;
|
||||||
import org.alfresco.web.bean.repository.Repository;
|
import org.alfresco.web.ui.repo.component.template.DefaultModelHelper;
|
||||||
import org.alfresco.web.bean.repository.User;
|
|
||||||
import org.alfresco.web.ui.common.Utils;
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
@@ -232,48 +223,17 @@ public class TemplateContentServlet extends HttpServlet
|
|||||||
*/
|
*/
|
||||||
private Object getModel(ServiceRegistry services, HttpSession session, NodeRef nodeRef)
|
private Object getModel(ServiceRegistry services, HttpSession session, NodeRef nodeRef)
|
||||||
{
|
{
|
||||||
// create FreeMarker default model and merge
|
// build FreeMarker default model and merge
|
||||||
Map root = new HashMap(11, 1.0f);
|
Map root = DefaultModelHelper.buildDefaultModel(services, Application.getCurrentUser(session));
|
||||||
|
|
||||||
// supply the CompanyHome space as "companyhome"
|
|
||||||
NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
|
||||||
TemplateNode companyRootNode = new TemplateNode(companyRootRef, services, imageResolver);
|
|
||||||
root.put("companyhome", companyRootNode);
|
|
||||||
|
|
||||||
// supply the users Home Space as "userhome"
|
|
||||||
User user = Application.getCurrentUser(session);
|
|
||||||
NodeRef userRootRef = new NodeRef(Repository.getStoreRef(), user.getHomeSpaceId());
|
|
||||||
TemplateNode userRootNode = new TemplateNode(userRootRef, services, imageResolver);
|
|
||||||
root.put("userhome", userRootNode);
|
|
||||||
|
|
||||||
// put the current NodeRef in as "space" and "document"
|
// put the current NodeRef in as "space" and "document"
|
||||||
TemplateNode node = new TemplateNode(nodeRef, services, imageResolver);
|
TemplateNode node = new TemplateNode(nodeRef, services, DefaultModelHelper.imageResolver);
|
||||||
root.put("space", node);
|
root.put("space", node);
|
||||||
root.put("document", node);
|
root.put("document", node);
|
||||||
|
|
||||||
// supply the current user Node as "person"
|
|
||||||
root.put("person", new TemplateNode(user.getPerson(), services, imageResolver));
|
|
||||||
|
|
||||||
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
|
||||||
root.put("date", new Date());
|
|
||||||
|
|
||||||
// add custom method objects
|
|
||||||
root.put("hasAspect", new HasAspectMethod());
|
|
||||||
root.put("message", new I18NMessageMethod());
|
|
||||||
root.put("dateCompare", new DateCompareMethod());
|
|
||||||
|
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Template Image resolver helper */
|
|
||||||
private TemplateImageResolver imageResolver = new TemplateImageResolver()
|
|
||||||
{
|
|
||||||
public String resolveImagePathForName(String filename, boolean small)
|
|
||||||
{
|
|
||||||
return Utils.getFileTypeImage(filename, small);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to generate a URL to process a template against a node.
|
* Helper to generate a URL to process a template against a node.
|
||||||
* <p>
|
* <p>
|
||||||
|
@@ -55,17 +55,20 @@ import org.alfresco.service.cmr.search.SearchService;
|
|||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.service.namespace.RegexQNamePattern;
|
||||||
import org.alfresco.util.CachingDateFormat;
|
import org.alfresco.util.CachingDateFormat;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
import org.alfresco.web.bean.SearchContext.RangeProperties;
|
import org.alfresco.web.bean.SearchContext.RangeProperties;
|
||||||
import org.alfresco.web.bean.repository.MapNode;
|
import org.alfresco.web.bean.repository.MapNode;
|
||||||
import org.alfresco.web.bean.repository.Node;
|
import org.alfresco.web.bean.repository.Node;
|
||||||
import org.alfresco.web.bean.repository.Repository;
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
|
import org.alfresco.web.bean.repository.User;
|
||||||
import org.alfresco.web.config.ClientConfigElement;
|
import org.alfresco.web.config.ClientConfigElement;
|
||||||
import org.alfresco.web.config.ClientConfigElement.CustomProperty;
|
import org.alfresco.web.config.ClientConfigElement.CustomProperty;
|
||||||
import org.alfresco.web.data.IDataContainer;
|
import org.alfresco.web.data.IDataContainer;
|
||||||
import org.alfresco.web.data.QuickSort;
|
import org.alfresco.web.data.QuickSort;
|
||||||
import org.alfresco.web.ui.common.Utils;
|
import org.alfresco.web.ui.common.Utils;
|
||||||
|
import org.alfresco.web.ui.common.component.UIModeList;
|
||||||
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
|
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
|
||||||
import org.alfresco.web.ui.repo.component.UICategorySelector;
|
import org.alfresco.web.ui.repo.component.UICategorySelector;
|
||||||
import org.alfresco.web.ui.repo.component.UISearchCustomProperties;
|
import org.alfresco.web.ui.repo.component.UISearchCustomProperties;
|
||||||
@@ -81,6 +84,8 @@ import org.alfresco.web.ui.repo.component.UISearchCustomProperties;
|
|||||||
*/
|
*/
|
||||||
public class AdvancedSearchBean
|
public class AdvancedSearchBean
|
||||||
{
|
{
|
||||||
|
private static final String OUTCOME_BROWSE = "browse";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor
|
* Default constructor
|
||||||
*/
|
*/
|
||||||
@@ -207,6 +212,22 @@ public class AdvancedSearchBean
|
|||||||
{
|
{
|
||||||
this.editSearchName = editSearchName;
|
this.editSearchName = editSearchName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the searchSaveGlobal.
|
||||||
|
*/
|
||||||
|
public boolean isSearchSaveGlobal()
|
||||||
|
{
|
||||||
|
return this.searchSaveGlobal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param searchSaveGlobal The searchSaveGlobal to set.
|
||||||
|
*/
|
||||||
|
public void setSearchSaveGlobal(boolean searchSaveGlobal)
|
||||||
|
{
|
||||||
|
this.searchSaveGlobal = searchSaveGlobal;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the folder to search, null for all.
|
* @return Returns the folder to search, null for all.
|
||||||
@@ -256,6 +277,38 @@ public class AdvancedSearchBean
|
|||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the savedSearchMode.
|
||||||
|
*/
|
||||||
|
public String getSavedSearchMode()
|
||||||
|
{
|
||||||
|
return this.savedSearchMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param savedSearchMode The savedSearchMode to set.
|
||||||
|
*/
|
||||||
|
public void setSavedSearchMode(String savedSearchMode)
|
||||||
|
{
|
||||||
|
this.savedSearchMode = savedSearchMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the allow Edit mode.
|
||||||
|
*/
|
||||||
|
public boolean isAllowEdit()
|
||||||
|
{
|
||||||
|
return (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param allowEdit The allow Edit mode to set.
|
||||||
|
*/
|
||||||
|
public void setAllowEdit(boolean allowEdit)
|
||||||
|
{
|
||||||
|
// dummy method for Bean interface compliance
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the text to search for.
|
* @return Returns the text to search for.
|
||||||
*/
|
*/
|
||||||
@@ -754,56 +807,74 @@ public class AdvancedSearchBean
|
|||||||
// this causes the browse screen to switch into search results view
|
// this causes the browse screen to switch into search results view
|
||||||
this.navigator.setSearchContext(search);
|
this.navigator.setSearchContext(search);
|
||||||
|
|
||||||
return "browse";
|
return OUTCOME_BROWSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action handler called to initiate the saved search screen
|
* Action handler called to initiate the saved search screen for Create
|
||||||
*/
|
*/
|
||||||
public String saveSearch()
|
public String saveNewSearch()
|
||||||
|
{
|
||||||
|
this.searchDescription = null;
|
||||||
|
this.searchName = null;
|
||||||
|
this.searchSaveGlobal = false;
|
||||||
|
|
||||||
|
return "saveNewSearch";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler called to initiate the saved search screen for Edit
|
||||||
|
*/
|
||||||
|
public String saveEditSearch()
|
||||||
{
|
{
|
||||||
this.searchDescription = null;
|
this.searchDescription = null;
|
||||||
this.searchName = null;
|
this.searchName = null;
|
||||||
this.editSearchName = null;
|
this.editSearchName = null;
|
||||||
|
|
||||||
if (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false)
|
// load previously selected search for overwrite
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// load previous for overwrite
|
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
||||||
try
|
Node searchNode = new Node(searchRef);
|
||||||
|
if (this.nodeService.exists(searchRef) && searchNode.hasPermission(PermissionService.WRITE))
|
||||||
{
|
{
|
||||||
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
Node node = new Node(searchRef);
|
||||||
Node searchNode = new Node(searchRef);
|
this.searchName = node.getName();
|
||||||
if (this.nodeService.exists(searchRef) && searchNode.hasPermission(PermissionService.WRITE))
|
this.editSearchName = this.searchName;
|
||||||
{
|
this.searchDescription = (String)node.getProperties().get(ContentModel.PROP_DESCRIPTION);
|
||||||
Node node = new Node(searchRef);
|
|
||||||
this.searchName = node.getName();
|
|
||||||
this.editSearchName = this.searchName;
|
|
||||||
this.searchDescription = (String)node.getProperties().get(ContentModel.PROP_DESCRIPTION);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// unable to overwrite existing saved search
|
|
||||||
this.savedSearch = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Throwable err)
|
else
|
||||||
{
|
{
|
||||||
// unable to overwrite existing saved search for some other reason
|
// unable to overwrite existing saved search
|
||||||
this.savedSearch = null;
|
this.savedSearch = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
// unable to overwrite existing saved search for some other reason
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
|
||||||
return "saveSearch";
|
return "saveEditSearch";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action handler called to save the current search
|
* Action handler called to save a new search
|
||||||
*/
|
*/
|
||||||
public String saveSearchOK()
|
public String saveNewSearchOK()
|
||||||
{
|
{
|
||||||
String outcome = "browse";
|
String outcome = OUTCOME_BROWSE;
|
||||||
|
|
||||||
|
NodeRef searchesRef;
|
||||||
|
if (isSearchSaveGlobal() == true)
|
||||||
|
{
|
||||||
|
searchesRef = getGlobalSearchesRef();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
searchesRef = getUserSearchesRef();
|
||||||
|
}
|
||||||
|
|
||||||
NodeRef searchesRef = getSavedSearchesRef();
|
|
||||||
SearchContext search = this.navigator.getSearchContext();
|
SearchContext search = this.navigator.getSearchContext();
|
||||||
if (searchesRef != null && search != null)
|
if (searchesRef != null && search != null)
|
||||||
{
|
{
|
||||||
@@ -814,45 +885,19 @@ public class AdvancedSearchBean
|
|||||||
tx = Repository.getUserTransaction(context);
|
tx = Repository.getUserTransaction(context);
|
||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
Map<QName, Serializable> props = null;
|
// create new content node as the saved search object
|
||||||
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2, 1.0f);
|
||||||
// handle Edit e.g. Overwrite of existing search
|
props.put(ContentModel.PROP_NAME, this.searchName);
|
||||||
// detect if was previously selected saved search (e.g. NodeRef not null)
|
props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
|
||||||
boolean edit = false;
|
ChildAssociationRef childRef = this.nodeService.createNode(
|
||||||
if (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false)
|
searchesRef,
|
||||||
{
|
ContentModel.ASSOC_CONTAINS,
|
||||||
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(this.searchName)),
|
||||||
edit = (this.nodeService.exists(searchRef));
|
ContentModel.TYPE_CONTENT,
|
||||||
}
|
props);
|
||||||
|
|
||||||
ContentService contentService = Repository.getServiceRegistry(context).getContentService();
|
ContentService contentService = Repository.getServiceRegistry(context).getContentService();
|
||||||
ContentWriter writer;
|
ContentWriter writer = contentService.getWriter(childRef.getChildRef(), ContentModel.PROP_CONTENT, true);
|
||||||
if (edit)
|
|
||||||
{
|
|
||||||
// edit existing saved search
|
|
||||||
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
|
||||||
props = this.nodeService.getProperties(searchRef);
|
|
||||||
props.put(ContentModel.PROP_NAME, this.searchName);
|
|
||||||
props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
|
|
||||||
this.nodeService.setProperties(searchRef, props);
|
|
||||||
|
|
||||||
writer = contentService.getWriter(searchRef, ContentModel.PROP_CONTENT, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// create new content node as the saved search object
|
|
||||||
props = new HashMap<QName, Serializable>(2, 1.0f);
|
|
||||||
props.put(ContentModel.PROP_NAME, this.searchName);
|
|
||||||
props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
|
|
||||||
ChildAssociationRef childRef = this.nodeService.createNode(
|
|
||||||
searchesRef,
|
|
||||||
ContentModel.ASSOC_CONTAINS,
|
|
||||||
QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(this.searchName)),
|
|
||||||
ContentModel.TYPE_CONTENT,
|
|
||||||
props);
|
|
||||||
|
|
||||||
writer = contentService.getWriter(childRef.getChildRef(), ContentModel.PROP_CONTENT, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get a writer to our new node ready for XML content
|
// get a writer to our new node ready for XML content
|
||||||
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||||
@@ -878,6 +923,61 @@ public class AdvancedSearchBean
|
|||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler called to save an existing search
|
||||||
|
*/
|
||||||
|
public String saveEditSearchOK()
|
||||||
|
{
|
||||||
|
String outcome = OUTCOME_BROWSE;
|
||||||
|
|
||||||
|
SearchContext search = this.navigator.getSearchContext();
|
||||||
|
if (search != null)
|
||||||
|
{
|
||||||
|
UserTransaction tx = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FacesContext context = FacesContext.getCurrentInstance();
|
||||||
|
tx = Repository.getUserTransaction(context);
|
||||||
|
tx.begin();
|
||||||
|
|
||||||
|
// handle Edit e.g. Overwrite of existing search
|
||||||
|
// detect if was previously selected saved search (e.g. NodeRef not null)
|
||||||
|
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
||||||
|
if (this.nodeService.exists(searchRef))
|
||||||
|
{
|
||||||
|
Map<QName, Serializable> props = this.nodeService.getProperties(searchRef);
|
||||||
|
props.put(ContentModel.PROP_NAME, this.searchName);
|
||||||
|
props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
|
||||||
|
this.nodeService.setProperties(searchRef, props);
|
||||||
|
|
||||||
|
ContentService contentService = Repository.getServiceRegistry(context).getContentService();
|
||||||
|
ContentWriter writer = contentService.getWriter(searchRef, ContentModel.PROP_CONTENT, true);
|
||||||
|
|
||||||
|
// get a writer to our new node ready for XML content
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
// output an XML serialized version of the SearchContext object
|
||||||
|
writer.putContent(search.toXML());
|
||||||
|
|
||||||
|
tx.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cachedSavedSearches.clear();
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
|
||||||
|
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||||
|
FacesContext.getCurrentInstance(), MSG_ERROR_SAVE_SEARCH), e.getMessage()), e);
|
||||||
|
outcome = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return outcome;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return list of saved searches as SelectItem objects
|
* @return list of saved searches as SelectItem objects
|
||||||
*/
|
*/
|
||||||
@@ -887,26 +987,35 @@ public class AdvancedSearchBean
|
|||||||
if (savedSearches == null)
|
if (savedSearches == null)
|
||||||
{
|
{
|
||||||
FacesContext fc = FacesContext.getCurrentInstance();
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
String xpath = ".//*";
|
|
||||||
|
|
||||||
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||||
|
|
||||||
NodeRef searchesRef = getSavedSearchesRef();
|
// get the searches list from the current user or global searches location
|
||||||
|
NodeRef searchesRef = null;
|
||||||
|
if (SAVED_SEARCHES_USER.equals(getSavedSearchMode()) == true)
|
||||||
|
{
|
||||||
|
searchesRef = getUserSearchesRef();
|
||||||
|
}
|
||||||
|
else if (SAVED_SEARCHES_GLOBAL.equals(getSavedSearchMode()) == true)
|
||||||
|
{
|
||||||
|
searchesRef = getGlobalSearchesRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the content nodes under the folder
|
||||||
if (searchesRef != null)
|
if (searchesRef != null)
|
||||||
{
|
{
|
||||||
List<NodeRef> results = searchService.selectNodes(
|
DictionaryService dd = services.getDictionaryService();
|
||||||
searchesRef,
|
|
||||||
xpath,
|
List<ChildAssociationRef> childRefs = nodeService.getChildAssocs(
|
||||||
null,
|
searchesRef,
|
||||||
namespaceService,
|
ContentModel.ASSOC_CONTAINS,
|
||||||
false);
|
RegexQNamePattern.MATCH_ALL);
|
||||||
savedSearches = new ArrayList<SelectItem>(results.size() + 1);
|
|
||||||
if (results.size() != 0)
|
savedSearches = new ArrayList<SelectItem>(childRefs.size() + 1);
|
||||||
|
if (childRefs.size() != 0)
|
||||||
{
|
{
|
||||||
DictionaryService dd = services.getDictionaryService();
|
for (ChildAssociationRef ref : childRefs)
|
||||||
for (NodeRef ref : results)
|
|
||||||
{
|
{
|
||||||
Node childNode = new Node(ref);
|
Node childNode = new Node(ref.getChildRef());
|
||||||
if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT))
|
if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT))
|
||||||
{
|
{
|
||||||
savedSearches.add(new SelectItem(childNode.getId(), childNode.getName()));
|
savedSearches.add(new SelectItem(childNode.getId(), childNode.getName()));
|
||||||
@@ -920,7 +1029,7 @@ public class AdvancedSearchBean
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// handle missing folder case
|
// handle missing/access denied folder case
|
||||||
savedSearches = new ArrayList<SelectItem>(1);
|
savedSearches = new ArrayList<SelectItem>(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -935,6 +1044,25 @@ public class AdvancedSearchBean
|
|||||||
return savedSearches;
|
return savedSearches;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the current saved searches list mode based on user selection
|
||||||
|
*/
|
||||||
|
public void savedSearchModeChanged(ActionEvent event)
|
||||||
|
{
|
||||||
|
UIModeList savedModeList = (UIModeList)event.getComponent();
|
||||||
|
|
||||||
|
// get the saved searches list mode
|
||||||
|
String viewMode = savedModeList.getValue().toString();
|
||||||
|
|
||||||
|
// persist
|
||||||
|
setSavedSearchMode(viewMode);
|
||||||
|
|
||||||
|
// clear existing caches and values
|
||||||
|
// the values will be re-queried when the client requests the saved searches list
|
||||||
|
this.cachedSavedSearches.clear();
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action handler called when a saved search is selected by the user
|
* Action handler called when a saved search is selected by the user
|
||||||
*/
|
*/
|
||||||
@@ -1142,9 +1270,66 @@ public class AdvancedSearchBean
|
|||||||
/**
|
/**
|
||||||
* @return the cached reference to the shared Saved Searches folder
|
* @return the cached reference to the shared Saved Searches folder
|
||||||
*/
|
*/
|
||||||
private NodeRef getSavedSearchesRef()
|
private NodeRef getUserSearchesRef()
|
||||||
{
|
{
|
||||||
if (savedSearchesRef == null)
|
if (userSearchesRef == null)
|
||||||
|
{
|
||||||
|
NodeRef globalRef = getGlobalSearchesRef();
|
||||||
|
if (globalRef != null)
|
||||||
|
{
|
||||||
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
|
User user = Application.getCurrentUser(fc);
|
||||||
|
String xpath = NamespaceService.APP_MODEL_PREFIX + ":" + QName.createValidLocalName(user.getUserName());
|
||||||
|
|
||||||
|
List<NodeRef> results = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = searchService.selectNodes(
|
||||||
|
globalRef,
|
||||||
|
xpath,
|
||||||
|
null,
|
||||||
|
namespaceService,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
catch (AccessDeniedException err)
|
||||||
|
{
|
||||||
|
// ignore and return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results != null)
|
||||||
|
{
|
||||||
|
if (results.size() == 1)
|
||||||
|
{
|
||||||
|
userSearchesRef = results.get(0);
|
||||||
|
}
|
||||||
|
else if (results.size() == 0)
|
||||||
|
{
|
||||||
|
// attempt to create folder for this user for first time
|
||||||
|
// create the preferences Node for this user
|
||||||
|
Map<QName, Serializable> props = new HashMap<QName, Serializable>(2, 1.0f);
|
||||||
|
props.put(ContentModel.PROP_NAME, user.getUserName());
|
||||||
|
ChildAssociationRef childRef = nodeService.createNode(
|
||||||
|
globalRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.APP_MODEL_1_0_URI, QName.createValidLocalName(user.getUserName())),
|
||||||
|
ContentModel.TYPE_FOLDER,
|
||||||
|
props);
|
||||||
|
|
||||||
|
userSearchesRef = childRef.getChildRef();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return userSearchesRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cached reference to the global Saved Searches folder
|
||||||
|
*/
|
||||||
|
private NodeRef getGlobalSearchesRef()
|
||||||
|
{
|
||||||
|
if (globalSearchesRef == null)
|
||||||
{
|
{
|
||||||
FacesContext fc = FacesContext.getCurrentInstance();
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
String xpath = Application.getRootPath(fc) + "/" +
|
String xpath = Application.getRootPath(fc) + "/" +
|
||||||
@@ -1169,11 +1354,11 @@ public class AdvancedSearchBean
|
|||||||
|
|
||||||
if (results != null && results.size() == 1)
|
if (results != null && results.size() == 1)
|
||||||
{
|
{
|
||||||
savedSearchesRef = results.get(0);
|
globalSearchesRef = results.get(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return savedSearchesRef;
|
return globalSearchesRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1292,7 +1477,10 @@ public class AdvancedSearchBean
|
|||||||
private static final String LOOKIN_ALL = "all";
|
private static final String LOOKIN_ALL = "all";
|
||||||
private static final String LOOKIN_OTHER = "other";
|
private static final String LOOKIN_OTHER = "other";
|
||||||
|
|
||||||
private static final String NO_SELECTION = "none";
|
private static final String SAVED_SEARCHES_USER = "user";
|
||||||
|
private static final String SAVED_SEARCHES_GLOBAL = "global";
|
||||||
|
|
||||||
|
private static final String NO_SELECTION = "NONE";
|
||||||
|
|
||||||
/** The NodeService to be used by the bean */
|
/** The NodeService to be used by the bean */
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
@@ -1379,11 +1567,24 @@ public class AdvancedSearchBean
|
|||||||
private boolean modifiedDateChecked = false;
|
private boolean modifiedDateChecked = false;
|
||||||
private boolean createdDateChecked = false;
|
private boolean createdDateChecked = false;
|
||||||
|
|
||||||
private NodeRef savedSearchesRef = null;
|
/** cached ref to the global saved searches folder */
|
||||||
|
private NodeRef globalSearchesRef = null;
|
||||||
|
|
||||||
|
/** cached ref to the current users saved searches folder */
|
||||||
|
private NodeRef userSearchesRef = null;
|
||||||
|
|
||||||
|
/** ID to the last selected saved search */
|
||||||
private String savedSearch = null;
|
private String savedSearch = null;
|
||||||
|
|
||||||
|
/** ModeList component value for selecting user/global searches */
|
||||||
|
private String savedSearchMode = SAVED_SEARCHES_USER;
|
||||||
|
|
||||||
|
/** name of the saved search to edit */
|
||||||
private String editSearchName = null;
|
private String editSearchName = null;
|
||||||
|
|
||||||
|
/** form field for saving search as user/global */
|
||||||
|
private boolean searchSaveGlobal = false;
|
||||||
|
|
||||||
|
/** auto-expiring cache of the list of saved searches */
|
||||||
private ExpiringValueCache<List<SelectItem>> cachedSavedSearches = new ExpiringValueCache<List<SelectItem>>();
|
private ExpiringValueCache<List<SelectItem>> cachedSavedSearches = new ExpiringValueCache<List<SelectItem>>();
|
||||||
}
|
}
|
||||||
|
@@ -138,7 +138,7 @@ public final class SearchContext implements Serializable
|
|||||||
|
|
||||||
if (text.length() != 0 && text.length() >= minimum)
|
if (text.length() != 0 && text.length() >= minimum)
|
||||||
{
|
{
|
||||||
if (text.indexOf(' ') == -1)
|
if (text.indexOf(' ') == -1 && text.charAt(0) != '"')
|
||||||
{
|
{
|
||||||
// simple single word text search
|
// simple single word text search
|
||||||
if (text.charAt(0) != '*')
|
if (text.charAt(0) != '*')
|
||||||
|
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Mozilla Public License version 1.1
|
||||||
|
* with a permitted attribution clause. You may obtain a
|
||||||
|
* copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.alfresco.org/legal/license.txt
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
* either express or implied. See the License for the specific
|
||||||
|
* language governing permissions and limitations under the
|
||||||
|
* License.
|
||||||
|
*/
|
||||||
|
package org.alfresco.web.ui.repo.component.template;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.alfresco.repo.template.DateCompareMethod;
|
||||||
|
import org.alfresco.repo.template.HasAspectMethod;
|
||||||
|
import org.alfresco.repo.template.I18NMessageMethod;
|
||||||
|
import org.alfresco.service.ServiceRegistry;
|
||||||
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
|
import org.alfresco.service.cmr.repository.TemplateImageResolver;
|
||||||
|
import org.alfresco.service.cmr.repository.TemplateNode;
|
||||||
|
import org.alfresco.web.app.Application;
|
||||||
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
|
import org.alfresco.web.bean.repository.User;
|
||||||
|
import org.alfresco.web.ui.common.Utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to generate the default template model.
|
||||||
|
* <p>
|
||||||
|
* See {@link http://www.alfresco.org/mediawiki/index.php/Template_Guide}
|
||||||
|
*
|
||||||
|
* @author Kevin Roast
|
||||||
|
*/
|
||||||
|
public class DefaultModelHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Private Constructor
|
||||||
|
*/
|
||||||
|
private DefaultModelHelper()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the default FreeMarker template model.
|
||||||
|
* <p>
|
||||||
|
* Other root level objects such as the current Space or Document are generally
|
||||||
|
* added by the appropriate bean responsible for provided access to those nodes.
|
||||||
|
* <p>
|
||||||
|
* See {@link http://www.alfresco.org/mediawiki/index.php/Template_Guide}
|
||||||
|
*
|
||||||
|
* @return Map containing the default model.
|
||||||
|
*/
|
||||||
|
public static Map buildDefaultModel(ServiceRegistry services, User user)
|
||||||
|
{
|
||||||
|
if (services == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("ServiceRegistry is mandatory.");
|
||||||
|
}
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Current User is mandatory.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create FreeMarker default model and merge
|
||||||
|
Map root = new HashMap(16, 1.0f);
|
||||||
|
|
||||||
|
// supply the CompanyHome space as "companyhome"
|
||||||
|
NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
||||||
|
TemplateNode companyRootNode = new TemplateNode(companyRootRef, services, imageResolver);
|
||||||
|
root.put("companyhome", companyRootNode);
|
||||||
|
|
||||||
|
// supply the users Home Space as "userhome"
|
||||||
|
NodeRef userRootRef = new NodeRef(Repository.getStoreRef(), user.getHomeSpaceId());
|
||||||
|
TemplateNode userRootNode = new TemplateNode(userRootRef, services, imageResolver);
|
||||||
|
root.put("userhome", userRootNode);
|
||||||
|
|
||||||
|
// supply the current user Node as "person"
|
||||||
|
root.put("person", new TemplateNode(user.getPerson(), services, imageResolver));
|
||||||
|
|
||||||
|
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
||||||
|
root.put("date", new Date());
|
||||||
|
|
||||||
|
// add custom method objects
|
||||||
|
root.put("hasAspect", new HasAspectMethod());
|
||||||
|
root.put("message", new I18NMessageMethod());
|
||||||
|
root.put("dateCompare", new DateCompareMethod());
|
||||||
|
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Template Image resolver helper */
|
||||||
|
public static TemplateImageResolver imageResolver = new TemplateImageResolver()
|
||||||
|
{
|
||||||
|
public String resolveImagePathForName(String filename, boolean small)
|
||||||
|
{
|
||||||
|
return Utils.getFileTypeImage(filename, small);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@@ -191,33 +191,11 @@ public class UITemplate extends SelfRenderingComponent
|
|||||||
|
|
||||||
if (getEngine().equals(ENGINE_DEFAULT))
|
if (getEngine().equals(ENGINE_DEFAULT))
|
||||||
{
|
{
|
||||||
// create FreeMarker default model and merge
|
// create an instance of the default FreeMarker template object model
|
||||||
Map root = new HashMap(11, 1.0f);
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
|
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||||
FacesContext context = FacesContext.getCurrentInstance();
|
User user = Application.getCurrentUser(fc);
|
||||||
ServiceRegistry services = Repository.getServiceRegistry(context);
|
Map root = DefaultModelHelper.buildDefaultModel(services, user);
|
||||||
|
|
||||||
// supply the CompanyHome space as "companyhome"
|
|
||||||
NodeRef companyRootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
|
||||||
TemplateNode companyRootNode = new TemplateNode(companyRootRef, services, imageResolver);
|
|
||||||
root.put("companyhome", companyRootNode);
|
|
||||||
|
|
||||||
// supply the users Home Space as "userhome"
|
|
||||||
User user = Application.getCurrentUser(context);
|
|
||||||
NodeRef userRootRef = new NodeRef(Repository.getStoreRef(), user.getHomeSpaceId());
|
|
||||||
TemplateNode userRootNode = new TemplateNode(userRootRef, services, imageResolver);
|
|
||||||
root.put("userhome", userRootNode);
|
|
||||||
|
|
||||||
// supply the current user Node as "person"
|
|
||||||
root.put("person", new TemplateNode(user.getPerson(), services, imageResolver));
|
|
||||||
|
|
||||||
// current date/time is useful to have and isn't supplied by FreeMarker by default
|
|
||||||
root.put("date", new Date());
|
|
||||||
|
|
||||||
// add custom method objects
|
|
||||||
root.put("hasAspect", new HasAspectMethod());
|
|
||||||
root.put("message", new I18NMessageMethod());
|
|
||||||
root.put("dateCompare", new DateCompareMethod());
|
|
||||||
|
|
||||||
// merge models
|
// merge models
|
||||||
if (model instanceof Map)
|
if (model instanceof Map)
|
||||||
|
@@ -175,9 +175,13 @@
|
|||||||
<to-view-id>/jsp/forums/topic.jsp</to-view-id>
|
<to-view-id>/jsp/forums/topic.jsp</to-view-id>
|
||||||
</navigation-case>
|
</navigation-case>
|
||||||
<navigation-case>
|
<navigation-case>
|
||||||
<from-outcome>saveSearch</from-outcome>
|
<from-outcome>saveNewSearch</from-outcome>
|
||||||
<to-view-id>/jsp/dialog/save-search.jsp</to-view-id>
|
<to-view-id>/jsp/dialog/save-search.jsp</to-view-id>
|
||||||
</navigation-case>
|
</navigation-case>
|
||||||
|
<navigation-case>
|
||||||
|
<from-outcome>saveEditSearch</from-outcome>
|
||||||
|
<to-view-id>/jsp/dialog/edit-search.jsp</to-view-id>
|
||||||
|
</navigation-case>
|
||||||
</navigation-rule>
|
</navigation-rule>
|
||||||
|
|
||||||
<!-- Admin Console rules -->
|
<!-- Admin Console rules -->
|
||||||
|
BIN
source/web/images/icons/edit_search.gif
Normal file
BIN
source/web/images/icons/edit_search.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 925 B |
BIN
source/web/images/icons/edit_search_large.gif
Normal file
BIN
source/web/images/icons/edit_search_large.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@@ -159,11 +159,14 @@
|
|||||||
<%--<div style="padding-top:2px"><a:statusMessage id="status2" border="yellowInner" bgcolor="#ffffcc" binding="#{BrowseBean.statusMessage}" /></div>--%>
|
<%--<div style="padding-top:2px"><a:statusMessage id="status2" border="yellowInner" bgcolor="#ffffcc" binding="#{BrowseBean.statusMessage}" /></div>--%>
|
||||||
</td>
|
</td>
|
||||||
<td bgcolor="#465F7D" width=1></td>
|
<td bgcolor="#465F7D" width=1></td>
|
||||||
<td width=100 style="padding-left:2px">
|
<td width=135 style="padding-left:2px">
|
||||||
<%-- Current object actions --%>
|
<%-- Current object actions --%>
|
||||||
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.actions}" id="msg14" /><br>
|
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.actions}" id="msg14" /><br>
|
||||||
<a:actionLink value="#{msg.new_search}" image="/images/icons/search_icon.gif" padding="4" action="advSearch" id="link20" />
|
<a:actionLink value="#{msg.new_search}" image="/images/icons/search_icon.gif" padding="4" action="advSearch" id="link20" />
|
||||||
<a:actionLink value="#{msg.save_search}" image="/images/icons/save_search.gif" padding="4" action="#{AdvancedSearchBean.saveSearch}" id="link20_1" />
|
<a:actionLink value="#{msg.save_new_search}" image="/images/icons/save_search.gif" padding="4" action="#{AdvancedSearchBean.saveNewSearch}" id="link20_1" />
|
||||||
|
<a:booleanEvaluator value="#{AdvancedSearchBean.allowEdit == true}" id="eval0">
|
||||||
|
<a:actionLink value="#{msg.save_edit_search}" image="/images/icons/edit_search.gif" padding="4" action="#{AdvancedSearchBean.saveEditSearch}" id="link20_2" />
|
||||||
|
</a:booleanEvaluator>
|
||||||
<a:actionLink value="#{msg.close_search}" image="/images/icons/action.gif" padding="4" actionListener="#{BrowseBean.closeSearch}" id="link21" />
|
<a:actionLink value="#{msg.close_search}" image="/images/icons/action.gif" padding="4" actionListener="#{BrowseBean.closeSearch}" id="link21" />
|
||||||
</td>
|
</td>
|
||||||
</a:panel>
|
</a:panel>
|
||||||
|
@@ -92,14 +92,21 @@
|
|||||||
<a:actionLink value="#{msg.resetall}" image="/images/icons/delete.gif" padding="4" actionListener="#{AdvancedSearchBean.reset}" />
|
<a:actionLink value="#{msg.resetall}" image="/images/icons/delete.gif" padding="4" actionListener="#{AdvancedSearchBean.reset}" />
|
||||||
</td>
|
</td>
|
||||||
<td bgcolor="#465F7D" width=1></td>
|
<td bgcolor="#465F7D" width=1></td>
|
||||||
<td width=100 style="padding-left:2px">
|
<td width=200 style="padding-left:2px">
|
||||||
<%-- Available Saved Searches --%>
|
<%-- Available Saved Searches --%>
|
||||||
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.saved_searches}" />
|
<center><h:outputText styleClass="mainSubTitle" value="#{msg.saved_searches}" /></center>
|
||||||
<div style="padding-top:4px;white-space:nowrap">
|
<div style="padding-top:4px">
|
||||||
|
<a:modeList itemSpacing="3" iconColumnWidth="20" style="text-align:right" selectedStyleClass="statusListHighlight" disabledStyleClass="statusListDisabled" selectedImage="/images/icons/Details.gif"
|
||||||
|
value="#{AdvancedSearchBean.savedSearchMode}" actionListener="#{AdvancedSearchBean.savedSearchModeChanged}">
|
||||||
|
<a:listItem value="user" label="#{msg.user_searches}" />
|
||||||
|
<a:listItem value="global" label="#{msg.global_searches}" />
|
||||||
|
</a:modeList>
|
||||||
|
</div>
|
||||||
|
<div style="white-space:nowrap">
|
||||||
<%-- Saved Searches drop-down selector --%>
|
<%-- Saved Searches drop-down selector --%>
|
||||||
<%-- uses a nasty hack to execute an ActionListener for the drop-down
|
<%-- uses a nasty hack to execute an ActionListener for the drop-down.
|
||||||
tried using a valueChangedListener+formsubmit but the valueChangedListener
|
tried using a valueChangedListener+formsubmit but the valueChangedListener
|
||||||
is called too late in the lifecycle for the form controls to be managed --%>
|
is called too late in the lifecycle for the form controls to be modified --%>
|
||||||
<h:selectOneMenu id="searches" value="#{AdvancedSearchBean.savedSearch}" onchange="document.forms['advsearch']['advsearch:act'].value='advsearch:show-search'; document.forms['advsearch'].submit(); return true;">
|
<h:selectOneMenu id="searches" value="#{AdvancedSearchBean.savedSearch}" onchange="document.forms['advsearch']['advsearch:act'].value='advsearch:show-search'; document.forms['advsearch'].submit(); return true;">
|
||||||
<f:selectItems value="#{AdvancedSearchBean.savedSearches}" />
|
<f:selectItems value="#{AdvancedSearchBean.savedSearches}" />
|
||||||
</h:selectOneMenu>
|
</h:selectOneMenu>
|
||||||
|
@@ -148,7 +148,7 @@
|
|||||||
actionListener="#{ClipboardBean.copyNode}">
|
actionListener="#{ClipboardBean.copyNode}">
|
||||||
<f:param name="id" value="#{DocumentDetailsBean.id}" />
|
<f:param name="id" value="#{DocumentDetailsBean.id}" />
|
||||||
</a:actionLink>
|
</a:actionLink>
|
||||||
|
|
||||||
<%-- delete --%>
|
<%-- delete --%>
|
||||||
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Delete">
|
<r:permissionEvaluator value="#{DocumentDetailsBean.document}" allow="Delete">
|
||||||
<a:booleanEvaluator value="#{DocumentDetailsBean.locked == false && DocumentDetailsBean.workingCopy == false}">
|
<a:booleanEvaluator value="#{DocumentDetailsBean.locked == false && DocumentDetailsBean.workingCopy == false}">
|
||||||
|
203
source/web/jsp/dialog/edit-search.jsp
Normal file
203
source/web/jsp/dialog/edit-search.jsp
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<%--
|
||||||
|
Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
|
||||||
|
Licensed under the Mozilla Public License version 1.1
|
||||||
|
with a permitted attribution clause. You may obtain a
|
||||||
|
copy of the License at
|
||||||
|
|
||||||
|
http://www.alfresco.org/legal/license.txt
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
either express or implied. See the License for the specific
|
||||||
|
language governing permissions and limitations under the
|
||||||
|
License.
|
||||||
|
--%>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
|
||||||
|
|
||||||
|
<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
|
||||||
|
<%@ page isELIgnored="false" %>
|
||||||
|
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
|
||||||
|
|
||||||
|
<r:page titleId="title_save_search">
|
||||||
|
|
||||||
|
<script language="JavaScript1.2">
|
||||||
|
|
||||||
|
window.onload = pageLoaded;
|
||||||
|
|
||||||
|
function pageLoaded()
|
||||||
|
{
|
||||||
|
document.getElementById("save-search:name").focus();
|
||||||
|
checkButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkButtonState()
|
||||||
|
{
|
||||||
|
if (document.getElementById("save-search:name").value.length == 0 )
|
||||||
|
{
|
||||||
|
document.getElementById("save-search:ok-button").disabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
document.getElementById("save-search:ok-button").disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<f:view>
|
||||||
|
|
||||||
|
<%-- load a bundle of properties with I18N strings --%>
|
||||||
|
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
|
||||||
|
|
||||||
|
<h:form acceptCharset="UTF-8" id="save-search">
|
||||||
|
|
||||||
|
<%-- Main outer table --%>
|
||||||
|
<table cellspacing="0" cellpadding="2">
|
||||||
|
|
||||||
|
<%-- Title bar --%>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<%@ include file="../parts/titlebar.jsp" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- Main area --%>
|
||||||
|
<tr valign="top">
|
||||||
|
<%-- Shelf --%>
|
||||||
|
<td>
|
||||||
|
<%@ include file="../parts/shelf.jsp" %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<%-- Work Area --%>
|
||||||
|
<td width="100%">
|
||||||
|
<table cellspacing="0" cellpadding="0" width="100%">
|
||||||
|
<%-- Breadcrumb --%>
|
||||||
|
<%@ include file="../parts/breadcrumb.jsp" %>
|
||||||
|
|
||||||
|
<%-- Status and Actions --%>
|
||||||
|
<tr>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_4.gif)" width="4"></td>
|
||||||
|
<td bgcolor="#EEEEEE">
|
||||||
|
|
||||||
|
<%-- Status and Actions inner contents table --%>
|
||||||
|
<%-- Generally this consists of an icon, textual summary and actions for the current object --%>
|
||||||
|
<table cellspacing="4" cellpadding="0" width="100%">
|
||||||
|
<tr valign="top">
|
||||||
|
<td width="32">
|
||||||
|
<h:graphicImage id="wizard-logo" url="/images/icons/save_search_large.gif" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="mainTitle"><h:outputText value="#{msg.save_edit_search}" /></div>
|
||||||
|
<div class="mainSubText"><h:outputText value="#{msg.save_search_description}" /></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_6.gif)" width="4"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- separator row with gradient shadow --%>
|
||||||
|
<tr>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_7.gif" width="4" height="9"></td>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_8.gif)"></td>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_9.gif" width="4" height="9"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- Details --%>
|
||||||
|
<tr valign=top>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
|
||||||
|
<td>
|
||||||
|
<table cellspacing="0" cellpadding="3" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td width="100%" valign="top">
|
||||||
|
|
||||||
|
<a:errors message="#{msg.error_wizard}" styleClass="errorMessage" />
|
||||||
|
|
||||||
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
|
||||||
|
<table cellpadding="2" cellspacing="2" border="0" width="100%">
|
||||||
|
<a:panel id="edit-panel" rendered="#{AdvancedSearchBean.editSearchName != null}">
|
||||||
|
<tr>
|
||||||
|
<td width="100%" valign="top" colspan="2" style="padding-bottom:6px">
|
||||||
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %>
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td valign=top style="padding-top:2px" width=20><h:graphicImage url="/images/icons/info_icon.gif" width="16" height="16"/></td>
|
||||||
|
<td class="mainSubText">
|
||||||
|
<h:outputFormat value="#{msg.saved_search_warning}">
|
||||||
|
<f:param value="#{AdvancedSearchBean.editSearchName}" />
|
||||||
|
</h:outputFormat>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</a:panel>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="wizardSectionHeading"><h:outputText value="#{msg.search_props}" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><h:outputText value="#{msg.name}" />:</td>
|
||||||
|
<td>
|
||||||
|
<h:inputText id="name" value="#{AdvancedSearchBean.searchName}" size="35" maxlength="1024"
|
||||||
|
onkeyup="javascript:checkButtonState();" onchange="javascript:checkButtonState();"/> *
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><h:outputText value="#{msg.description}" />:</td>
|
||||||
|
<td>
|
||||||
|
<h:inputText value="#{AdvancedSearchBean.searchDescription}" size="35" maxlength="1024" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td valign="top">
|
||||||
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %>
|
||||||
|
<table cellpadding="1" cellspacing="1" border="0">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<h:commandButton id="ok-button" value="#{msg.save}" action="#{AdvancedSearchBean.saveEditSearchOK}"
|
||||||
|
styleClass="wizardButton" disabled="true" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<h:commandButton value="#{msg.cancel}" action="browse" styleClass="wizardButton" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- separator row with bottom panel graphics --%>
|
||||||
|
<tr>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_7.gif" width="4" height="4"></td>
|
||||||
|
<td width="100%" align="center" style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_8.gif)"></td>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_9.gif" width="4" height="4"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
</f:view>
|
||||||
|
|
||||||
|
</r:page>
|
@@ -90,10 +90,10 @@
|
|||||||
<table cellspacing="4" cellpadding="0" width="100%">
|
<table cellspacing="4" cellpadding="0" width="100%">
|
||||||
<tr valign="top">
|
<tr valign="top">
|
||||||
<td width="32">
|
<td width="32">
|
||||||
<h:graphicImage id="wizard-logo" url="/images/icons/save_search_large.gif" />
|
<h:graphicImage id="wizard-logo" url="/images/icons/edit_search_large.gif" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="mainTitle"><h:outputText value="#{msg.save_search}" /></div>
|
<div class="mainTitle"><h:outputText value="#{msg.save_new_search}" /></div>
|
||||||
<div class="mainSubText"><h:outputText value="#{msg.save_search_description}" /></div>
|
<div class="mainSubText"><h:outputText value="#{msg.save_search_description}" /></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -122,25 +122,6 @@
|
|||||||
|
|
||||||
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
|
||||||
<table cellpadding="2" cellspacing="2" border="0" width="100%">
|
<table cellpadding="2" cellspacing="2" border="0" width="100%">
|
||||||
<a:panel id="edit-panel" rendered="#{AdvancedSearchBean.editSearchName != null}">
|
|
||||||
<tr>
|
|
||||||
<td width="100%" valign="top" colspan="2" style="padding-bottom:6px">
|
|
||||||
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %>
|
|
||||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
|
||||||
<tr>
|
|
||||||
<td valign=top style="padding-top:2px" width=20><h:graphicImage url="/images/icons/info_icon.gif" width="16" height="16"/></td>
|
|
||||||
<td class="mainSubText">
|
|
||||||
<h:outputFormat value="#{msg.saved_search_warning}">
|
|
||||||
<f:param value="#{AdvancedSearchBean.editSearchName}" />
|
|
||||||
</h:outputFormat>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</a:panel>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="2" class="wizardSectionHeading"><h:outputText value="#{msg.search_props}" /></td>
|
<td colspan="2" class="wizardSectionHeading"><h:outputText value="#{msg.search_props}" /></td>
|
||||||
</tr>
|
</tr>
|
||||||
@@ -157,6 +138,12 @@
|
|||||||
<h:inputText value="#{AdvancedSearchBean.searchDescription}" size="35" maxlength="1024" />
|
<h:inputText value="#{AdvancedSearchBean.searchDescription}" size="35" maxlength="1024" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td></td>
|
||||||
|
<td>
|
||||||
|
<h:selectBooleanCheckbox value="#{AdvancedSearchBean.searchSaveGlobal}" /><span style="vertical-align:20%"><h:outputText value="#{msg.save_search_global}" /></span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %>
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %>
|
||||||
</td>
|
</td>
|
||||||
@@ -166,7 +153,7 @@
|
|||||||
<table cellpadding="1" cellspacing="1" border="0">
|
<table cellpadding="1" cellspacing="1" border="0">
|
||||||
<tr>
|
<tr>
|
||||||
<td align="center">
|
<td align="center">
|
||||||
<h:commandButton id="ok-button" value="#{msg.save}" action="#{AdvancedSearchBean.saveSearchOK}"
|
<h:commandButton id="ok-button" value="#{msg.save}" action="#{AdvancedSearchBean.saveNewSearchOK}"
|
||||||
styleClass="wizardButton" disabled="true" />
|
styleClass="wizardButton" disabled="true" />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
Reference in New Issue
Block a user