diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties index 191c20d171..934e9f28f3 100644 --- a/config/alfresco/messages/webclient.properties +++ b/config/alfresco/messages/webclient.properties @@ -319,6 +319,9 @@ edit_forum_description=Modify the forum properties then click OK. edit_topic_description=Modify the topic properties then click OK. edit_post_description=Modify the message then click OK. edit_post_finish=To save the message click Post. +start_discussion=Start Discussion +discuss=Discuss +discussion_for={0} discussion # Common Wizard messages steps=Steps @@ -828,6 +831,7 @@ title_create_forum=Create Forum title_forums_details=Forum Space Details title_forum_details=Forum Details title_create_topic=Create Topic +title_create_discussion=Create Discussion title_topic_details=Topic Details title_create_post=Post Message title_create_reply=Create Reply diff --git a/config/alfresco/web-client-config-icons.xml b/config/alfresco/web-client-config-icons.xml index 98da12e776..88e4f13ae5 100644 --- a/config/alfresco/web-client-config-icons.xml +++ b/config/alfresco/web-client-config-icons.xml @@ -33,6 +33,8 @@ + + diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml index 7cffe13ad9..8d20c3aa13 100644 --- a/config/alfresco/web-client-config.xml +++ b/config/alfresco/web-client-config.xml @@ -153,7 +153,6 @@ - @@ -167,7 +166,6 @@ - @@ -325,7 +323,7 @@ - + diff --git a/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java b/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java index 26d1b6e81e..84fe5144f4 100644 --- a/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java +++ b/source/java/org/alfresco/web/app/AlfrescoNavigationHandler.java @@ -17,6 +17,8 @@ */ package org.alfresco.web.app; +import java.util.Stack; + import javax.faces.application.NavigationHandler; import javax.faces.application.ViewHandler; import javax.faces.component.UIViewRoot; @@ -38,7 +40,12 @@ import org.springframework.web.jsf.FacesContextUtils; */ public class AlfrescoNavigationHandler extends NavigationHandler { + public final static String DIALOG_SEPARATOR = ":"; + public final static String DIALOG_PREXIX = "dialog" + DIALOG_SEPARATOR; + public final static String CLOSE_DIALOG_OUTCOME = DIALOG_PREXIX + "close"; + private final static Log logger = LogFactory.getLog(AlfrescoNavigationHandler.class); + private final static String VIEW_STACK = "_alfViewStack"; // The original navigation handler private NavigationHandler origHandler; @@ -58,102 +65,228 @@ public class AlfrescoNavigationHandler extends NavigationHandler * @see javax.faces.application.NavigationHandler#handleNavigation(javax.faces.context.FacesContext, java.lang.String, java.lang.String) */ @Override + @SuppressWarnings("unchecked") public void handleNavigation(FacesContext context, String fromAction, String outcome) { if (logger.isDebugEnabled()) logger.debug("handleNavigation (fromAction=" + fromAction + ", outcome=" + outcome + ")"); boolean useOriginalNavHandler = true; - String finalOutcome = outcome; + boolean closingDialog = false; String viewId = context.getViewRoot().getViewId(); if (logger.isDebugEnabled()) logger.debug("Current view id: " + viewId); - NavigationBean navBean = (NavigationBean)context.getExternalContext(). - getSessionMap().get("NavigationBean"); - - // only continue if we have some dispatching context - if (navBean != null && navBean.getDispatchContextNode() != null) + // determine if we are dealing with a dialog + if (outcome != null && outcome.startsWith(DIALOG_PREXIX)) { - Node node = navBean.getDispatchContextNode(); - - if (logger.isDebugEnabled()) - logger.debug("Found node in dispatch context: " + node); + // determine whether it's being closed or opened + closingDialog = outcome.startsWith(CLOSE_DIALOG_OUTCOME); + + // remove the dialog prefix + outcome = outcome.substring(DIALOG_PREXIX.length()); - // see if there is any navigation config for the node type - ConfigService configSvc = (ConfigService)FacesContextUtils.getRequiredWebApplicationContext( - context).getBean(Application.BEAN_CONFIG_SERVICE); - - Config nodeConfig = configSvc.getConfig(node); - NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig. - getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION); - - if (navigationCfg != null) + if (closingDialog) { - // see if there is config for the current view state - NavigationResult navResult = navigationCfg.getOverride(viewId, outcome); - - if (navResult != null) + // if we are closing the dialog take the view off the + // top of the stack then decide whether to use the view + // or any overridden outcome that may be present + if (getViewStack(context).empty() == false) { - if (logger.isDebugEnabled()) - logger.debug("Found navigation config: " + navResult); - - if (navResult.isOutcome()) + String newViewId = (String)getViewStack(context).pop(); + + // is there an overiddent outcome? + int idx = outcome.indexOf(DIALOG_SEPARATOR); + if (idx == -1) { - finalOutcome = navResult.getResult(); + // there isn't an overidden outcome so go back to the previous view + if (logger.isDebugEnabled()) + logger.debug("Closing dialog, going back to view id: " + newViewId); + + goToView(context, newViewId); } else { - String newViewId = navResult.getResult(); + // there is an overidden outcome so extract it + outcome = outcome.substring(idx+1, outcome.length()); + + if (logger.isDebugEnabled()) + logger.debug("Closing dialog with an overridden outcome of '" + outcome + "'"); - if (newViewId.equals(viewId) == false) + this.origHandler.handleNavigation(context, fromAction, outcome); + } + } + else + { + // we are trying to close a dialog when one hasn't been opened! + // log a warning and return a null outcome to stay on the same page + if (logger.isWarnEnabled()) + { + logger.warn("Attempting to close a dialog with an empty view stack, returning 'browse' outcome"); + } + + // TODO: change this back to returning null outcome as that + // will highlight any areas we have neglected to launch + // in a dilaog, for backwards compatibility for the short + // term return 'browse' outcome. + + this.origHandler.handleNavigation(context, fromAction, "browse"); + } + } + else + { + // if we are opening a dialog push the current view id + // on to the stack, but only if it is different than the + // current view at the top (you can't launch a dialog from + // the same page 2 times in a row!) + + // TODO: This wouldn't happen if we could be sure a dialog is + // ALWAYS exited properly, look into a way of ensuring + // dialogs get closed if a user navigates away from the page, + // would a PhaseListener help in any way?? + + if (getViewStack(context).empty() || + viewId.equals(getViewStack(context).peek()) == false) + { + getViewStack(context).push(viewId); + + if (logger.isDebugEnabled()) + logger.debug("Pushed current view to stack: " + viewId); + } + else + { + if (getViewStack(context).empty() == false && logger.isDebugEnabled()) + { + logger.debug("current view is already top the view stack!"); + } + } + } + + if (logger.isDebugEnabled()) + logger.debug("view stack: " + getViewStack(context)); + } + + if (closingDialog == false) + { + NavigationBean navBean = (NavigationBean)context.getExternalContext(). + getSessionMap().get("NavigationBean"); + + // only continue if we have some dispatching context + if (navBean != null && navBean.getDispatchContextNode() != null) + { + Node node = navBean.getDispatchContextNode(); + + if (logger.isDebugEnabled()) + logger.debug("Found node with type '" + node.getType().toString() + + "' in dispatch context"); + + // see if there is any navigation config for the node type + ConfigService configSvc = (ConfigService)FacesContextUtils.getRequiredWebApplicationContext( + context).getBean(Application.BEAN_CONFIG_SERVICE); + + Config nodeConfig = configSvc.getConfig(node); + NavigationConfigElement navigationCfg = (NavigationConfigElement)nodeConfig. + getConfigElement(NavigationElementReader.ELEMENT_NAVIGATION); + + if (navigationCfg != null) + { + // see if there is config for the current view state + NavigationResult navResult = navigationCfg.getOverride(viewId, outcome); + + if (navResult != null) + { + if (logger.isDebugEnabled()) + logger.debug("Found navigation config: " + navResult); + + if (navResult.isOutcome()) { - useOriginalNavHandler = false; - - if (logger.isDebugEnabled()) - logger.debug("Dispatching to new view id: " + newViewId); - - ViewHandler viewHandler = context.getApplication().getViewHandler(); - UIViewRoot viewRoot = viewHandler.createView(context, newViewId); - viewRoot.setViewId(newViewId); - context.setViewRoot(viewRoot); - context.renderResponse(); + outcome = navResult.getResult(); } else { - if (logger.isDebugEnabled()) - logger.debug("New view id is the same as the current one so setting outcome to null"); + String newViewId = navResult.getResult(); - finalOutcome = null; + if (newViewId.equals(viewId) == false) + { + useOriginalNavHandler = false; + + if (logger.isDebugEnabled()) + logger.debug("Dispatching to new view id: " + newViewId); + + goToView(context, newViewId); + } + else + { + if (logger.isDebugEnabled()) + logger.debug("New view id is the same as the current one so setting outcome to null"); + + outcome = null; + } } } + else if (logger.isDebugEnabled()) + { + logger.debug("No override configuration found for current view or outcome"); + } } else if (logger.isDebugEnabled()) { - logger.debug("No override configuration found for current view or outcome"); + logger.debug("No navigation configuration found for node"); } + + // reset the dispatch context + navBean.resetDispatchContext(); } else if (logger.isDebugEnabled()) { - logger.debug("No navigation configuration found for node"); + logger.debug("No dispatch context found"); } - // reset the dispatch context - navBean.resetDispatchContext(); - } - else if (logger.isDebugEnabled()) - { - logger.debug("No dispatch context found"); - } - - // do the appropriate navigation handling - if (useOriginalNavHandler) - { - if (logger.isDebugEnabled()) - logger.debug("Passing outcome '" + finalOutcome + "' to original navigation handler"); - - this.origHandler.handleNavigation(context, fromAction, finalOutcome); + // do the appropriate navigation handling + if (useOriginalNavHandler) + { + if (logger.isDebugEnabled()) + logger.debug("Passing outcome '" + outcome + "' to original navigation handler"); + + this.origHandler.handleNavigation(context, fromAction, outcome); + } } } + + /** + * Dispatches to the given view id + * + * @param context Faces context + * @param viewId The view id to go to + */ + private void goToView(FacesContext context, String viewId) + { + ViewHandler viewHandler = context.getApplication().getViewHandler(); + UIViewRoot viewRoot = viewHandler.createView(context, viewId); + viewRoot.setViewId(viewId); + context.setViewRoot(viewRoot); + context.renderResponse(); + } + + /** + * Returns the view stack for the current user. + * + * @param context FacesContext + * @return A Stack representing the views that have launched dialogs in + * the users session, will never be null + */ + @SuppressWarnings("unchecked") + private Stack getViewStack(FacesContext context) + { + Stack viewStack = (Stack)context.getExternalContext().getSessionMap().get(VIEW_STACK); + + if (viewStack == null) + { + viewStack = new Stack(); + context.getExternalContext().getSessionMap().put(VIEW_STACK, viewStack); + } + + return viewStack; + } } diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java index 5702004ec5..5597cfe59d 100644 --- a/source/java/org/alfresco/web/bean/BrowseBean.java +++ b/source/java/org/alfresco/web/bean/BrowseBean.java @@ -28,6 +28,7 @@ import javax.faces.event.ActionEvent; import javax.transaction.UserTransaction; import org.alfresco.model.ContentModel; +import org.alfresco.model.ForumModel; import org.alfresco.service.cmr.dictionary.DictionaryService; import org.alfresco.service.cmr.dictionary.TypeDefinition; import org.alfresco.service.cmr.lock.LockService; @@ -43,6 +44,8 @@ import org.alfresco.service.cmr.search.ResultSetRow; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; @@ -399,6 +402,7 @@ public class BrowseBean implements IContextListener node.addPropertyResolver("size", this.resolverSize); node.addPropertyResolver("cancelCheckOut", this.resolverCancelCheckOut); node.addPropertyResolver("checkIn", this.resolverCheckIn); + node.addPropertyResolver("beingDiscussed", this.resolverBeingDiscussed); node.addPropertyResolver("editLinkType", this.resolverEditLinkType); node.addPropertyResolver("webdavUrl", this.resolverWebdavUrl); node.addPropertyResolver("cifsPath", this.resolverCifsPath); @@ -490,9 +494,9 @@ public class BrowseBean implements IContextListener // build a NodeRef for the specified Id and our store parentRef = new NodeRef(Repository.getStoreRef(), parentNodeId); } - - // TODO: can we improve the Get here with an API call for children of a specific type? - List childRefs = this.nodeService.getChildAssocs(parentRef); + + List childRefs = this.nodeService.getChildAssocs(parentRef, + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); this.containerNodes = new ArrayList(childRefs.size()); this.contentNodes = new ArrayList(childRefs.size()); for (ChildAssociationRef ref: childRefs) @@ -517,6 +521,7 @@ public class BrowseBean implements IContextListener // create our Node representation MapNode node = new MapNode(nodeRef, this.nodeService, true); node.addPropertyResolver("icon", this.resolverSpaceIcon); + node.addPropertyResolver("beingDiscussed", this.resolverBeingDiscussed); this.containerNodes.add(node); } @@ -632,6 +637,7 @@ public class BrowseBean implements IContextListener node.addPropertyResolver("path", this.resolverPath); node.addPropertyResolver("displayPath", this.resolverDisplayPath); node.addPropertyResolver("icon", this.resolverSpaceIcon); + node.addPropertyResolver("beingDiscussed", this.resolverBeingDiscussed); this.containerNodes.add(node); } @@ -732,6 +738,12 @@ public class BrowseBean implements IContextListener } }; + public NodePropertyResolver resolverBeingDiscussed = new NodePropertyResolver() { + public Object get(Node node) { + return node.hasAspect(ForumModel.ASPECT_DISCUSSABLE); + } + }; + public NodePropertyResolver resolverDownload = new NodePropertyResolver() { public Object get(Node node) { return DownloadContentServlet.generateDownloadURL(node.getNodeRef(), node.getName()); @@ -865,9 +877,7 @@ public class BrowseBean implements IContextListener try { NodeRef ref = new NodeRef(Repository.getStoreRef(), id); - - // refresh UI based on node selection - updateUILocation(ref); + clickSpace(ref); } catch (InvalidNodeRefException refErr) { @@ -877,6 +887,17 @@ public class BrowseBean implements IContextListener } } + /** + * Action called when a folder space is clicked. + * + * @param nodeRef The node being clicked + */ + public void clickSpace(NodeRef nodeRef) + { + // refresh UI based on node selection + updateUILocation(nodeRef); + } + /** * Handler called when a path element is clicked - navigate to the appropriate Space */ diff --git a/source/java/org/alfresco/web/bean/ExportBean.java b/source/java/org/alfresco/web/bean/ExportBean.java index fce8cf56b0..d41b71a318 100644 --- a/source/java/org/alfresco/web/bean/ExportBean.java +++ b/source/java/org/alfresco/web/bean/ExportBean.java @@ -48,7 +48,7 @@ public class ExportBean private static final String ALL_SPACES = "all"; private static final String CURRENT_SPACE = "current"; - private static final String DEFAULT_OUTCOME = "browse"; + private static final String DEFAULT_OUTCOME = "dialog:close"; private static final String MSG_ERROR = "error_export"; diff --git a/source/java/org/alfresco/web/bean/ForumsBean.java b/source/java/org/alfresco/web/bean/ForumsBean.java index f7e6a9153d..724528061e 100644 --- a/source/java/org/alfresco/web/bean/ForumsBean.java +++ b/source/java/org/alfresco/web/bean/ForumsBean.java @@ -17,11 +17,15 @@ package org.alfresco.web.bean; import java.io.IOException; +import java.io.Writer; import java.text.MessageFormat; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; +import java.util.Date; import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; @@ -29,6 +33,7 @@ import javax.faces.context.ResponseWriter; import javax.faces.event.ActionEvent; import javax.transaction.UserTransaction; +import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.model.ContentModel; import org.alfresco.model.ForumModel; import org.alfresco.service.cmr.dictionary.DictionaryService; @@ -44,6 +49,8 @@ import org.alfresco.service.cmr.search.QueryParameterDefinition; import org.alfresco.service.cmr.search.SearchService; import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; +import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.app.context.IContextListener; import org.alfresco.web.app.context.UIContextService; @@ -53,6 +60,7 @@ import org.alfresco.web.bean.repository.NodePropertyResolver; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.config.ClientConfigElement; import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.UIActionLink; import org.alfresco.web.ui.common.component.UIModeList; import org.alfresco.web.ui.common.component.data.UIColumn; import org.alfresco.web.ui.common.component.data.UIRichList; @@ -428,8 +436,8 @@ public class ForumsBean implements IContextListener parentRef = new NodeRef(Repository.getStoreRef(), parentNodeId); } - // TODO: can we improve the Get here with an API call for children of a specific type? - List childRefs = this.nodeService.getChildAssocs(parentRef); + List childRefs = this.nodeService.getChildAssocs(parentRef, + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); this.forums = new ArrayList(childRefs.size()); this.topics = new ArrayList(childRefs.size()); this.posts = new ArrayList(childRefs.size()); @@ -596,6 +604,13 @@ public class ForumsBean implements IContextListener // push the view mode into the lists setForumsViewMode(viewMode); + + // get the default for the forum page + this.forumsPageSize = this.clientConfig.getDefaultPageSize(PAGE_NAME_FORUMS, + this.forumsViewMode); + + if (logger.isDebugEnabled()) + logger.debug("Set default forums page size to: " + this.forumsPageSize); } /** @@ -612,6 +627,13 @@ public class ForumsBean implements IContextListener // push the view mode into the lists setForumViewMode(viewMode); + + // get the default for the forum page + this.forumPageSize = this.clientConfig.getDefaultPageSize(PAGE_NAME_FORUM, + this.forumViewMode); + + if (logger.isDebugEnabled()) + logger.debug("Set default forum page size to: " + this.forumPageSize); } /** @@ -628,6 +650,137 @@ public class ForumsBean implements IContextListener // push the view mode into the lists setTopicViewMode(viewMode); + + // change the default page size if necessary + this.topicPageSize = this.clientConfig.getDefaultPageSize(PAGE_NAME_TOPIC, + this.topicViewMode); + + if (logger.isDebugEnabled()) + logger.debug("Set default topic page size to: " + this.topicPageSize); + } + + /** + * Event handler called when a user wants to view or participate + * in a discussion on an object + * + * @param event ActionEvent + */ + public void discuss(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String id = params.get("id"); + if (id == null || id.length() == 0) + { + throw new AlfrescoRuntimeException("discuss called without an id"); + } + + FacesContext context = FacesContext.getCurrentInstance(); + + NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), id); + + if (this.nodeService.hasAspect(nodeRef, ForumModel.ASPECT_DISCUSSABLE) == false) + { + throw new AlfrescoRuntimeException("discuss called for an object that does not have a discussion!"); + } + + // as the node has the discussable aspect there must be a discussions child assoc + List children = this.nodeService.getChildAssocs(nodeRef, + ForumModel.ASSOC_DISCUSSION, RegexQNamePattern.MATCH_ALL); + + // there should only be one child, retrieve it if there is + if (children.size() == 1) + { + NodeRef forumNodeRef = children.get(0).getChildRef(); + + // query for the number of topics there are + String repliesXPath = "./*[(subtypeOf('" + ForumModel.TYPE_TOPIC + "'))]"; + List topics = searchService.selectNodes(forumNodeRef, repliesXPath, + new QueryParameterDefinition[] {}, this.namespaceService, false); + if (topics.size() == 1) + { + // if the forum has only one topic go straight into the topic by + // setting the context and navigating to it + NodeRef topicNodeRef = topics.get(0); + this.browseBean.clickSpace(topicNodeRef); + context.getApplication().getNavigationHandler().handleNavigation(context, null, "showTopic"); + } + else + { + // if the forum has more than one topic we need to setup the context + // for the forum and navigate to the forum page + this.browseBean.clickSpace(forumNodeRef); + context.getApplication().getNavigationHandler().handleNavigation(context, null, "showForum"); + } + } + } + + /** + * Called when the user confirms they wish to delete a forum space + * + * @return The outcome + */ + public String deleteForumsOK() + { + String outcome = "browse"; + + // find out what the parent type of the node being deleted + Node node = this.browseBean.getActionSpace(); + ChildAssociationRef assoc = this.nodeService.getPrimaryParent(node.getNodeRef()); + if (assoc != null) + { + NodeRef parent = assoc.getParentRef(); + QName parentType = this.nodeService.getType(parent); + if (parentType.equals(ForumModel.TYPE_FORUMS)) + { + outcome = "forumsDeleted"; + } + } + + // call the generic handler + this.browseBean.deleteSpaceOK(); + + // return an overidden outcome which closes the dialog with an outcome + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.DIALOG_SEPARATOR + outcome; + } + + /** + * Called when the user confirms they wish to delete a forum space + * + * @return The outcome + */ + public String deleteForumOK() + { + this.browseBean.deleteSpaceOK(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.DIALOG_SEPARATOR + "forumDeleted"; + } + + /** + * Called when the user confirms they wish to delete a forum space + * + * @return The outcome + */ + public String deleteTopicOK() + { + this.browseBean.deleteSpaceOK(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME + + AlfrescoNavigationHandler.DIALOG_SEPARATOR + "topicDeleted"; + } + + /** + * Called when the user confirms they wish to delete a forum space + * + * @return The outcome + */ + public String deletePostOK() + { + this.browseBean.deleteFileOK(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } // ------------------------------------------------------------------------------ @@ -703,6 +856,25 @@ public class ForumsBean implements IContextListener } }; + /** + * Creates a file name for the message being posted + * + * @return The file name for the post + */ + public static String createPostFileName() + { + StringBuilder name = new StringBuilder("posted-"); + + // add a timestamp + SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy-hh:mm:ss"); + name.append(dateFormat.format(new Date())); + + // add the HTML file extension + name.append(".html"); + + return name.toString(); + } + // ------------------------------------------------------------------------------ // Private helpers @@ -839,6 +1011,124 @@ public class ForumsBean implements IContextListener out.write(""); } + /** + * Renders the top part of the bubble i.e. before the header + * + * @param out The writer to output to + * @param contextPath Context path of the application + * @param colour The colour of the bubble + * @param titleBgColour Background colour of the header area + */ + public static void renderBubbleTop(Writer out, String contextPath, + String colour, String titleBgColour) throws IOException + { + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write(""); + out.write("
"); + } + + /** + * Renders the middle part of the bubble i.e. after the header and before the body + * + * @param out The writer to output to + * @param contextPath Context path of the application + * @param colour The colour of the bubble + */ + public static void renderBubbleMiddle(Writer out, String contextPath, String colour) + throws IOException + { + out.write("
"); + } + + /** + * Renders the bottom part of the bubble i.e. after the body + * + * @param out The writer to output to + * @param contextPath Context path of the application + * @param colour The colour of the bubble + */ + public static void renderBubbleBottom(Writer out, String contextPath, String colour) + throws IOException + { + out.write("
"); + } + /** * Renders the new post speech bubble * @@ -852,13 +1142,22 @@ public class ForumsBean implements IContextListener private void renderNewPostBubble(FacesContext context, ResponseWriter out, Node node, UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) throws IOException { + String contextPath = context.getExternalContext().getRequestContextPath(); + String colour = "orange"; + out.write(""); out.write("

