Ejemplo n.º 1
0
        /// <summary>
        /// Uses properties of the SimpleWorkItem to determine this PBI's color.
        /// </summary>
        internal static string GetPbiColor(SimpleWorkItem pbi)
        {
            // Mark PBIs with no effort as red.
            if (pbi.Effort == 0)
            {
                return "#BB0000";
            }

            // Otherwise, color by the PBI's state.
            switch (pbi.State)
            {
                case "New":
                    return "#0000BB";
                case "Approved":
                    return "#990099";
                case "Committed":
                    return "#FF6600";
                case "Done":
                    return "#00BB00";
                case "Removed":
                    return "#BB0000";
                default: // Unknown state.
                    return "#FFFFFF";
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Checks each filter level to see if this item should be ignored.
        /// </summary>
        internal bool IsNotIgnored(SimpleWorkItem simpleWorkItem)
        {
            // If there's no filter provided, it's not ignored.
            var filterCollection = _globalManager.FilterLevels;
            if (filterCollection == null)
            {
                return true;
            }

            // Check if any filter level's filter wants this item ignored.
            foreach (var filterLevel in SimpleWorkItem.NonPbiLevels)
            {
                // Get the filter level keys.
                HashSet<string> filterKeys;
                if (filterCollection.TryGetValue(filterLevel, out filterKeys))
                {
                    // Check if the item's associated key is not contained in the filter level keys.
                    var keyToCheck = simpleWorkItem.GetKey(filterLevel);
                    if (!filterKeys.Contains(keyToCheck))
                    {
                        return false;
                    }
                }
            }

            // It was not found in any of the filters.
            return true;
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Adds the work item to the main nested collection, creating branches as necessary.
        /// </summary>
        internal void AddToTree(SimpleWorkItem simpleWorkItem)
        {
            // Start from the beginning of the collection and work down the tree levels.
            var currentTree = _globalManager.Tree;
            foreach (var treeLevel in _globalManager.TreeLevels)
            {
                // Should never happen.
                if (currentTree == null)
                {
                    throw new Exception("Tree was null.");
                }

                // Get the relevant data from this item for this tree level to use as a key.
                var itemKey = simpleWorkItem.GetKey(treeLevel);

                // Every item has a set of properties associated with it.
                var propertiesManager = new PropertiesManager(_globalManager);

                if (treeLevel == "PBI") // Final level reached, add the work item. This level is optional.
                {
                    propertiesManager.SetPbiProperties(simpleWorkItem);
                    currentTree.Add(itemKey, propertiesManager.Properties);
                }
                else // Get the appropriate collection, making a new one if necessary.
                {
                    if (!currentTree.ContainsKey(itemKey)) // This key's collection doesn't exist.
                    {
                        // Since it's new, add it to a grouping list for synchronizing size/color across a tree level.
                        var group = _globalManager.Groupings.GetOrAdd(treeLevel, new ConcurrentDictionary<string, string>());
                        group.TryAdd(itemKey, "");

                        // The last level won't have children so don't make a new list for children.
                        // This distinction is helpful in other places for determining if there are any children by checking if properties["children"] = null.
                        if (treeLevel != _globalManager.TreeLevels.Last())
                        {
                            propertiesManager.AddChildren();
                        }

                        // Some tree levels have specific properties.
                        propertiesManager.SetLevelProperties(treeLevel, itemKey);

                        // Now that properties are determined, add it to the collection.
                        currentTree.Add(itemKey, propertiesManager.Properties);
                    }
                    else // This key's collection already exists.
                    {
                        // Get the existing properties instead.
                        propertiesManager.Properties = currentTree[itemKey];
                    }

                    // Go a level deeper for the next iteration.
                    currentTree = propertiesManager.GetChildren();
                }

                // Add to the total effort for this grouping/item at this tree level.
                propertiesManager.AddEffort(simpleWorkItem.Effort);
            }
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Pulls information from work item types.
 /// </summary>
 internal void StoreWorkItem(string type, SimpleWorkItem simpleWorkItem)
 {
     switch (type)
     {
         case "PBIs":
             StorePbi(simpleWorkItem);
             break;
         case "Themes":
             StoreTheme(simpleWorkItem);
             break;
         case "Filters":
             StoreFilter(simpleWorkItem);
             break;
         case "Teams":
             StoreTeam(simpleWorkItem);
             break;
         default:
             throw new Exception("Work item type: " + type + ", is not supported.");
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Stores a pre-defined list of properties from work items into a simple object.
        /// </summary>
        internal static SimpleWorkItem BuildSimpleWorkItem(WorkItem workItem, DisplayFieldList displayFieldList)
        {
            var simpleWorkItem = new SimpleWorkItem();
            foreach (FieldDefinition fieldDefinition in displayFieldList)
            {
                // Each case needs the field's value.
                var fieldValue = GetFieldValue(workItem, fieldDefinition.Name);

                // Modify properties here before storing them if they aren't in a desirable format, such as replacing team codes with team names.
                switch (fieldDefinition.Name)
                {
                    case "Effort":
                        double effort;
                        double.TryParse(fieldValue, out effort);
                        simpleWorkItem.Effort = effort;
                        break;
                    case "ID":
                        int id;
                        int.TryParse(fieldValue, out id);
                        simpleWorkItem.Id = id;
                        break;
                    case "Backlog Priority":
                        double priority;
                        double.TryParse(fieldValue, out priority);
                        simpleWorkItem.Priority = priority;
                        break;
                    case "Iteration Path":
                        // Remove the project name, or use a constant if it's solely the project name.
                        var quarter = fieldValue.Contains("\\") ? fieldValue.Substring(fieldValue.IndexOf('\\') + 1) : SimpleWorkItem.GetMissingString("Quarter");
                        var sprint = fieldValue.Contains("\\") ? fieldValue.Substring(fieldValue.IndexOf('\\') + 1) : SimpleWorkItem.GetMissingString("Sprint");

                        // Remove the sprint part for determining quarter, if needed.
                        quarter = quarter.Contains("Sprint") ? quarter.Substring(0, quarter.LastIndexOf('\\')) : quarter;
                        simpleWorkItem.Quarter = quarter;

                        // Normally would remove the quarter/year part for determining sprint here, but I need that for sorting by date.
                        simpleWorkItem.Sprint = sprint;
                        break;
                    case "State":
                        simpleWorkItem.State = fieldValue;
                        break;
                    case "Node Name":
                        simpleWorkItem.Team = fieldValue;
                        switch (simpleWorkItem.Team)
                        {
                            // Some hardcoded team names in TFS.
                            case "Advantage":
                            case "Identity":
                                simpleWorkItem.Team = SimpleWorkItem.GetMissingString("Team");
                                break;
                            case "STL":
                                simpleWorkItem.Team = "Vulcan";
                                break;
                            case "T1":
                                simpleWorkItem.Team = "Loki";
                                break;
                            case "T2":
                                simpleWorkItem.Team = "Anubis";
                                break;
                            case "T3":
                                simpleWorkItem.Team = "Janus";
                                break;
                            case "TC":
                                simpleWorkItem.Team = "Atlas";
                                break;
                            case "TS":
                                simpleWorkItem.Team = "Athena";
                                break;
                        }
                        break;
                    case "Product":
                        simpleWorkItem.Product = fieldValue == string.Empty ? SimpleWorkItem.GetMissingString("Product") : fieldValue;
                        break;
                    case "Program Theme":
                        simpleWorkItem.Theme = fieldValue == string.Empty ? SimpleWorkItem.GetMissingString("Theme") : fieldValue;
                        break;
                    case "Title":
                        simpleWorkItem.Title = fieldValue;
                        break;
                    case "Work Item Type":
                        simpleWorkItem.Type = fieldValue;
                        break;
                    case "Description HTML": // Not PBI-related, used for main theme coloring.
                        var color = ThemeManager.ParseHtmlForColor(fieldValue);
                        simpleWorkItem.MainThemeColor = color;
                        break;
                    case "Mean Velocity": // Not PBI-related, used for teams.
                        double velocity;
                        double.TryParse(fieldValue, out velocity);
                        simpleWorkItem.MeanVelocity = velocity;
                        break;
                }
            }

            // Themes are currently the only optional field for the PBIs query so if it's not an included column, assign it the missing theme value.
            if (simpleWorkItem.Theme == null)
            {
                simpleWorkItem.Theme = SimpleWorkItem.GetMissingString("Theme");
            }

            return simpleWorkItem;
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Stores filter names into a collection.
 /// </summary>
 void StoreFilter(SimpleWorkItem simpleWorkItem)
 {
     foreach (var dataLevel in SimpleWorkItem.NonPbiLevels)
     {
         var dataKey = simpleWorkItem.GetKey(dataLevel);
         var group = _globalManager.Groupings.GetOrAdd(dataLevel, new ConcurrentDictionary<string, string>());
         group.TryAdd(dataKey, "");
     }
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Stores information specific to themes.
        /// </summary>
        void StoreTheme(SimpleWorkItem simpleWorkItem)
        {
            // Some themes have shortcuts that should be used instead.
            var trueTheme = ThemeManager.GetTrueTheme(simpleWorkItem.Title);

            // Make this possibly already parsed title match the parsing conventions.
            var mainThemeName = GlobalManager.GetMainTheme(trueTheme);

            // Store its priority.
            try
            {
                _globalManager.ThemePriorities.Add(mainThemeName, simpleWorkItem.Priority);
            }
            catch (ArgumentException)
            {
                // TODO: Ignoring same name themes.
            }

            // Store its color.
            if (!_globalManager.MainThemeColors.TryAdd(mainThemeName, simpleWorkItem.MainThemeColor))
            {
                // TODO: Ignoring same name themes.
            }
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Stores team velocities into a collection.
 /// </summary>
 void StoreTeam(SimpleWorkItem simpleWorkItem)
 {
     _globalManager.TeamVelocities.TryAdd(simpleWorkItem.Title, simpleWorkItem.MeanVelocity);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Stores a SimpleWorkItem in a logically nested collection for efficient iteration.
        /// </summary>
        void StorePbi(SimpleWorkItem simpleWorkItem)
        {
            // Only PBIs are currently supported.
            if (simpleWorkItem.Type != "Product Backlog Item")
            {
                return;
            }

            // Don't store this item if it's marked to be ignored by any of the filter levels.
            if (IsNotIgnored(simpleWorkItem))
            {
                _treeManager.AddToTree(simpleWorkItem);
            }
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Sets properties associated specifically with PBIs.
 /// </summary>
 internal void SetPbiProperties(SimpleWorkItem simpleWorkItem)
 {
     Properties["priority"] = simpleWorkItem.Priority; // Useful in SortManager.
     Properties["simpleWorkItem"] = simpleWorkItem;
 }