/// <summary>
        /// Get the tree root node of a tree.
        /// </summary>
        private async Task <TreeRootNode> GetTreeRootNode(Tree tree, int id, FormDataCollection querystring)
        {
            if (tree == null)
            {
                throw new ArgumentNullException(nameof(tree));
            }

            var children = await GetChildren(tree, id, querystring);

            var rootNode = await GetRootNode(tree, querystring);

            var sectionRoot = TreeRootNode.CreateSingleTreeRoot(
                Constants.System.RootString,
                rootNode.ChildNodesUrl,
                rootNode.MenuUrl,
                rootNode.Name,
                children,
                tree.IsSingleNodeTree);

            // assign the route path based on the root node, this means it will route there when the
            // section is navigated to and no dashboards will be available for this section
            sectionRoot.RoutePath = rootNode.RoutePath;
            sectionRoot.Path      = rootNode.Path;

            foreach (var d in rootNode.AdditionalData)
            {
                sectionRoot.AdditionalData[d.Key] = d.Value;
            }

            return(sectionRoot);
        }
    /// <summary>
    ///     Get the tree root node of a tree.
    /// </summary>
    private async Task <ActionResult <TreeRootNode> > GetTreeRootNode(Tree tree, int id, FormCollection?querystring)
    {
        if (tree == null)
        {
            throw new ArgumentNullException(nameof(tree));
        }

        ActionResult <TreeNodeCollection?>?childrenResult = await GetChildren(tree, id, querystring);

        if (!(childrenResult?.Result is null))
        {
            return(new ActionResult <TreeRootNode>(childrenResult.Result));
        }

        TreeNodeCollection?      children       = childrenResult?.Value;
        ActionResult <TreeNode?>?rootNodeResult = await GetRootNode(tree, querystring);

        if (!(rootNodeResult?.Result is null))
        {
            return(rootNodeResult.Result);
        }

        TreeNode?rootNode = rootNodeResult?.Value;


        var sectionRoot = TreeRootNode.CreateSingleTreeRoot(
            Constants.System.RootString,
            rootNode !.ChildNodesUrl,
            rootNode.MenuUrl,
            rootNode.Name,
            children,
            tree.IsSingleNodeTree);

        // assign the route path based on the root node, this means it will route there when the
        // section is navigated to and no dashboards will be available for this section
        sectionRoot.RoutePath = rootNode.RoutePath;
        sectionRoot.Path      = rootNode.Path;

        foreach (KeyValuePair <string, object?> d in rootNode.AdditionalData)
        {
            sectionRoot.AdditionalData[d.Key] = d.Value;
        }

        return(sectionRoot);
    }