"); out.write((String)node.getProperties().get("creator")); out.write("
"); - renderBubble(context, out, "orange", "#FCC75E", primaryColumn, actionsColumn, columns); + + renderBubbleTop(out, contextPath, colour, "#FCC75E"); + renderHeaderContents(context, out, primaryColumn, actionsColumn, columns); + renderBubbleMiddle(out, contextPath, colour); + renderBodyContents(context, primaryColumn); + renderBubbleBottom(out, contextPath, colour); + out.write("
"); } @@ -875,48 +1174,28 @@ public class ForumsBean implements IContextListener private void renderReplyToBubble(FacesContext context, ResponseWriter out, Node node, UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) throws IOException { + String contextPath = context.getExternalContext().getRequestContextPath(); + String colour = "yellow"; + out.write(""); out.write("
"); - renderBubble(context, out, "yellow", "#FFF5A3", primaryColumn, actionsColumn, columns); + + renderBubbleTop(out, contextPath, colour, "#FFF5A3"); + renderHeaderContents(context, out, primaryColumn, actionsColumn, columns); + renderBubbleMiddle(out, contextPath, colour); + renderBodyContents(context, primaryColumn); + renderBubbleBottom(out, contextPath, colour); + out.write("
"); out.write((String)node.getProperties().get("creator")); out.write("
"); } - /** - * Renders the speech bubble - * - * @param context Faces context - * @param out The response writer - * @param colour The colour of the bubble - * @param titleBgColour The colour of the background of the title area (#rrggbb) - * @param primaryColumn The primary column containing the message content - * @param actionsColumn The actions column containing all the actions - * @param columns All configured columns - */ - private void renderBubble(FacesContext context, ResponseWriter out, - String colour, String titleBgColour, - UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) - throws IOException + private void renderHeaderContents(FacesContext context, ResponseWriter out, + UIColumn primaryColumn, UIColumn actionsColumn, UIColumn[] columns) throws IOException { - String contextPath = context.getExternalContext().getRequestContextPath(); - - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write("
"); - // render the header area with the configured columns out.write(""); @@ -948,73 +1227,28 @@ public class ForumsBean implements IContextListener } // render the actions column - out.write("
"); + out.write(""); if (actionsColumn != null && actionsColumn.getChildCount() != 0) { Utils.encodeRecursive(context, actionsColumn); } - out.write("
"); - - out.write("
"); - + out.write("
"); + } + + /** + * Renders the body contents for the bubble using the given primary coumn + * + * @param context Faces context + * @param primaryColumn The primary column holding the message text + */ + private void renderBodyContents(FacesContext context, UIColumn primaryColumn) + throws IOException + { // render the primary column if (primaryColumn != null && primaryColumn.getChildCount() != 0) { Utils.encodeRecursive(context, primaryColumn); } - - out.write(""); - - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); - out.write(""); } } } diff --git a/source/java/org/alfresco/web/bean/ImportBean.java b/source/java/org/alfresco/web/bean/ImportBean.java index abc3bd32b3..fd8252a9a9 100644 --- a/source/java/org/alfresco/web/bean/ImportBean.java +++ b/source/java/org/alfresco/web/bean/ImportBean.java @@ -53,7 +53,7 @@ public class ImportBean { private static final Log logger = LogFactory.getLog(ImportBean.class); - private static final String DEFAULT_OUTCOME = "browse"; + private static final String DEFAULT_OUTCOME = "dialog:close"; private static final String MSG_ERROR = "error_import"; private static final String MSG_ERROR_NO_FILE = "error_import_no_file"; diff --git a/source/java/org/alfresco/web/bean/SpaceDetailsBean.java b/source/java/org/alfresco/web/bean/SpaceDetailsBean.java index 7598615a40..4b960d46fe 100644 --- a/source/java/org/alfresco/web/bean/SpaceDetailsBean.java +++ b/source/java/org/alfresco/web/bean/SpaceDetailsBean.java @@ -34,6 +34,7 @@ import org.alfresco.service.cmr.repository.TemplateImageResolver; import org.alfresco.service.cmr.repository.TemplateNode; import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.namespace.NamespaceService; +import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; @@ -208,6 +209,7 @@ public class SpaceDetailsBean * * @return model containing current current space info. */ + @SuppressWarnings("unchecked") public Map getTemplateModel() { HashMap model = new HashMap(1, 1.0f); @@ -402,6 +404,6 @@ public class SpaceDetailsBean public String closeDialog() { this.navigator.resetCurrentNodeProperties(); - return "browse"; + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } } diff --git a/source/java/org/alfresco/web/bean/wizard/NewDiscussionWizard.java b/source/java/org/alfresco/web/bean/wizard/NewDiscussionWizard.java new file mode 100644 index 0000000000..2c3400369b --- /dev/null +++ b/source/java/org/alfresco/web/bean/wizard/NewDiscussionWizard.java @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2005 Alfresco, Inc. + * + * Licensed under the GNU Lesser General Public License as + * published by the Free Software Foundation; either version + * 2.1 of the License, or (at your option) any later version. + * You may obtain a copy of the License at + * + * http://www.gnu.org/licenses/lgpl.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.bean.wizard; + +import java.io.Serializable; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; + +import javax.faces.context.FacesContext; +import javax.faces.event.ActionEvent; +import javax.transaction.UserTransaction; + +import org.alfresco.error.AlfrescoRuntimeException; +import org.alfresco.model.ContentModel; +import org.alfresco.model.ForumModel; +import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.repository.NodeRef; +import org.alfresco.service.namespace.QName; +import org.alfresco.web.app.Application; +import org.alfresco.web.bean.repository.Repository; +import org.alfresco.web.ui.common.Utils; +import org.alfresco.web.ui.common.component.UIActionLink; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Backing bean class used to create discussions for documents + * + * @author gavinc + */ +public class NewDiscussionWizard extends NewTopicWizard +{ + private static final Log logger = LogFactory.getLog(NewDiscussionWizard.class); + + private NodeRef discussingNodeRef; + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#startWizard(javax.faces.event.ActionEvent) + */ + @Override + public void startWizard(ActionEvent event) + { + UIActionLink link = (UIActionLink)event.getComponent(); + Map params = link.getParameterMap(); + String id = params.get("id"); + if (id == null || id.length() == 0) + { + throw new AlfrescoRuntimeException("startDiscussion called without an id"); + } + + FacesContext context = FacesContext.getCurrentInstance(); + UserTransaction tx = null; + NodeRef forumNodeRef = null; + + try + { + tx = Repository.getUserTransaction(context); + tx.begin(); + + this.discussingNodeRef = new NodeRef(Repository.getStoreRef(), id); + + if (this.nodeService.hasAspect(this.discussingNodeRef, ForumModel.ASPECT_DISCUSSABLE)) + { + throw new AlfrescoRuntimeException("startDiscussion called for an object that already has a discussion!"); + } + + // add the discussable aspect + this.nodeService.addAspect(this.discussingNodeRef, ForumModel.ASPECT_DISCUSSABLE, null); + + // create a child forum space using the child association just introduced by + // adding the discussable aspect + String name = (String)this.nodeService.getProperty(this.discussingNodeRef, + ContentModel.PROP_NAME); + String msg = Application.getMessage(FacesContext.getCurrentInstance(), "discussion_for"); + String forumName = MessageFormat.format(msg, new Object[] {name}); + + Map forumProps = new HashMap(1); + forumProps.put(ContentModel.PROP_NAME, forumName); + ChildAssociationRef childRef = this.nodeService.createNode(this.discussingNodeRef, + ForumModel.ASSOC_DISCUSSION, + QName.createQName(ForumModel.FORUMS_MODEL_URI, "discussion"), + ForumModel.TYPE_FORUM, forumProps); + + forumNodeRef = childRef.getChildRef(); + + // apply the uifacets aspect + Map uiFacetsProps = new HashMap(5); + uiFacetsProps.put(ContentModel.PROP_ICON, "forum_large"); + this.nodeService.addAspect(forumNodeRef, ContentModel.ASPECT_UIFACETS, uiFacetsProps); + + if (logger.isDebugEnabled()) + logger.debug("created forum for content: " + forumNodeRef.toString()); + + // commit the transaction + tx.commit(); + } + catch (Exception e) + { + // rollback the transaction + try { if (tx != null) {tx.rollback();} } catch (Exception ex) {} + Utils.addErrorMessage(MessageFormat.format(Application.getMessage( + context, Repository.ERROR_GENERIC), e.getMessage()), e); + } + + // finally setup the context for the forum we just created + if (forumNodeRef != null) + { + this.browseBean.clickSpace(forumNodeRef); + + // now initialise the wizard and navigate to it + super.startWizard(event); + context.getApplication().getNavigationHandler().handleNavigation(context, null, "dialog:createDiscussion"); + } + } + +} diff --git a/source/java/org/alfresco/web/bean/wizard/NewForumWizard.java b/source/java/org/alfresco/web/bean/wizard/NewForumWizard.java index 66c596a86d..51a3b5e429 100644 --- a/source/java/org/alfresco/web/bean/wizard/NewForumWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/NewForumWizard.java @@ -17,12 +17,8 @@ */ package org.alfresco.web.bean.wizard; -import java.util.List; - -import javax.faces.context.FacesContext; - import org.alfresco.model.ForumModel; -import org.alfresco.web.ui.common.component.UIListItem; +import org.alfresco.web.app.AlfrescoNavigationHandler; /** * Wizard bean used for creating and editing forum spaces @@ -31,30 +27,6 @@ import org.alfresco.web.ui.common.component.UIListItem; */ public class NewForumWizard extends NewSpaceWizard { - protected String forumStatus; - - protected List forumIcons; - - /** - * Returns the status of the forum - * - * @return The status of the forum - */ - public String getForumStatus() - { - return this.forumStatus; - } - - /** - * Sets the status of the forum - * - * @param forumStatus The status - */ - public void setForumStatus(String forumStatus) - { - this.forumStatus = forumStatus; - } - /** * @see org.alfresco.web.bean.wizard.AbstractWizardBean#init() */ @@ -63,15 +35,27 @@ public class NewForumWizard extends NewSpaceWizard super.init(); this.spaceType = ForumModel.TYPE_FORUM.toString(); - this.forumStatus = "0"; + } + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#finish() + */ + @Override + public String finish() + { + super.finish(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } /** - * @see org.alfresco.web.bean.wizard.NewSpaceWizard#performCustomProcessing(javax.faces.context.FacesContext) + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#cancel() */ @Override - protected void performCustomProcessing(FacesContext context) + public String cancel() { - // add or update the ForumModel.PROP_STATUS property depending on the editMode + super.cancel(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } } diff --git a/source/java/org/alfresco/web/bean/wizard/NewForumsWizard.java b/source/java/org/alfresco/web/bean/wizard/NewForumsWizard.java index bf526c9ce6..8f8644d194 100644 --- a/source/java/org/alfresco/web/bean/wizard/NewForumsWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/NewForumsWizard.java @@ -17,10 +17,8 @@ */ package org.alfresco.web.bean.wizard; -import java.util.List; - import org.alfresco.model.ForumModel; -import org.alfresco.web.ui.common.component.UIListItem; +import org.alfresco.web.app.AlfrescoNavigationHandler; /** * Wizard bean used for creating and editing forums spaces @@ -29,8 +27,6 @@ import org.alfresco.web.ui.common.component.UIListItem; */ public class NewForumsWizard extends NewSpaceWizard { - protected List forumsIcons; - /** * @see org.alfresco.web.bean.wizard.AbstractWizardBean#init() */ @@ -40,4 +36,26 @@ public class NewForumsWizard extends NewSpaceWizard this.spaceType = ForumModel.TYPE_FORUMS.toString(); } + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#finish() + */ + @Override + public String finish() + { + super.finish(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#cancel() + */ + @Override + public String cancel() + { + super.cancel(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } } diff --git a/source/java/org/alfresco/web/bean/wizard/NewPostWizard.java b/source/java/org/alfresco/web/bean/wizard/NewPostWizard.java index 40b0e9e5df..5766e68210 100644 --- a/source/java/org/alfresco/web/bean/wizard/NewPostWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/NewPostWizard.java @@ -25,6 +25,8 @@ import org.alfresco.model.ForumModel; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.util.GUID; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.bean.ForumsBean; import org.alfresco.web.bean.repository.Node; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; @@ -56,7 +58,8 @@ public class NewPostWizard extends CreateContentWizard public void startWizardForEdit(ActionEvent event) { // TODO: Allow action link to have multiple action listeners - // then we wouldn't need to have this coupling in here + // then we wouldn't need to have this coupling back + // to the browse bean in here // we need to setup the content in the browse bean first this.browseBean.setupContentAction(event); @@ -101,17 +104,18 @@ public class NewPostWizard extends CreateContentWizard } else { - // create appropriate values for filename, title and content type - this.fileName = GUID.generate() + ".html"; + // create appropriate values for filename and content type + this.fileName = ForumsBean.createPostFileName(); this.contentType = Repository.getMimeTypeForFileName( FacesContext.getCurrentInstance(), this.fileName); - this.title = this.fileName; // remove link breaks and replace with
this.content = Utils.replaceLineBreaks(this.content); } - return super.finish(); + super.finish(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } /** @@ -120,16 +124,28 @@ public class NewPostWizard extends CreateContentWizard @Override protected void performCustomProcessing() { - // update the content - Node currentDocument = this.browseBean.getDocument(); - - ContentWriter writer = this.contentService.getWriter(currentDocument.getNodeRef(), - ContentModel.PROP_CONTENT, true); - if (writer != null) + if (this.editMode) { - writer.putContent(this.content); + // update the content + Node currentDocument = this.browseBean.getDocument(); + + ContentWriter writer = this.contentService.getWriter(currentDocument.getNodeRef(), + ContentModel.PROP_CONTENT, true); + if (writer != null) + { + writer.putContent(this.content); + } } } - - + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#cancel() + */ + @Override + public String cancel() + { + super.cancel(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } } diff --git a/source/java/org/alfresco/web/bean/wizard/NewReplyWizard.java b/source/java/org/alfresco/web/bean/wizard/NewReplyWizard.java index c0166f4b70..60e8e55d8c 100644 --- a/source/java/org/alfresco/web/bean/wizard/NewReplyWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/NewReplyWizard.java @@ -20,6 +20,7 @@ package org.alfresco.web.bean.wizard; import javax.faces.event.ActionEvent; import org.alfresco.model.ContentModel; +import org.alfresco.web.app.AlfrescoNavigationHandler; import org.alfresco.web.ui.common.Utils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -55,7 +56,9 @@ public class NewReplyWizard extends NewPostWizard // remove link breaks and replace with
this.content = Utils.replaceLineBreaks(this.content); - return super.finish(); + super.finish(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; } /** @@ -79,4 +82,15 @@ public class NewReplyWizard extends NewPostWizard } } } + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#cancel() + */ + @Override + public String cancel() + { + super.cancel(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } } diff --git a/source/java/org/alfresco/web/bean/wizard/NewSpaceWizard.java b/source/java/org/alfresco/web/bean/wizard/NewSpaceWizard.java index 300f23478a..75899812db 100644 --- a/source/java/org/alfresco/web/bean/wizard/NewSpaceWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/NewSpaceWizard.java @@ -80,10 +80,10 @@ public class NewSpaceWizard extends AbstractWizardBean private static final String DEFAULT_SPACE_TYPE_ICON = "/images/icons/space.gif"; // new space wizard specific properties - private SearchService searchService; - private NamespaceService namespaceService; - private DictionaryService dictionaryService; - private ConfigService configService; + protected SearchService searchService; + protected NamespaceService namespaceService; + protected DictionaryService dictionaryService; + protected ConfigService configService; protected String spaceType; protected String icon; @@ -996,7 +996,7 @@ public class NewSpaceWizard extends AbstractWizardBean * * @param context Faces context */ - protected void performCustomProcessing(FacesContext context) + protected void performCustomProcessing(FacesContext context) throws Exception { // used by subclasses if necessary } diff --git a/source/java/org/alfresco/web/bean/wizard/NewTopicWizard.java b/source/java/org/alfresco/web/bean/wizard/NewTopicWizard.java index c81f48c621..5b637f068d 100644 --- a/source/java/org/alfresco/web/bean/wizard/NewTopicWizard.java +++ b/source/java/org/alfresco/web/bean/wizard/NewTopicWizard.java @@ -18,26 +18,22 @@ package org.alfresco.web.bean.wizard; import java.io.Serializable; -import java.util.ArrayList; import java.util.HashMap; -import java.util.List; import java.util.Map; import javax.faces.context.FacesContext; -import javax.faces.model.SelectItem; import org.alfresco.model.ContentModel; import org.alfresco.model.ForumModel; -import org.alfresco.service.cmr.repository.ChildAssociationRef; +import org.alfresco.service.cmr.model.FileInfo; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.ContentWriter; import org.alfresco.service.cmr.repository.NodeRef; -import org.alfresco.service.namespace.NamespaceService; import org.alfresco.service.namespace.QName; -import org.alfresco.util.GUID; +import org.alfresco.web.app.AlfrescoNavigationHandler; +import org.alfresco.web.bean.ForumsBean; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; -import org.alfresco.web.ui.common.component.UIListItem; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -51,51 +47,8 @@ public class NewTopicWizard extends NewSpaceWizard private static final Log logger = LogFactory.getLog(NewTopicWizard.class); protected String message; - protected String topicType; - protected List topicIcons; - protected List topicTypes; protected ContentService contentService; - - /** - * Returns a list of topic types for the user to select from - * - * @return The topic types - */ - public List getTopicTypes() - { - if (this.topicTypes == null) - { - this.topicTypes = new ArrayList(3); - - // TODO: change this to be based on categories - this.topicTypes.add(new SelectItem("1", "Announcement")); - this.topicTypes.add(new SelectItem("0", "Normal")); - this.topicTypes.add(new SelectItem("2", "Sticky")); - } - - return this.topicTypes; - } - - /** - * Returns the type of the topic - * - * @return The type of topic - */ - public String getTopicType() - { - return this.topicType; - } - - /** - * Sets the type of the topic - * - * @param topicType The type of the topic - */ - public void setTopicType(String topicType) - { - this.topicType = topicType; - } /** * Returns the message entered by the user for the first post @@ -133,7 +86,6 @@ public class NewTopicWizard extends NewSpaceWizard super.init(); this.spaceType = ForumModel.TYPE_TOPIC.toString(); - this.topicType = "0"; this.message = null; } @@ -141,34 +93,19 @@ public class NewTopicWizard extends NewSpaceWizard * @see org.alfresco.web.bean.wizard.NewSpaceWizard#performCustomProcessing(javax.faces.context.FacesContext) */ @Override - protected void performCustomProcessing(FacesContext context) + protected void performCustomProcessing(FacesContext context) throws Exception { if (this.editMode == false) { - // ************************* - // TODO: Add or update the ForumModel.PROP_TYPE property depending on the editMode - // ************************* - // get the node ref of the node that will contain the content NodeRef containerNodeRef = this.createdNode; // create a unique file name for the message content - String fileName = GUID.generate() + ".txt"; + String fileName = ForumsBean.createPostFileName(); - // create properties for content type - Map contentProps = new HashMap(5, 1.0f); - contentProps.put(ContentModel.PROP_NAME, fileName); - - // create the node to represent the content - String assocName = QName.createValidLocalName(fileName); - ChildAssociationRef assocRef = this.nodeService.createNode( - containerNodeRef, - ContentModel.ASSOC_CONTAINS, - QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, assocName), - Repository.resolveToQName(ForumModel.TYPE_POST.toString()), - contentProps); - - NodeRef postNodeRef = assocRef.getChildRef(); + FileInfo fileInfo = this.fileFolderService.create(containerNodeRef, + fileName, ForumModel.TYPE_POST); + NodeRef postNodeRef = fileInfo.getNodeRef(); if (logger.isDebugEnabled()) logger.debug("Created post node with filename: " + fileName); @@ -196,4 +133,26 @@ public class NewTopicWizard extends NewSpaceWizard writer.putContent(Utils.replaceLineBreaks(this.message)); } } + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#finish() + */ + @Override + public String finish() + { + super.finish(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } + + /** + * @see org.alfresco.web.bean.wizard.AbstractWizardBean#cancel() + */ + @Override + public String cancel() + { + super.cancel(); + + return AlfrescoNavigationHandler.CLOSE_DIALOG_OUTCOME; + } } diff --git a/source/java/org/alfresco/web/ui/repo/component/UISpaceSelector.java b/source/java/org/alfresco/web/ui/repo/component/UISpaceSelector.java index 4fe45e78f9..1d8174f0e7 100644 --- a/source/java/org/alfresco/web/ui/repo/component/UISpaceSelector.java +++ b/source/java/org/alfresco/web/ui/repo/component/UISpaceSelector.java @@ -27,6 +27,7 @@ import org.alfresco.service.cmr.dictionary.DictionaryService; 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.namespace.RegexQNamePattern; import org.alfresco.web.app.Application; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.repo.WebResources; @@ -83,7 +84,8 @@ public class UISpaceSelector extends AbstractItemSelector public Collection getChildrenForNode(FacesContext context) { NodeRef nodeRef = new NodeRef(Repository.getStoreRef(), this.navigationId); - List allKids = getNodeService(context).getChildAssocs(nodeRef); + List allKids = getNodeService(context).getChildAssocs(nodeRef, + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); DictionaryService dd = getDictionaryService(context); NodeService service = getNodeService(context); diff --git a/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java b/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java index e30379d30d..ce762fcf7e 100644 --- a/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java +++ b/source/java/org/alfresco/web/ui/repo/renderer/NodeDescendantsLinkRenderer.java @@ -34,6 +34,7 @@ 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.namespace.QName; +import org.alfresco.service.namespace.RegexQNamePattern; import org.alfresco.web.bean.repository.Repository; import org.alfresco.web.ui.common.Utils; import org.alfresco.web.ui.common.renderer.BaseRenderer; @@ -115,7 +116,8 @@ public class NodeDescendantsLinkRenderer extends BaseRenderer // calculate the number of displayed child refs if (service.exists(parentRef) == true) { - List childRefs = service.getChildAssocs(parentRef); + List childRefs = service.getChildAssocs(parentRef, + ContentModel.ASSOC_CONTAINS, RegexQNamePattern.MATCH_ALL); List refs = new ArrayList(childRefs.size()); for (int index=0; indexpreviewSpace /jsp/dialog/preview-space.jsp + + startDiscussion + /jsp/forums/create-topic.jsp + + + showForum + /jsp/forums/forum.jsp + + + showTopic + /jsp/forums/topic.jsp + @@ -900,14 +912,6 @@ /jsp/forums/* - - cancel - /jsp/forums/forums.jsp - - - finish - /jsp/forums/forums.jsp - createForums /jsp/forums/create-forums.jsp @@ -976,14 +980,22 @@ manageInvitedUsers /jsp/roles/manage-invited-users.jsp + + import + /jsp/dialog/import.jsp + + + export + /jsp/dialog/export.jsp + + + createDiscussion + /jsp/forums/create-discussion.jsp + /jsp/forums/forums-details.jsp - - browse - /jsp/forums/forums.jsp - nextItem /jsp/forums/forums-details.jsp @@ -996,10 +1008,6 @@ /jsp/forums/forum-details.jsp - - browse - /jsp/forums/forum.jsp - nextItem /jsp/forums/forum-details.jsp @@ -1009,153 +1017,45 @@ /jsp/forums/forum-details.jsp + + + /jsp/forums/topic-details.jsp + + nextItem + /jsp/forums/topic-details.jsp + + + previousItem + /jsp/forums/topic-details.jsp + + + + + /jsp/forums/delete-forums.jsp + + forumsDeleted + /jsp/forums/forums.jsp + + + browse + /jsp/browse/browse.jsp + + /jsp/forums/delete-forum.jsp - browse + forumDeleted /jsp/forums/forums.jsp - - /jsp/forums/create-topic.jsp - - cancel - /jsp/forums/forum.jsp - - - finish - /jsp/forums/forum.jsp - - - /jsp/forums/delete-topic.jsp - browse + topicDeleted /jsp/forums/forum.jsp - - cancel - /jsp/forums/forum.jsp - - - finish - /jsp/forums/forum.jsp - - - - - /jsp/forums/topic-details.jsp - - browse - /jsp/forums/topic.jsp - - - cancel - /jsp/forums/topic.jsp - - - finish - /jsp/forums/topic.jsp - - - nextItem - /jsp/forums/topic-details.jsp - - - previousItem - /jsp/forums/topic-details.jsp - - - - - /jsp/forums/create-post.jsp - - cancel - /jsp/forums/topic.jsp - - - finish - /jsp/forums/topic.jsp - - - - - /jsp/forums/create-reply.jsp - - cancel - /jsp/forums/topic.jsp - - - finish - /jsp/forums/topic.jsp - - - - - /jsp/forums/delete-post.jsp - - browse - /jsp/forums/topic.jsp - - - cancel - /jsp/forums/topic.jsp - - - finish - /jsp/forums/topic.jsp - - - - - /jsp/forums/edit-forums.jsp - - cancel - /jsp/forums/forums-details.jsp - - - finish - /jsp/forums/forums-details.jsp - - - - - /jsp/forums/edit-forum.jsp - - cancel - /jsp/forums/forum-details.jsp - - - finish - /jsp/forums/forum-details.jsp - - - - - /jsp/forums/edit-topic.jsp - - cancel - /jsp/forums/topic-details.jsp - - - finish - /jsp/forums/topic-details.jsp - - - - - /jsp/forums/edit-post.jsp - - cancel - /jsp/forums/topic.jsp - - - finish - /jsp/forums/topic.jsp - diff --git a/source/web/WEB-INF/faces-config.xml b/source/web/WEB-INF/faces-config.xml index 59a72d3c1b..cd1fce0be4 100644 --- a/source/web/WEB-INF/faces-config.xml +++ b/source/web/WEB-INF/faces-config.xml @@ -1279,6 +1279,51 @@ #{DictionaryService} + + + + The bean that backs up the Create Discussion Dialog + + CreateDiscussionDialog + org.alfresco.web.bean.wizard.NewDiscussionWizard + session + + nodeService + #{NodeService} + + + fileFolderService + #{FileFolderService} + + + searchService + #{SearchService} + + + navigator + #{NavigationBean} + + + browseBean + #{BrowseBean} + + + searchService + #{SearchService} + + + contentService + #{ContentService} + + + configService + #{configService} + + + namespaceService + #{NamespaceService} + + diff --git a/source/web/images/icons/create_forum.gif b/source/web/images/icons/create_forum.gif index fb8e08588b..982f2b0434 100644 Binary files a/source/web/images/icons/create_forum.gif and b/source/web/images/icons/create_forum.gif differ diff --git a/source/web/images/icons/create_forum_large.gif b/source/web/images/icons/create_forum_large.gif index 95334651dd..0afcaacfd0 100644 Binary files a/source/web/images/icons/create_forum_large.gif and b/source/web/images/icons/create_forum_large.gif differ diff --git a/source/web/images/icons/create_forums.gif b/source/web/images/icons/create_forums.gif index f2e52f9d45..b3f9b04d9f 100644 Binary files a/source/web/images/icons/create_forums.gif and b/source/web/images/icons/create_forums.gif differ diff --git a/source/web/images/icons/create_forums_large.gif b/source/web/images/icons/create_forums_large.gif new file mode 100644 index 0000000000..9fa7b794ba Binary files /dev/null and b/source/web/images/icons/create_forums_large.gif differ diff --git a/source/web/images/icons/create_post.gif b/source/web/images/icons/create_post.gif index e38a2b413e..e01c5ef9cc 100644 Binary files a/source/web/images/icons/create_post.gif and b/source/web/images/icons/create_post.gif differ diff --git a/source/web/images/icons/create_post_large.gif b/source/web/images/icons/create_post_large.gif new file mode 100644 index 0000000000..4ddbdffc0e Binary files /dev/null and b/source/web/images/icons/create_post_large.gif differ diff --git a/source/web/images/icons/create_topic.gif b/source/web/images/icons/create_topic.gif index ec62095a67..d5fc3d5f11 100644 Binary files a/source/web/images/icons/create_topic.gif and b/source/web/images/icons/create_topic.gif differ diff --git a/source/web/images/icons/create_topic_large.gif b/source/web/images/icons/create_topic_large.gif index 652754cbac..8adb6d4c9a 100644 Binary files a/source/web/images/icons/create_topic_large.gif and b/source/web/images/icons/create_topic_large.gif differ diff --git a/source/web/images/icons/edit_post.gif b/source/web/images/icons/edit_post.gif new file mode 100644 index 0000000000..0cb440496b Binary files /dev/null and b/source/web/images/icons/edit_post.gif differ diff --git a/source/web/images/icons/edit_post_large.gif b/source/web/images/icons/edit_post_large.gif new file mode 100644 index 0000000000..b2478b7348 Binary files /dev/null and b/source/web/images/icons/edit_post_large.gif differ diff --git a/source/web/images/icons/forum.gif b/source/web/images/icons/forum.gif index c7a167b47d..7ed3b5d933 100644 Binary files a/source/web/images/icons/forum.gif and b/source/web/images/icons/forum.gif differ diff --git a/source/web/images/icons/forum_large.gif b/source/web/images/icons/forum_large.gif index d025642a8c..96e3b3b5b5 100644 Binary files a/source/web/images/icons/forum_large.gif and b/source/web/images/icons/forum_large.gif differ diff --git a/source/web/images/icons/forums.gif b/source/web/images/icons/forums.gif index 9038f31650..c5864c242b 100644 Binary files a/source/web/images/icons/forums.gif and b/source/web/images/icons/forums.gif differ diff --git a/source/web/images/icons/forums_large.gif b/source/web/images/icons/forums_large.gif index 900dfd7dff..e562606d5e 100644 Binary files a/source/web/images/icons/forums_large.gif and b/source/web/images/icons/forums_large.gif differ diff --git a/source/web/images/icons/post_reply.gif b/source/web/images/icons/post_reply.gif index 0122b92048..c49ece5db0 100644 Binary files a/source/web/images/icons/post_reply.gif and b/source/web/images/icons/post_reply.gif differ diff --git a/source/web/images/icons/post_reply_large.gif b/source/web/images/icons/post_reply_large.gif new file mode 100644 index 0000000000..035d076420 Binary files /dev/null and b/source/web/images/icons/post_reply_large.gif differ diff --git a/source/web/images/icons/topic.gif b/source/web/images/icons/topic.gif index c04487d448..e36e8c7ac7 100644 Binary files a/source/web/images/icons/topic.gif and b/source/web/images/icons/topic.gif differ diff --git a/source/web/images/icons/topic_exclamation.gif b/source/web/images/icons/topic_exclamation.gif new file mode 100644 index 0000000000..005b4752d7 Binary files /dev/null and b/source/web/images/icons/topic_exclamation.gif differ diff --git a/source/web/images/icons/topic_exclamation_large.gif b/source/web/images/icons/topic_exclamation_large.gif new file mode 100644 index 0000000000..87410f5735 Binary files /dev/null and b/source/web/images/icons/topic_exclamation_large.gif differ diff --git a/source/web/images/icons/topic_large.gif b/source/web/images/icons/topic_large.gif index 08b2d3507e..db9aeb309c 100644 Binary files a/source/web/images/icons/topic_large.gif and b/source/web/images/icons/topic_large.gif differ diff --git a/source/web/images/icons/topic_question.gif b/source/web/images/icons/topic_question.gif new file mode 100644 index 0000000000..96da7d9b64 Binary files /dev/null and b/source/web/images/icons/topic_question.gif differ diff --git a/source/web/images/icons/topic_question_large.gif b/source/web/images/icons/topic_question_large.gif new file mode 100644 index 0000000000..f0d7003fcf Binary files /dev/null and b/source/web/images/icons/topic_question_large.gif differ diff --git a/source/web/jsp/admin/admin-console.jsp b/source/web/jsp/admin/admin-console.jsp index cd6fb87562..144fb9216e 100644 --- a/source/web/jsp/admin/admin-console.jsp +++ b/source/web/jsp/admin/admin-console.jsp @@ -106,14 +106,14 @@ - + - + diff --git a/source/web/jsp/browse/browse.jsp b/source/web/jsp/browse/browse.jsp index f1239ada1a..5165b2ac43 100644 --- a/source/web/jsp/browse/browse.jsp +++ b/source/web/jsp/browse/browse.jsp @@ -103,7 +103,7 @@ <%-- Current space More actions menu --%> - + @@ -124,7 +124,7 @@ - + @@ -315,9 +315,22 @@ - + + <%-- More actions menu --%> + + + + + + + + + + + + @@ -461,7 +474,7 @@ - + @@ -506,6 +519,16 @@ + + + + + + + + + + diff --git a/source/web/jsp/dialog/space-details.jsp b/source/web/jsp/dialog/space-details.jsp index 672a658f9d..eb9e452a45 100644 --- a/source/web/jsp/dialog/space-details.jsp +++ b/source/web/jsp/dialog/space-details.jsp @@ -94,11 +94,11 @@ - + - + diff --git a/source/web/jsp/forums/create-discussion.jsp b/source/web/jsp/forums/create-discussion.jsp new file mode 100644 index 0000000000..a8375f3942 --- /dev/null +++ b/source/web/jsp/forums/create-discussion.jsp @@ -0,0 +1,202 @@ +<%-- + 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" %> + + + + + + + + <%-- 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 --%> + + + + + + + <%-- Details --%> + + + + + + + <%-- 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 --%> + + + + + +
+ +
+
+
+
+ +
+ + + + + + +
+ + + + <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %> + + + + + + + + + + + + + + + + + + + + + + + + +
: +  * +
: +
+ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> + + + + <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> +
+
 
