Custom Sorting for Work Items in Team Foundation Server 2008
Team Foundation Server (TFS), Technology September 23rd, 2009TFS provides the WIQ Language (Work Item Query) to query work items. WIQ is very similar to standard SQL — you have a Select statement to pull back columns of data, a Where clause to filter data, and a Sort By clause. However, WIQ is much more limited than standard SQL. In particular, advanced sorting logic is not supported. Thus, you may find yourself needing to implement some type of custom solution to sort your work items. A recent client had a pretty advanced sorting system in place in their old Mercury TestDirector system (they migrated over to TFS and got rid of TestDirector). You might need custom sorting if, for example, you need special logic to determine the priority of the defects/bugs. Developers will work on the queue of defects based on the order of the work items. Here are your options:
- Use WIQ. As stated above, this option is limited to basic sorting. You can sort by a single field, or multiple fields. Conditional logic or advanced grouping is not supported.
- Develop a web service triggered by the Work Item Changed event. By adding a field to the work item definition (perhaps an integer field labeled "SortOrder") you can evaluate the work item to determine what sort order it should be assigned. In our case, we identified 5 sort levels, so the "SortOrder" field was assigned a number between 1 and 5. Work Item queries were written to sort based on this field first, then by other fields to secondary sort the work items.
The web service gets run after you save the work item. The web service event fires, evaluates the work item, assigns a value to the "SortOrder" field, and then saves the work item.
Sample code (this uses the TFSEvents framework available at Codeplex):
public void Notify(string eventXml, string tfsIdentityXml)
{
WorkItemChangedEvent workItemChangedEvent = this.CreateInstance<WorkItemChangedEvent>(eventXml);
TFSIdentity tfsIdentity = this.CreateInstance<TFSIdentity>(tfsIdentityXml);int WorkItemID = workItemChangedEvent.CoreFields.IntegerFields[0].NewValue;
Microsoft.TeamFoundation.Client.TeamFoundationServer TFS = new TeamFoundationServer(tfsIdentity.Url);
TFS.Authenticate();WorkItemStore WIS = TFS.GetService(typeof(WorkItemStore)) as WorkItemStore;
WorkItem updatedWI = WIS.GetWorkItem(WorkItemID);
string priority = "";
string environment = "";if (updatedWI.Fields.Contains("CustomFields.SortOrder"))
{
priority = updatedWI.Fields["CustomFields.Priority"].Value.ToString();
environment = updatedWI.Fields["CustomFields.FoundInEnvironment"].Value.ToString();if (priority == "1-Now")
{
updatedWI.Fields["CustomFields.SortOrder"].Value = 1;}
else if (priority == "2-ASAP")
{
updatedWI.Fields["CustomFields.SortOrder"].Value = 2;
}
else if (updatedWI.Fields["CustomFields.CRID"].Value.ToString() != "" ||
(updatedWI.Fields["System.IterationID"].Value.ToString() != "154" &&
updatedWI.Fields["System.IterationID"].Value.ToString() != "314"))
{
updatedWI.Fields["CustomFields.SortOrder"].Value = 3;
}
else if (environment == "2-PRE-PROD" || environment == "3-Test" || environment == "4-DEVL")
{
updatedWI.Fields["CustomFields.SortOrder"].Value = 4;
}
else if (environment == "1-PROD")
{
updatedWI.Fields["CustomFields.SortOrder"].Value = 5;
}if (updatedWI.IsDirty)
{
updatedWI.Save();
}
}
}A big disadvantage to this method — the work item gets updated by the web service, thus if a user has the work item loaded on their screen, makes a change, and tried to save, it will fail and notify the user the work item has been updated by another user. This scenario is very likely to happen since the user will have the work item on their screen during the initial save and may want to add additional data or update information on the work item. They are forced to close and reopen the work item after each save. For most organizations, this would be frustrating and probably disqualify this solution.
- Develop a client-side custom control. This option is similar to the web service, but the logic lives on the client. Using a custom field such as "SortOrder" you can assign a sort value based on the work item information. The logic runs before the work item is saved, so only one update/save operation is required. The advantage to this method is you don’t have the update problem as you do with the web service. The disadvantage is that this control needs to be deployed to all your developer/client machines or else the sort logic won’t run and be assigned.
Based on all these options, the best option if you require advanced sorting logic is to develop a client-side custom control.
Recent Comments