using System.Globalization; using System.Linq; using System.Runtime.Serialization; namespace Umbraco.Web.Models.Trees { /// /// A tree node that represents various types of root nodes /// /// /// /// A represents: /// * The root node for a section containing a single tree /// * The root node for a section containing multiple sub-trees /// * The root node for a section containing groups of multiple sub-trees /// * The group node in a section containing groups of multiple sub-trees /// /// /// This is required to return the tree data for a given section. Some sections may only contain one tree which means it's section /// root should also display a menu, whereas other sections have multiple trees and the section root shouldn't display a menu. /// /// /// The root node also contains an explicit collection of children. /// /// [DataContract(Name = "node", Namespace = "")] public sealed class TreeRootNode : TreeNode { private static readonly string RootId = Core.Constants.System.Root.ToString(CultureInfo.InvariantCulture); private bool _isGroup; private bool _alwaysShow; /// /// Creates a group node for grouped multiple trees /// /// /// public static TreeRootNode CreateGroupNode(TreeNodeCollection children, string section) { var sectionRoot = new TreeRootNode(RootId, string.Empty, string.Empty) { IsGroup = true, Children = children, RoutePath = section }; return sectionRoot; } /// /// Creates a section root node for grouped multiple trees /// /// /// public static TreeRootNode CreateGroupedMultiTreeRoot(TreeNodeCollection children) { var sectionRoot = new TreeRootNode(RootId, string.Empty, string.Empty) { IsContainer = true, Children = children, ContainsGroups = true }; return sectionRoot; } /// /// Creates a section root node for non-grouped multiple trees /// /// /// public static TreeRootNode CreateMultiTreeRoot(TreeNodeCollection children) { var sectionRoot = new TreeRootNode(RootId, string.Empty, string.Empty) { IsContainer = true, Children = children }; return sectionRoot; } /// /// Creates a section root node for a section with a single tree /// /// /// /// /// /// /// /// public static TreeRootNode CreateSingleTreeRoot(string nodeId, string getChildNodesUrl, string menuUrl, string title, TreeNodeCollection children, bool alwaysShowRootNode = false) { return new TreeRootNode(nodeId, getChildNodesUrl, menuUrl) { Children = children, Name = title, _alwaysShow = alwaysShowRootNode }; } /// /// Private constructor /// /// /// /// private TreeRootNode(string nodeId, string getChildNodesUrl, string menuUrl) : base(nodeId, null, getChildNodesUrl, menuUrl) { //default to false IsContainer = false; } /// /// Will be true if this is a multi-tree section root node (i.e. contains other trees) /// [DataMember(Name = "isContainer")] public bool IsContainer { get; private set; } /// /// True if this is a group root node /// [DataMember(Name = "isGroup")] public bool IsGroup { get => _isGroup; private set { //if a group is true then it is also a container _isGroup = value; IsContainer = true; } } /// /// True if this root node contains group root nodes /// [DataMember(Name = "containsGroups")] public bool ContainsGroups { get; private set; } /// /// The node's children collection /// [DataMember(Name = "children")] public TreeNodeCollection Children { get; private set; } /// /// Returns true if there are any children /// /// /// This is used in the UI to configure a full screen section/app /// [DataMember(Name = "containsTrees")] public bool ContainsTrees => Children.Count > 0 || _alwaysShow; } }