From a215c4c0a6c41806ec2e1fa464556be24f3c71f8 Mon Sep 17 00:00:00 2001 From: Kevin Roast Date: Thu, 27 Sep 2007 11:12:22 +0000 Subject: [PATCH] =?UTF-8?q?Category=20browsing=20shelf=20component=20and?= =?UTF-8?q?=20view=20-=20contribution=20from=20Jean-Luc=20Visel=C3=A9=20(A?= =?UTF-8?q?tol=20Conseils=20et=20D=C3=A9veloppements)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6871 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261 --- config/alfresco/messages/webclient.properties | 9 + config/alfresco/web-client-config.xml | 3 + .../org/alfresco/web/bean/BrowseBean.java | 15 +- .../web/bean/CategoryBrowserBean.java | 82 ++++ .../bean/ajax/CategoryBrowserPluginBean.java | 327 +++++++++++++ .../ui/repo/component/UICategoryBrowser.java | 253 ++++++++++ .../web/ui/repo/tag/CategoryBrowserTag.java | 62 +++ source/web/WEB-INF/faces-config-beans.xml | 24 + .../web/WEB-INF/faces-config-navigation.xml | 9 + source/web/WEB-INF/faces-config-repo.xml | 6 + source/web/WEB-INF/repo.tld | 18 + source/web/jsp/browse/category-browse.jsp | 460 ++++++++++++++++++ source/web/jsp/sidebar/category-browser.jsp | 30 ++ 13 files changed, 1295 insertions(+), 3 deletions(-) create mode 100644 source/java/org/alfresco/web/bean/CategoryBrowserBean.java create mode 100644 source/java/org/alfresco/web/bean/ajax/CategoryBrowserPluginBean.java create mode 100644 source/java/org/alfresco/web/ui/repo/component/UICategoryBrowser.java create mode 100644 source/java/org/alfresco/web/ui/repo/tag/CategoryBrowserTag.java create mode 100644 source/web/jsp/browse/category-browse.jsp create mode 100644 source/web/jsp/sidebar/category-browser.jsp diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index c5a8a9df79..81d2dd0502 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -1776,3 +1776,12 @@ click_to_edit=click to edit # File Picker go_up=Go up + +#Category browsing +category_browser_plugin_label=Categories +category_browser_plugin_description=Category Browsing +category_browser_plugin_include_subcategories=Browse items in sub-categories? +category_browser_browse_title=Category \"{0}\" +category_browser_browse_include=and its sub-categories +category_browser_browse_description=This view allows you to see all items in this category +title_category_browse=Alfresco Web Client - Category Browsing diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index f4f5dbd24a..3da96d2f9f 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -267,6 +267,9 @@ page="/jsp/sidebar/shelf.jsp" /> + diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java index f87bc8c291..8ae8ff1f47 100644 --- a/source/java/org/alfresco/web/bean/BrowseBean.java +++ b/source/java/org/alfresco/web/bean/BrowseBean.java @@ -698,8 +698,16 @@ public class BrowseBean implements IContextListener // setup dispatch context for custom views this.navigator.setupDispatchContext(this.navigator.getCurrentNode()); - - navigateBrowseScreen(); + + // browse to appropriate view + FacesContext fc = FacesContext.getCurrentInstance(); + String outcome = null; + String viewId = fc.getViewRoot().getViewId(); + if (viewId.equals(BROWSE_VIEW_ID) == false && viewId.equals(CATEGORY_VIEW_ID) == false) + { + outcome = "browse"; + } + fc.getApplication().getNavigationHandler().handleNavigation(fc, null, outcome); } else { @@ -1964,7 +1972,8 @@ public class BrowseBean implements IContextListener // Private data /** Browse screen view ID */ - public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp"; + public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp"; + public static final String CATEGORY_VIEW_ID = "/jsp/browse/category-browse.jsp"; /** Small icon default name */ public static final String SPACE_SMALL_DEFAULT = "space_small"; diff --git a/source/java/org/alfresco/web/bean/CategoryBrowserBean.java b/source/java/org/alfresco/web/bean/CategoryBrowserBean.java new file mode 100644 index 0000000000..f3db44178d --- /dev/null +++ b/source/java/org/alfresco/web/bean/CategoryBrowserBean.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.web.bean; + +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; + +public class CategoryBrowserBean +{ + public static String BEAN_NAME = "CategoryBrowserBean"; + + private NodeService nodeService; + + private NodeRef currentCategory = null; + + private boolean includeSubcategories = false; + + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public void setCurrentCategory(NodeRef currentCategory) + { + this.currentCategory = currentCategory; + } + + public String getCurrentCategoryName() + { + String currentCategoryName = null; + if (currentCategory != null) + currentCategoryName = (String) this.nodeService.getProperty(currentCategory, ContentModel.PROP_NAME); + + return currentCategoryName; + } + + public boolean isIncludeSubcategories() + { + return includeSubcategories; + } + + public void setIncludeSubcategories(boolean includeSubcategories) + { + this.includeSubcategories = includeSubcategories; + } + + public SearchContext generateCategorySearchContext() + { + SearchContext categorySearch = new SearchContext(); + + String[] categories = new String[1]; + categories[0] = SearchContext.getPathFromSpaceRef(currentCategory, includeSubcategories); + + categorySearch.setText(""); + categorySearch.setCategories(categories); + + return categorySearch; + } +} diff --git a/source/java/org/alfresco/web/bean/ajax/CategoryBrowserPluginBean.java b/source/java/org/alfresco/web/bean/ajax/CategoryBrowserPluginBean.java new file mode 100644 index 0000000000..b0c8caf377 --- /dev/null +++ b/source/java/org/alfresco/web/bean/ajax/CategoryBrowserPluginBean.java @@ -0,0 +1,327 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.web.bean.ajax; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.transaction.UserTransaction; + +import org.alfresco.model.ApplicationModel; +import org.alfresco.model.ContentModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.cmr.repository.NodeService; +import org.alfresco.service.cmr.search.CategoryService; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.data.IDataContainer; +import org.alfresco.web.data.QuickSort; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.repo.component.UITree.TreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class CategoryBrowserPluginBean +{ + public static final String BEAN_NAME = "CategoryBrowserPluginBean"; + + private static final Log logger = LogFactory.getLog(CategoryBrowserPluginBean.class); + + private CategoryService categoryService; + + private NodeService nodeService; + + private List categoryRootNodes; + + private Map categoryNodes; + + protected NodeRef previouslySelectedNode; + + /** + * @param categoryService + * the categoryService to set + */ + public void setCategoryService(CategoryService categoryService) + { + this.categoryService = categoryService; + } + + /** + * @param nodeService + * the nodeService to set + */ + public void setNodeService(NodeService nodeService) + { + this.nodeService = nodeService; + } + + public List getCategoryRootNodes() + { + if (this.categoryRootNodes == null) + { + this.categoryRootNodes = new ArrayList(); + this.categoryNodes = new HashMap(); + + UserTransaction tx = null; + try + { + tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true); + tx.begin(); + + Collection childRefs = this.categoryService.getRootCategories( + Repository.getStoreRef(), ContentModel.ASPECT_GEN_CLASSIFIABLE); + + for (ChildAssociationRef ref : childRefs) + { + NodeRef child = ref.getChildRef(); + TreeNode node = createTreeNode(child); + this.categoryRootNodes.add(node); + this.categoryNodes.put(node.getNodeRef(), node); + } + + tx.commit(); + } + catch (Throwable err) + { + Utils.addErrorMessage("NavigatorPluginBean exception in getCompanyHomeRootNodes()", err); + try + { + if (tx != null) + { + tx.rollback(); + } + } + catch (Exception tex) + { + } + } + } + + return this.categoryRootNodes; + } + + protected Map getNodesMap() + { + return this.categoryNodes; + } + + /** + * Retrieves the child folders for the noderef given in the 'noderef' parameter and caches the nodes against the area + * in the 'area' parameter. + */ + public void retrieveChildren() throws IOException + { + FacesContext context = FacesContext.getCurrentInstance(); + ResponseWriter out = context.getResponseWriter(); + + UserTransaction tx = null; + try + { + tx = Repository.getUserTransaction(context, true); + tx.begin(); + + Map params = context.getExternalContext().getRequestParameterMap(); + String nodeRefStr = (String) params.get("nodeRef"); + + // work out which list to cache the nodes in + Map currentNodes = getNodesMap(); + + if (nodeRefStr != null && currentNodes != null) + { + // get the given node's details + NodeRef parentNodeRef = new NodeRef(nodeRefStr); + TreeNode parentNode = currentNodes.get(parentNodeRef.toString()); + parentNode.setExpanded(true); + + if (logger.isDebugEnabled()) + logger.debug("retrieving children for noderef: " + parentNodeRef); + + // remove any existing children as the latest ones will be added + // below + parentNode.removeChildren(); + + // get all the child folder objects for the parent + List childRefs = this.nodeService.getChildAssocs(parentNodeRef, + ContentModel.ASSOC_SUBCATEGORIES, RegexQNamePattern.MATCH_ALL); + List sortedNodes = new ArrayList(); + for (ChildAssociationRef ref : childRefs) + { + NodeRef nodeRef = ref.getChildRef(); + logger.debug("retrieving child : " + nodeRef); + // build the XML representation of the child node + TreeNode childNode = createTreeNode(nodeRef); + parentNode.addChild(childNode); + currentNodes.put(childNode.getNodeRef(), childNode); + sortedNodes.add(childNode); + } + + // order the tree nodes by the tree label + if (sortedNodes.size() > 1) + { + QuickSort sorter = new QuickSort(sortedNodes, "name", true, IDataContainer.SORT_CASEINSENSITIVE); + sorter.sort(); + } + + // generate the XML representation + StringBuilder xml = new StringBuilder( + ""); + for (TreeNode childNode : sortedNodes) + { + xml.append(childNode.toXML()); + } + xml.append(""); + + // send the generated XML back to the tree + out.write(xml.toString()); + + if (logger.isDebugEnabled()) + logger.debug("returning XML: " + xml.toString()); + } + + // commit the transaction + tx.commit(); + } + catch (Throwable err) + { + try + { + if (tx != null) + { + tx.rollback(); + } + } + catch (Exception tex) + { + } + } + } + + /** + * Sets the state of the node given in the 'nodeRef' parameter to collapsed + */ + public void nodeCollapsed() throws IOException + { + FacesContext context = FacesContext.getCurrentInstance(); + ResponseWriter out = context.getResponseWriter(); + Map params = context.getExternalContext().getRequestParameterMap(); + String nodeRefStr = (String) params.get("nodeRef"); + + // work out which list to cache the nodes in + Map currentNodes = getNodesMap(); + + if (nodeRefStr != null && currentNodes != null) + { + TreeNode treeNode = currentNodes.get(nodeRefStr); + if (treeNode != null) + { + treeNode.setExpanded(false); + + // we need to return something for the client to be happy! + out.write(""); + + if (logger.isDebugEnabled()) + logger.debug("Set node " + treeNode + " to collapsed state"); + } + } + } + + public void selectNode(NodeRef selectedNode, String area) + { + // if there is a currently selected node, get hold of + // it (from any of the areas) and reset to unselected + if (this.previouslySelectedNode != null) + { + TreeNode node = this.categoryNodes.get(this.previouslySelectedNode.toString()); + if (node != null) + { + node.setSelected(false); + } + } + + // find the node just selected and set its state to selected + if (selectedNode != null) + { + TreeNode node = this.categoryNodes.get(selectedNode.toString()); + if (node != null) + { + node.setSelected(true); + } + } + + this.previouslySelectedNode = selectedNode; + + if (logger.isDebugEnabled()) + logger.debug("Selected node: " + selectedNode); + } + + /** + * Resets the selected node + */ + public void resetSelectedNode() + { + if (this.previouslySelectedNode != null) + { + TreeNode node = this.categoryNodes.get(this.previouslySelectedNode.toString()); + if (node != null) + { + node.setSelected(false); + } + } + if (logger.isDebugEnabled()) + logger.debug("Reset selected node: " + this.previouslySelectedNode); + } + + /** + * Resets all the caches held by the bean. + */ + public void reset() + { + this.categoryNodes = null; + this.categoryRootNodes = null; + + resetSelectedNode(); + } + + /** + * Creates a TreeNode object from the given NodeRef + * + * @param nodeRef + * The NodeRef to create the TreeNode from + */ + protected TreeNode createTreeNode(NodeRef nodeRef) + { + TreeNode node = new TreeNode(nodeRef.toString(), Repository.getNameForNode(this.nodeService, nodeRef), + (String) this.nodeService.getProperty(nodeRef, ApplicationModel.PROP_ICON)); + + return node; + } +} diff --git a/source/java/org/alfresco/web/ui/repo/component/UICategoryBrowser.java b/source/java/org/alfresco/web/ui/repo/component/UICategoryBrowser.java new file mode 100644 index 0000000000..f0dd3308bf --- /dev/null +++ b/source/java/org/alfresco/web/ui/repo/component/UICategoryBrowser.java @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.web.ui.repo.component; + +import java.io.IOException; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.faces.component.UIComponent; +import javax.faces.context.FacesContext; +import javax.faces.context.ResponseWriter; +import javax.faces.event.AbortProcessingException; +import javax.faces.event.ActionEvent; +import javax.faces.event.FacesEvent; + +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.web.app.Application; +import org.alfresco.web.app.servlet.FacesHelper; +import org.alfresco.web.bean.CategoryBrowserBean; +import org.alfresco.web.bean.NavigationBean; +import org.alfresco.web.bean.SearchContext; +import org.alfresco.web.bean.ajax.CategoryBrowserPluginBean; +import org.alfresco.web.data.IDataContainer; +import org.alfresco.web.data.QuickSort; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.SelfRenderingComponent; +import org.alfresco.web.ui.repo.component.UITree.TreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class UICategoryBrowser extends SelfRenderingComponent +{ + private static final Log logger = LogFactory.getLog(UICategoryBrowser.class); + + public static final String COMPONENT_TYPE = "org.alfresco.faces.CategoryBrowser"; + + private static final String AJAX_URL_START = "/ajax/invoke/" + CategoryBrowserPluginBean.BEAN_NAME; + + private static final String SUBCATEGORIES_PARAM = "include-subcategories-checkbox"; + + @Override + public String getFamily() + { + return COMPONENT_TYPE; + } + + @Override + public void restoreState(FacesContext context, Object state) + { + Object values[] = (Object[]) state; + // standard component attributes are restored by the super class + super.restoreState(context, values[0]); + } + + @Override + public Object saveState(FacesContext context) + { + Object values[] = new Object[2]; + // standard component attributes are saved by the super class + values[0] = super.saveState(context); + return values; + } + + /** + * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext) + */ + public void decode(FacesContext context) + { + Map requestMap = context.getExternalContext().getRequestParameterMap(); + String fieldId = getClientId(context); + String value = (String) requestMap.get(fieldId); + + if (value != null && value.length() != 0) + { + if (logger.isDebugEnabled()) + logger.debug("Received post back: " + value); + + // work out whether a panel or a node was selected + String item = value; + + String subcategoriesStr = (String) requestMap.get(SUBCATEGORIES_PARAM); + boolean includeSubcategories = "1".equals(subcategoriesStr); + logger.debug("Booléen = " + includeSubcategories); + + // queue an event to be handled later + CategoryBrowserEvent event = new CategoryBrowserEvent(this, item, includeSubcategories); + this.queueEvent(event); + } + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.extension.web.ui.repo.component.UINavigator#broadcast(javax.faces.event.FacesEvent) + */ + @Override + public void broadcast(FacesEvent event) throws AbortProcessingException + { + if (event instanceof CategoryBrowserEvent) + { + FacesContext context = FacesContext.getCurrentInstance(); + CategoryBrowserEvent categoryBrowseEvent = (CategoryBrowserEvent) event; + NodeRef nodeClicked = new NodeRef(categoryBrowseEvent.getItem()); + boolean subcategories = categoryBrowseEvent.isIncludeSubcategories(); + if (logger.isDebugEnabled()) + logger.debug("Selected category: " + nodeClicked + " subcategories? " + subcategories); + + CategoryBrowserBean categoryBrowserBean = (CategoryBrowserBean) FacesHelper.getManagedBean(context, + CategoryBrowserBean.BEAN_NAME); + categoryBrowserBean.setCurrentCategory(nodeClicked); + categoryBrowserBean.setIncludeSubcategories(subcategories); + SearchContext categorySearch = categoryBrowserBean.generateCategorySearchContext(); + + NavigationBean nb = (NavigationBean) FacesHelper.getManagedBean(context, NavigationBean.BEAN_NAME); + nb.setSearchContext(categorySearch); + context.getApplication().getNavigationHandler().handleNavigation(context, null, "category-browse"); + } + else + { + super.broadcast(event); + } + } + + /* + * (non-Javadoc) + * + * @see org.alfresco.web.ui.repo.component.UINavigator#encodeBegin(javax.faces.context.FacesContext) + */ + @Override + public void encodeBegin(FacesContext context) throws IOException + { + if (!isRendered()) + return; + + // TODO: pull width and height from user preferences and/or the main config, + // if present override below using the style attribute + + ResponseWriter out = context.getResponseWriter(); + CategoryBrowserPluginBean categoryBrowserPluginBean = (CategoryBrowserPluginBean) FacesHelper.getManagedBean( + context, CategoryBrowserPluginBean.BEAN_NAME); + CategoryBrowserBean categoryBrowserBean = (CategoryBrowserBean) FacesHelper.getManagedBean(context, + CategoryBrowserBean.BEAN_NAME); + + List rootNodes = null; + + rootNodes = categoryBrowserPluginBean.getCategoryRootNodes(); + // order the root nodes by the tree label + if (rootNodes != null && rootNodes.size() > 1) + { + QuickSort sorter = new QuickSort(rootNodes, "name", true, IDataContainer.SORT_CASEINSENSITIVE); + sorter.sort(); + } + + // main container div + out.write("
"); + + // Subcategories parameter + String includeSub = Application.getMessage(context, "category_browser_plugin_include_subcategories"); + out.write(""); + out.write(""); + + // generate the javascript method to capture the tree node click events + out.write(""); + + // generate the active panel containing the tree + out.write("
"); + UITree tree = (UITree) context.getApplication().createComponent(UITree.COMPONENT_TYPE); + tree.setId("tree"); + tree.setRootNodes(rootNodes); + tree.setRetrieveChildrenUrl(AJAX_URL_START + ".retrieveChildren?"); + tree.setNodeCollapsedUrl(AJAX_URL_START + ".nodeCollapsed?"); + tree.setNodeSelectedCallback("treeNodeSelected"); + tree.setNodeCollapsedCallback("informOfCollapse"); + Utils.encodeRecursive(context, tree); + out.write("
"); + + out.write("
"); + } + + @Override + public void encodeChildren(FacesContext context) throws IOException + { + if (!isRendered()) + return; + for (Iterator i = this.getChildren().iterator(); i.hasNext();) + { + UIComponent child = (UIComponent) i.next(); + Utils.encodeRecursive(context, child); + } + } + + @Override + public boolean getRendersChildren() + { + return true; + } + + /** + * Class representing the clicking of a tree node. + */ + @SuppressWarnings("serial") + public static class CategoryBrowserEvent extends ActionEvent + { + private String item; + + private boolean includeSubcategories; + + public CategoryBrowserEvent(UIComponent component, String item, boolean include) + { + super(component); + + this.item = item; + this.includeSubcategories = include; + } + + public String getItem() + { + return item; + } + + public boolean isIncludeSubcategories() + { + return includeSubcategories; + } + } +} diff --git a/source/java/org/alfresco/web/ui/repo/tag/CategoryBrowserTag.java b/source/java/org/alfresco/web/ui/repo/tag/CategoryBrowserTag.java new file mode 100644 index 0000000000..68b269deee --- /dev/null +++ b/source/java/org/alfresco/web/ui/repo/tag/CategoryBrowserTag.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005-2007 Alfresco Software Limited. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing + */ +package org.alfresco.web.ui.repo.tag; + +import javax.faces.component.UIComponent; + +import org.alfresco.web.ui.common.tag.HtmlComponentTag; + +public class CategoryBrowserTag extends HtmlComponentTag +{ + /** + * @see javax.faces.webapp.UIComponentTag#getRendererType() + */ + public String getRendererType() + { + return null; + } + + /** + * @see javax.faces.webapp.UIComponentTag#setProperties(javax.faces.component.UIComponent) + */ + protected void setProperties(UIComponent component) + { + super.setProperties(component); + } + + /** + * @see org.alfresco.web.ui.common.tag.HtmlComponentTag#release() + */ + public void release() + { + super.release(); + } + + @Override + public String getComponentType() + { + return "org.alfresco.faces.CategoryBrowser"; + } +} diff --git a/source/web/WEB-INF/faces-config-beans.xml b/source/web/WEB-INF/faces-config-beans.xml index d66e237e3c..1971d04fc1 100644 --- a/source/web/WEB-INF/faces-config-beans.xml +++ b/source/web/WEB-INF/faces-config-beans.xml @@ -5014,4 +5014,28 @@ + + CategoryBrowserPluginBean + org.alfresco.web.bean.ajax.CategoryBrowserPluginBean + session + + nodeService + #{NodeService} + + + categoryService + #{CategoryService} + + + + + CategoryBrowserBean + org.alfresco.web.bean.CategoryBrowserBean + session + + nodeService + #{NodeService} + + + diff --git a/source/web/WEB-INF/faces-config-navigation.xml b/source/web/WEB-INF/faces-config-navigation.xml index 58789f557f..4ba3d88e82 100644 --- a/source/web/WEB-INF/faces-config-navigation.xml +++ b/source/web/WEB-INF/faces-config-navigation.xml @@ -930,4 +930,13 @@ + + + /jsp/* + + category-browse + /jsp/browse/category-browse.jsp + + + diff --git a/source/web/WEB-INF/faces-config-repo.xml b/source/web/WEB-INF/faces-config-repo.xml index 958c8105c0..6b44845152 100644 --- a/source/web/WEB-INF/faces-config-repo.xml +++ b/source/web/WEB-INF/faces-config-repo.xml @@ -203,6 +203,12 @@ org.alfresco.faces.WebScript org.alfresco.web.scripts.jsf.UIWebScript + + + org.alfresco.faces.CategoryBrowser + org.alfresco.web.ui.repo.component.UICategoryBrowser + + diff --git a/source/web/WEB-INF/repo.tld b/source/web/WEB-INF/repo.tld index eb5bbee94f..69a3900ec2 100644 --- a/source/web/WEB-INF/repo.tld +++ b/source/web/WEB-INF/repo.tld @@ -2168,4 +2168,22 @@ + + categoryBrowser + org.alfresco.web.ui.repo.tag.CategoryBrowserTag + JSP + + + id + false + true + + + + rendered + false + true + + + diff --git a/source/web/jsp/browse/category-browse.jsp b/source/web/jsp/browse/category-browse.jsp new file mode 100644 index 0000000000..b7a7ed14cc --- /dev/null +++ b/source/web/jsp/browse/category-browse.jsp @@ -0,0 +1,460 @@ +<%-- + * Copyright (C) 2005-2007 Alfresco Software Limited. + + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" +--%> +<%@ page import="org.alfresco.web.app.Application" %> +<%@ page import="javax.faces.context.FacesContext" %> + +<%@ 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="100kb" contentType="text/html;charset=UTF-8" %> +<%@ page isELIgnored="false" %> + + + + + + +<% +FacesContext fc = FacesContext.getCurrentInstance(); + +// set locale for JSF framework usage +fc.getViewRoot().setLocale(Application.getLanguage(fc)); +%> + +<%-- load a bundle of properties with I18N strings --%> + + + + + <%-- Main outer table --%> + + + <%-- Title bar --%> + + + + + <%-- Main area --%> + + <%-- Shelf --%> + + + <%-- Work Area --%> + + +
+ <%@ include file="../parts/titlebar.jsp" %> +
+ <%@ include file="../parts/shelf.jsp" %> + + + <%-- Breadcrumb --%> + <%@ include file="../parts/breadcrumb.jsp" %> + + <%-- Status and Actions --%> + + + + + + + <%-- separator row with gradient shadow --%> + + + + + + + <%-- Custom Template View --%> + + + + + + + + + <%-- Details - Spaces --%> + + + + + + + <%-- Details - Content --%> + + + + + + + <%-- Error Messages --%> + + + + + + + <%-- separator row with bottom panel graphics --%> + + + + + + +
+ + <%-- Status and Actions inner contents table --%> + <%-- Generally this consists of an icon, textual summary and actions for the current object --%> + + + <%-- actions --%> + + + + + + + + +
+ + + <%-- Summary --%> +
+
+
+ <%-- View mode settings --%> + + + + + +
+ +
+ + + + +
+ + <%-- wrapper comment used by the panel to add additional component facets --%> + + + + + +
+
+
+
+ + + <%-- Spaces List --%> + + + <%-- Primary column for details view mode --%> + + + + + + + + + + + + + + + + + + <%-- Primary column for icons view mode --%> + + + + + + + + + + + + + + + <%-- Primary column for list view mode --%> + + + + + + + + + + + + + + + <%-- Description column for all view modes --%> + + + + + + + + <%-- Path column for search mode in details view mode --%> + + + + + + + + <%-- Created Date column for details view mode --%> + + + + + + + + + + <%-- Modified Date column for details/icons view modes --%> + + + + + + + + + + <%-- Node Descendants links for list view mode --%> + + + + + <%-- Space Actions column --%> + + + + + + <%-- actions are configured in web-client-config-actions.xml --%> + + + <%-- More actions menu --%> + + + + + + + + + + +
+ + + + + + +
+
+
+
+ + + <%-- Content list --%> + + + <%-- Primary column for details view mode --%> + + + + + + + + + + + + + + + + <%-- Primary column for icons view mode --%> + + + + + + + + + + + + + <%-- Primary column for list view mode --%> + + + + + + + + + + + + + <%-- Description column for all view modes --%> + + + + + + + + <%-- Path column for search mode in details view mode --%> + + + + + + + + <%-- Size for details/icons view modes --%> + + + + + + + + + + <%-- Created Date column for details view mode --%> + + + + + + + + + + <%-- Modified Date column for details/icons view modes --%> + + + + + + + + + + <%-- Content Actions column --%> + + + + + + <%-- actions are configured in web-client-config-actions.xml --%> + + + <%-- More actions menu --%> + + + + + + + + + + +
+ <%-- messages tag to show messages not handled by other specific message tags --%> + +
+
+ +
+ +
+ +
\ No newline at end of file diff --git a/source/web/jsp/sidebar/category-browser.jsp b/source/web/jsp/sidebar/category-browser.jsp new file mode 100644 index 0000000000..727592fcdf --- /dev/null +++ b/source/web/jsp/sidebar/category-browser.jsp @@ -0,0 +1,30 @@ +<%-- + * Copyright (C) 2005-2007 Alfresco Software Limited. + + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + * As a special exception to the terms and conditions of version 2.0 of + * the GPL, you may redistribute this Program in connection with Free/Libre + * and Open Source Software ("FLOSS") applications as described in Alfresco's + * FLOSS exception. You should have recieved a copy of the text describing + * the FLOSS exception, and it is also available here: + * http://www.alfresco.com/legal/licensing" +--%> +<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> +<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> +<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %> +<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %> + + \ No newline at end of file