: +  * +
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %> +
+ <% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %> + + + + + + + +
+ +
+ +
+ <% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %> +
+
+
+ +
+ + + +
+ +
\ No newline at end of file diff --git a/source/web/jsp/forums/create-forums.jsp b/source/web/jsp/forums/create-forums.jsp index 7e38c49a06..8cd9954eb9 100644 --- a/source/web/jsp/forums/create-forums.jsp +++ b/source/web/jsp/forums/create-forums.jsp @@ -90,7 +90,7 @@
-
diff --git a/source/web/jsp/forums/create-post.jsp b/source/web/jsp/forums/create-post.jsp index 083ec4a116..c576f09260 100644 --- a/source/web/jsp/forums/create-post.jsp +++ b/source/web/jsp/forums/create-post.jsp @@ -81,7 +81,7 @@
-
diff --git a/source/web/jsp/forums/create-reply.jsp b/source/web/jsp/forums/create-reply.jsp index fb33756ecf..05a5687cf5 100644 --- a/source/web/jsp/forums/create-reply.jsp +++ b/source/web/jsp/forums/create-reply.jsp @@ -81,7 +81,7 @@
-
diff --git a/source/web/jsp/forums/create-topic.jsp b/source/web/jsp/forums/create-topic.jsp index 447ab1aca0..1e398425f9 100644 --- a/source/web/jsp/forums/create-topic.jsp +++ b/source/web/jsp/forums/create-topic.jsp @@ -82,7 +82,7 @@
-
diff --git a/source/web/jsp/forums/delete-forum.jsp b/source/web/jsp/forums/delete-forum.jsp index a7263a1c28..7d1dc556b7 100644 --- a/source/web/jsp/forums/delete-forum.jsp +++ b/source/web/jsp/forums/delete-forum.jsp @@ -137,13 +137,13 @@
- +
- +
diff --git a/source/web/jsp/forums/delete-forums.jsp b/source/web/jsp/forums/delete-forums.jsp index cc8de78fec..f507671394 100644 --- a/source/web/jsp/forums/delete-forums.jsp +++ b/source/web/jsp/forums/delete-forums.jsp @@ -137,13 +137,13 @@
- +
- +
diff --git a/source/web/jsp/forums/delete-post.jsp b/source/web/jsp/forums/delete-post.jsp index 8ceb636834..bc2ef852ef 100644 --- a/source/web/jsp/forums/delete-post.jsp +++ b/source/web/jsp/forums/delete-post.jsp @@ -137,13 +137,13 @@
- +
- +
diff --git a/source/web/jsp/forums/delete-topic.jsp b/source/web/jsp/forums/delete-topic.jsp index 616dcd5579..702c9a8e0f 100644 --- a/source/web/jsp/forums/delete-topic.jsp +++ b/source/web/jsp/forums/delete-topic.jsp @@ -137,13 +137,13 @@
- +
- +
diff --git a/source/web/jsp/forums/edit-forum.jsp b/source/web/jsp/forums/edit-forum.jsp index cce3368c5f..38c77ca97e 100644 --- a/source/web/jsp/forums/edit-forum.jsp +++ b/source/web/jsp/forums/edit-forum.jsp @@ -80,7 +80,7 @@
-
diff --git a/source/web/jsp/forums/edit-forums.jsp b/source/web/jsp/forums/edit-forums.jsp index c6e1455aaa..e2b71863f5 100644 --- a/source/web/jsp/forums/edit-forums.jsp +++ b/source/web/jsp/forums/edit-forums.jsp @@ -80,7 +80,7 @@
-
diff --git a/source/web/jsp/forums/edit-post.jsp b/source/web/jsp/forums/edit-post.jsp index dfa73117b6..08b397a29a 100644 --- a/source/web/jsp/forums/edit-post.jsp +++ b/source/web/jsp/forums/edit-post.jsp @@ -81,7 +81,7 @@
-
diff --git a/source/web/jsp/forums/edit-topic.jsp b/source/web/jsp/forums/edit-topic.jsp index 45a5a956d4..2501131bf8 100644 --- a/source/web/jsp/forums/edit-topic.jsp +++ b/source/web/jsp/forums/edit-topic.jsp @@ -80,7 +80,7 @@ <%-- Navigation --%> @@ -150,7 +130,7 @@ + action="dialog:editForumProperties" actionListener="#{EditForumDialog.startWizardForEdit}" /> diff --git a/source/web/jsp/forums/forum.jsp b/source/web/jsp/forums/forum.jsp index 8a46f62fe6..bf530eb486 100644 --- a/source/web/jsp/forums/forum.jsp +++ b/source/web/jsp/forums/forum.jsp @@ -81,13 +81,13 @@ <%-- Current object actions --%>
- + - + - + @@ -105,7 +105,7 @@ - + @@ -183,11 +183,19 @@ - + - + + + + + + + + + diff --git a/source/web/jsp/forums/forums-details.jsp b/source/web/jsp/forums/forums-details.jsp index b22c3dc554..f61cc13d0e 100644 --- a/source/web/jsp/forums/forums-details.jsp +++ b/source/web/jsp/forums/forums-details.jsp @@ -88,30 +88,10 @@ - + - <%-- - - - - - - - - - - - - - - - - - - - --%> <%-- Navigation --%> @@ -150,7 +130,7 @@ + action="dialog:editForumsProperties" actionListener="#{EditForumsDialog.startWizardForEdit}" /> diff --git a/source/web/jsp/forums/forums.jsp b/source/web/jsp/forums/forums.jsp index ca13fd5813..1063f0351b 100644 --- a/source/web/jsp/forums/forums.jsp +++ b/source/web/jsp/forums/forums.jsp @@ -82,18 +82,18 @@ <%-- Current object actions --%>
- + - + - + <%-- Current space More actions menu --%> - + @@ -107,10 +107,18 @@ - + + + + + + + + + @@ -244,11 +252,19 @@ - + - + + + + + + + + + diff --git a/source/web/jsp/forums/topic-details.jsp b/source/web/jsp/forums/topic-details.jsp index 425153b164..3766e8cc4f 100644 --- a/source/web/jsp/forums/topic-details.jsp +++ b/source/web/jsp/forums/topic-details.jsp @@ -88,30 +88,10 @@ - + - <%-- - - - - - - - - - - - - - - - - - - - --%> <%-- Navigation --%> @@ -150,7 +130,7 @@ + action="dialog:editTopicProperties" actionListener="#{EditTopicDialog.startWizardForEdit}" /> diff --git a/source/web/jsp/forums/topic.jsp b/source/web/jsp/forums/topic.jsp index 445015cf3f..d451a68418 100644 --- a/source/web/jsp/forums/topic.jsp +++ b/source/web/jsp/forums/topic.jsp @@ -68,7 +68,7 @@ <%-- actions for forums --%>
-
diff --git a/source/web/jsp/forums/forum-details.jsp b/source/web/jsp/forums/forum-details.jsp index fef4b7b9d1..48f1a34850 100644 --- a/source/web/jsp/forums/forum-details.jsp +++ b/source/web/jsp/forums/forum-details.jsp @@ -88,30 +88,10 @@ - + - <%-- - - - - - - - - - - - - - - - - - - - --%>
- <%-- Summary --%> @@ -81,13 +81,13 @@ <%-- Current object actions --%>
- + - + - + @@ -105,7 +105,7 @@ - + @@ -217,17 +217,17 @@ - + - + - + diff --git a/source/web/jsp/roles/manage-invited-users.jsp b/source/web/jsp/roles/manage-invited-users.jsp index e9cff7e015..2d08ba1780 100644 --- a/source/web/jsp/roles/manage-invited-users.jsp +++ b/source/web/jsp/roles/manage-invited-users.jsp @@ -173,7 +173,7 @@
- +