Exemplo n.º 3
0
        /// <summary>
        /// Get the root node for an application with one tree
        /// </summary>
        /// <param name="configTree"></param>
        /// <param name="id"></param>
        /// <param name="queryStrings"></param>
        /// <param name="application"></param>
        /// <returns></returns>
        private async Task <TreeRootNode> GetRootForSingleAppTree(ApplicationTree configTree, string id, FormDataCollection queryStrings, string application)
        {
            var rootId = Constants.System.Root.ToString(CultureInfo.InvariantCulture);

            if (configTree == null)
            {
                throw new ArgumentNullException(nameof(configTree));
            }
            var byControllerAttempt = configTree.TryLoadFromControllerTree(id, queryStrings, ControllerContext);

            if (byControllerAttempt.Success)
            {
                var rootNode = await configTree.TryGetRootNodeFromControllerTree(queryStrings, ControllerContext);

                if (rootNode.Success == false)
                {
                    //This should really never happen if we've successfully got the children above.
                    throw new InvalidOperationException("Could not create root node for tree " + configTree.Alias);
                }

                var treeAttribute = configTree.GetTreeAttribute();

                var sectionRoot = TreeRootNode.CreateSingleTreeRoot(
                    rootId,
                    rootNode.Result.ChildNodesUrl,
                    rootNode.Result.MenuUrl,
                    rootNode.Result.Name,
                    byControllerAttempt.Result,
                    treeAttribute.IsSingleNodeTree);

                //assign the route path based on the root node, this means it will route there when the section is navigated to
                //and no dashboards will be available for this section
                sectionRoot.RoutePath = rootNode.Result.RoutePath;

                foreach (var d in rootNode.Result.AdditionalData)
                {
                    sectionRoot.AdditionalData[d.Key] = d.Value;
                }
                return(sectionRoot);
            }

            throw new ApplicationException("Could not render a tree for type " + configTree.Alias);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns the tree nodes for an application
        /// </summary>
        /// <param name="application">The application to load tree for</param>
        /// <param name="tree">An optional single tree alias, if specified will only load the single tree for the request app</param>
        /// <param name="queryStrings">The query strings</param>
        /// <param name="use">Tree use.</param>
        public async Task <ActionResult <TreeRootNode> > GetApplicationTrees(string application, string tree, [ModelBinder(typeof(HttpQueryStringModelBinder))] FormCollection queryStrings, TreeUse use = TreeUse.Main)
        {
            application = application.CleanForXss();

            if (string.IsNullOrEmpty(application))
            {
                return(NotFound());
            }

            var section = _sectionService.GetByAlias(application);

            if (section == null)
            {
                return(NotFound());
            }

            // find all tree definitions that have the current application alias
            var groupedTrees = _treeService.GetBySectionGrouped(application, use);
            var allTrees     = groupedTrees.Values.SelectMany(x => x).ToList();

            if (allTrees.Count == 0)
            {
                // if there are no trees defined for this section but the section is defined then we can have a simple
                // full screen section without trees
                var name = _localizedTextService.Localize("sections", application);
                return(TreeRootNode.CreateSingleTreeRoot(Constants.System.RootString, null, null, name, TreeNodeCollection.Empty, true));
            }

            // handle request for a specific tree / or when there is only one tree
            if (!tree.IsNullOrWhiteSpace() || allTrees.Count == 1)
            {
                var t = tree.IsNullOrWhiteSpace()
                    ? allTrees[0]
                    : allTrees.FirstOrDefault(x => x.TreeAlias == tree);

                if (t == null)
                {
                    return(NotFound());
                }

                var treeRootNode = await GetTreeRootNode(t, Constants.System.Root, queryStrings);

                if (treeRootNode != null)
                {
                    return(treeRootNode);
                }

                return(NotFound());
            }

            // handle requests for all trees
            // for only 1 group
            if (groupedTrees.Count == 1)
            {
                var nodes = new TreeNodeCollection();
                foreach (var t in allTrees)
                {
                    var nodeResult = await TryGetRootNode(t, queryStrings);

                    if (!(nodeResult.Result is null))
                    {
                        return(nodeResult.Result);
                    }

                    var node = nodeResult.Value;
                    if (node != null)
                    {
                        nodes.Add(node);
                    }
                }

                var name = _localizedTextService.Localize("sections", application);

                if (nodes.Count > 0)
                {
                    var treeRootNode = TreeRootNode.CreateMultiTreeRoot(nodes);
                    treeRootNode.Name = name;
                    return(treeRootNode);
                }

                // otherwise it's a section with all empty trees, aka a fullscreen section
                // todo is this true? what if we just failed to TryGetRootNode on all of them? SD: Yes it's true but we should check the result of TryGetRootNode and throw?
                return(TreeRootNode.CreateSingleTreeRoot(Constants.System.RootString, null, null, name, TreeNodeCollection.Empty, true));
            }

            // for many groups
            var treeRootNodes = new List <TreeRootNode>();

            foreach (var(groupName, trees) in groupedTrees)
            {
                var nodes = new TreeNodeCollection();
                foreach (var t in trees)
                {
                    var nodeResult = await TryGetRootNode(t, queryStrings);

                    if (nodeResult != null && nodeResult.Result is not null)
                    {
                        return(nodeResult.Result);
                    }
                    var node = nodeResult?.Value;

                    if (node != null)
                    {
                        nodes.Add(node);
                    }
                }

                if (nodes.Count == 0)
                {
                    continue;
                }

                // no name => third party
                // use localization key treeHeaders/thirdPartyGroup
                // todo this is an odd convention
                var name = groupName.IsNullOrWhiteSpace() ? "thirdPartyGroup" : groupName;

                var groupRootNode = TreeRootNode.CreateGroupNode(nodes, application);
                groupRootNode.Name = _localizedTextService.Localize("treeHeaders", name);
                treeRootNodes.Add(groupRootNode);
            }

            return(TreeRootNode.CreateGroupedMultiTreeRoot(new TreeNodeCollection(treeRootNodes.OrderBy(x => x.Name))));
        }
Exemplo n.º 5
0
        public async Task <TreeRootNode> GetApplicationTrees(string application, string tree, FormDataCollection queryStrings, bool onlyInitialized = true)
        {
            application = application.CleanForXss();

            if (string.IsNullOrEmpty(application))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            //find all tree definitions that have the current application alias
            var groupedTrees = Services.ApplicationTreeService.GetGroupedApplicationTrees(application, onlyInitialized);
            var allTrees     = groupedTrees.Values.SelectMany(x => x).ToList();

            if (string.IsNullOrEmpty(tree) == false || allTrees.Count == 1)
            {
                var apptree = !tree.IsNullOrWhiteSpace()
                    ? allTrees.FirstOrDefault(x => x.Alias == tree)
                    : allTrees.FirstOrDefault();

                if (apptree == null)
                {
                    throw new HttpResponseException(HttpStatusCode.NotFound);
                }

                var result = await GetRootForSingleAppTree(
                    apptree,
                    Constants.System.Root.ToString(CultureInfo.InvariantCulture),
                    queryStrings,
                    application);

                //this will be null if it cannot convert to a single root section
                if (result != null)
                {
                    return(result);
                }
            }

            //Don't apply fancy grouping logic futher down, if we only have one group of items
            var hasGroups = groupedTrees.Count > 1;

            if (!hasGroups)
            {
                var collection = new TreeNodeCollection();
                foreach (var apptree in allTrees)
                {
                    //return the root nodes for each tree in the app
                    var rootNode = await GetRootForMultipleAppTree(apptree, queryStrings);

                    //This could be null if the tree decides not to return it's root (i.e. the member type tree does this when not in umbraco membership mode)
                    if (rootNode != null)
                    {
                        collection.Add(rootNode);
                    }
                }

                if (collection.Count > 0)
                {
                    var multiTree = TreeRootNode.CreateMultiTreeRoot(collection);
                    multiTree.Name = Services.TextService.Localize("sections/" + application);

                    return(multiTree);
                }

                //Otherwise its a application/section with no trees (aka a full screen app)
                //For example we do not have a Forms tree definied in C# & can not attribute with [Tree(isSingleNodeTree:true0]
                var rootId  = Constants.System.Root.ToString(CultureInfo.InvariantCulture);
                var section = Services.TextService.Localize("sections/" + application);

                return(TreeRootNode.CreateSingleTreeRoot(rootId, null, null, section, TreeNodeCollection.Empty, true));
            }

            var rootNodeGroups = new List <TreeRootNode>();

            //Group trees by [CoreTree] attribute with a TreeGroup property
            foreach (var treeSectionGroup in groupedTrees)
            {
                var treeGroupName = treeSectionGroup.Key;

                var groupNodeCollection = new TreeNodeCollection();
                foreach (var appTree in treeSectionGroup.Value)
                {
                    var rootNode = await GetRootForMultipleAppTree(appTree, queryStrings);

                    if (rootNode != null)
                    {
                        //Add to a new list/collection
                        groupNodeCollection.Add(rootNode);
                    }
                }

                //If treeGroupName == null then its third party
                if (treeGroupName.IsNullOrWhiteSpace())
                {
                    //This is used for the localisation key
                    //treeHeaders/thirdPartyGroup
                    treeGroupName = "thirdPartyGroup";
                }

                if (groupNodeCollection.Count > 0)
                {
                    var groupRoot = TreeRootNode.CreateGroupNode(groupNodeCollection, application);
                    groupRoot.Name = Services.TextService.Localize("treeHeaders/" + treeGroupName);

                    rootNodeGroups.Add(groupRoot);
                }
            }

            return(TreeRootNode.CreateGroupedMultiTreeRoot(new TreeNodeCollection(rootNodeGroups.OrderBy(x => x.Name))));
        }