Example #1
0
        private void BuildChildItemsList(IConfiguration configuration)
        {
            var backlogChildrenList = new List <BacklogChildren>();

            AllChildren = new List <WorkItem>();

            //keep a hash with the backlog items ids. It implies an additional iteration through the collection,
            //but we make up for this when searching for parents in constant time rather than linear
            HashSet <int> backLogIds = new HashSet <int>();

            BackLogItems.ForEach(wi => backLogIds.Add(wi.Id));

            // Iterate over all backlog items and get the list of child items.
            // Keep track of the relation between a backlog item and its child item via the BacklogChildren class.
            foreach (var backLogItem in BackLogItems)
            {
                var currentItem = backLogItem;
                // Get all the work items that the current item points to
                var childInfos = WorkItemLinkInfos.Where(info => info.SourceId == currentItem.Id).ToList();
                // Get the Ids of tht work items
                var childIds = (from WorkItemLinkInfo info in childInfos select info.TargetId).ToList();
                // Get the work items for that ids but only if they are not already in the backlog items list and if they match the child item setting

                // Note: Uncomment the following line and comment the line after in order to hide backlog items from the child area
                //var children = WorkItems.Cast<WorkItem>().Where(item => childIds.Contains(item.Id) && !backLogIds.Contains(item.Id) && configuration.ChildItems.Contains(item.Type.Name)).ToList();
                var children = WorkItems.Cast <WorkItem>().Where(item => childIds.Contains(item.Id) && configuration.ChildItems.Contains(item.Type.Name)).ToList();

                AllChildren.AddRange(children);
                var backlogChildren = new BacklogChildren(backLogItem, children, configuration.States);
                backlogChildrenList.Add(backlogChildren);
            }

            ApplyChildrenChangesOnUIThread(backlogChildrenList);
        }
Example #2
0
 private void ApplyChildrenChangesOnUIThread(List <BacklogChildren> backlogChildrenList)
 {
     // The UI binds to BacklogChildren and that's why we must switch to the UI thread before changing the list
     if (SyncService != null)
     {
         if (!SyncService.Value.CheckAccess())
         {
             SyncService.Value.Invoke(new Action <List <BacklogChildren> >(ApplyChildrenChangesOnUIThread), backlogChildrenList);
             return;
         }
     }
     BacklogChildren.Clear();
     foreach (var children in backlogChildrenList)
     {
         BacklogChildren.Add(children);
         FlushWindowsMessageQueue(true);
     }
 }
Example #3
0
        public void ApplyConfiguration(IConfiguration configuration)
        {
            if (TeamProjectCollection == null)
            {
                return;
            }
            if (configuration == null)
            {
                return;
            }
            if (configuration.QueryId == Guid.Empty)
            {
                var errorMessage = StatusService.EnqueueStatusItem("InvalidQuery");
                errorMessage.Message = "There is no query defined in the configuration. Please choose a query by clicking \"Edit\"";
                return;
            }

            // Before refreshing the data we should verify whether there are unsaved changes that need to be saved
            if (!VerifySaveRequest())
            {
                return;
            }

            var statusItem = StatusService.EnqueueStatusItem("ApplyConfiguration");

            statusItem.Message                 = string.Format("Applying configuration for team project {0}", TeamProject.Name);
            statusItem.IsProgressing           = true;
            statusItem.IsProgressIndeterminate = true;
            // Run the query in order to provide the result data
            var store = TeamProjectCollection.GetService <WorkItemStore>();
            // Get the query based on the Id we keep in the configuration
            QueryDefinition queryDefinition = SaveGetQueryDefinition(store, configuration.QueryId);
            Query           query           = GetQuery(queryDefinition);

            // Only if the query is a link query we perform the fullblown request for data
            if ((query != null) && (query.IsLinkQuery))
            {
                // First get the linking information
                WorkItemLinkInfos = query.RunLinkQuery();
                // Get the configured link type in order to respect it when retrieving the work items
                var linkType = (!string.IsNullOrEmpty(configuration.LinkType)) ? store.WorkItemLinkTypes.FirstOrDefault(type => type.ReferenceName == configuration.LinkType) : null;
                // Now put all TargetIds into a BatchReadParameterCollection in order to get the work items for the links
                // Attention: Consider handling the link types correctly
                var batchReadParams = new BatchReadParameterCollection();
                foreach (var linkInfo in WorkItemLinkInfos)
                {
                    if (linkType == null)
                    {
                        // If there is no link type there is nothing we can check explicitly and therefor we respect any child
                        if (!batchReadParams.Contains(linkInfo.TargetId))
                        {
                            batchReadParams.Add(new BatchReadParameter(linkInfo.TargetId));
                        }
                    }
                    else
                    {
                        // Debug.WriteLink("Link: {0} Source: {1} Target: {2} RefName: {3} Forward: {4} Reverse: {5}", linkInfo.LinkTypeId, linkInfo.SourceId, linkInfo.TargetId, linkType.ReferenceName, linkType.ForwardEnd.Id, linkType.ReverseEnd.Id);
                        // We need to respect the link type.
                        if (IsValidLinkInfo(linkInfo, linkType))
                        {
                            // When the link info is valid according to the current configuration then we consider the work item in our query.
                            if (!batchReadParams.Contains(linkInfo.TargetId))
                            {
                                batchReadParams.Add(new BatchReadParameter(linkInfo.TargetId));
                            }
                        }
                        // When the link type is not valid we also do not consider the item.
                    }
                }
                // Now construct the query to get the work items
                string        batchQuery       = "SELECT {0} FROM WorkItems";
                List <string> displayFields    = (from FieldDefinition fieldDefinition in query.DisplayFieldList select fieldDefinition.ReferenceName).ToList();
                string        displayFieldPart = string.Join(",", displayFields.ToArray());
                if (batchReadParams.Count != 0)
                {
                    batchQuery = string.Format(batchQuery, displayFieldPart);
                    // Run the query and remember the results
                    WorkItems = store.Query(batchReadParams, batchQuery);
                    BuildBacklogItemsList(configuration);
                    BuildChildItemsList(configuration);
                }
                else
                {
                    ApplyChildrenChangesOnUIThread(new List <BacklogChildren>());
                }
            }
            else
            {
                WorkItemLinkInfos = null;
                WorkItems         = query != null?query.RunQuery() : null;

                if (AllChildren != null)
                {
                    AllChildren.Clear();
                }
                if (BacklogChildren.Count > 0)
                {
                    BacklogChildren.Clear();
                }
                if (BackLogItems != null)
                {
                    BackLogItems.Clear();
                }
            }
            PrepareTransitionsMap(configuration);
            OnConfigurationApplied();
        }