Printing Task Board Cards from Team Foundation Server

Update 2015-10-02: Added info about digital cards and TFS 2015

Most Scrum teams use a physical task board as it fosters communication more than an digital one. Unfortunately, Team Foundation Server (TFS) can’t print task board cards. Fortunately, friendly people have filled that void and Pascal van Buijtene is one of them. His Scrum Power Tools for Visual Studio 2013 can do even more than print task board cards.

Another benefit of using his Scrum Power Tools is that you can easily customize the template used to print task board cards as it’s defined by an .xslt file. We wanted three customizations:

  1. Show the corresponding work item’s ID on each task card
  2. Show the order – based on the Project Owner’s prioritization – on each work item card
  3. Give task card captions their own background color

We also had to change some of the selectors as his transformation is based on TFS’ Agile template and we use the Scrum template. See comments in “Changes to TaskBoardCards.xslt” below for details.

This is the result:

Printing Task Board Cards from Team Foundation Server - marked

Getting hold of TaskBoardCards.xslt

After installing Scrum Power Tools for Visual Studio 2013 it will use it’s integrated TaskBoardCards.xslt. Once you run a print job (Team Explorer | Work Items | Context Menu of a Query: Create Task Board Cards) you’ll find a copy of TaskBoardCards.xslt as well as WorkItems.xml (work items and tasks selected by your query) and Cards.html (printed task board cards) in C:\Users\<UserName>\AppData\Local\Temp\ScrumPowerToolsTaskBoardCards\.

Copy TaskBoardCards.xslt to your project or to a more generic project. Then add it to the respective project to get it under source control. After that go to Visual Studio’s options and specify the copy at Tools | Options | Scrum Power Tools | Task board cards xslt file.

Customizing TaskBoardCards.xslt

Change TaskBoardCards.xslt like this:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:output method="html" indent="yes"  encoding="utf-8" 
		doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
		doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" />

	<xsl:template match="/WorkItems">
		<html xmlns="http://www.w3.org/1999/xhtml">
			<head>
				<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
				<title>Taskboard Cards</title>
				<style type="text/css">

					body { font-family: arial; }

					.card, .userStoryCard, .bugCard {
					border: solid 1px black; width: 8cm; height: 5.3cm;
					display: inline-block; margin: 3mm; position: relative;
					overflow: hidden;
					}

					.title { color: white; font-weight: bold; text-align: center; }

					.card .title { background-color: #efe4b0; }

					.bugCard .title { background-color: #8b0000; }

					.userStoryCard .title { background-color: #4169e1; }

					.description, .title, .estimation, .sprintDetails { padding: 2mm; }

					.description { position: absolute; }

					.estimation { position: absolute; bottom: 0px; right: 0px; font-size: 26px; font-weight: bold; }

					.sprintDetails { position: absolute; bottom: 0px; left: 0px; font-size: 10px; color: gray; }

				</style>
			</head>

			<body>
				<xsl:for-each select="WorkItem">
					<!-- Agile template = Microsoft.VSTS.Common.StackRank; Scrum template = Microsoft.VSTS.Common.BacklogPriority -->
					<xsl:sort select="Fields/Field[@RefName='Microsoft.VSTS.Common.BacklogPriority']/@Value=''"/>
					<xsl:sort select="Fields/Field[@RefName='Microsoft.VSTS.Common.BacklogPriority']/@Value" data-type="number"/>

					<div class="card">

						<xsl:choose>
							<!-- Agile template = User Story; Scrum template = Product Backlog Item -->
							<xsl:when test="@Type = 'Product Backlog Item'">
								<xsl:attribute name="class">userStoryCard</xsl:attribute>
							</xsl:when>
							<xsl:when test="@Type = 'Bug' or Fields/Field[@RefName='CodeStudio.WorkItemType']/@Value = 'Issue'">
								<xsl:attribute name="class">bugCard</xsl:attribute>
							</xsl:when>
							<xsl:otherwise>
								<xsl:attribute name="class">card</xsl:attribute>
							</xsl:otherwise>
						</xsl:choose>

						<div class="title">
							<xsl:if test="@Type != 'Task'">
								<div># <xsl:value-of select="position()" /></div>
							</xsl:if>			  
							<xsl:value-of select="@Type" /> <xsl:value-of select="@Id" /></div>
						<div class="description"><xsl:value-of select="Fields/Field[@RefName='System.Title']/@Value" /></div>

						<!-- Agile template = Microsoft.VSTS.Scheduling.StoryPoints; Scrum template = Microsoft.VSTS.Scheduling.Effort -->
						<xsl:if test="Fields/Field[@RefName='Microsoft.VSTS.Scheduling.Effort']/@Value">
							<div class="estimation">
								<xsl:value-of select="Fields/Field[@RefName='Microsoft.VSTS.Scheduling.Effort']/@Value" /> SP
							</div>              
						</xsl:if>

						<div class="sprintDetails">
							<xsl:choose>
								<xsl:when test="@Type = 'Task'">
									<xsl:text>WorkItem ID </xsl:text><xsl:value-of select="WorkItemLinks/WorkItemLink[@LinkTypeEndName='Parent']/@TargetId" />
								</xsl:when>
								<xsl:otherwise>
									<div><xsl:value-of select="Fields/Field[@RefName='System.AreaPath']/@Value" /></div>
									<div><xsl:value-of select="Fields/Field[@RefName='System.IterationPath']/@Value" /></div>
								</xsl:otherwise>
							</xsl:choose>
						</div>
					</div>

				</xsl:for-each>
			</body>
		</html>
	</xsl:template>

</xsl:stylesheet>
                          

A short explanation of the changes:

  • Lines 23, 25, and 29 create a different background color for each card type’s caption
  • Lines 44, 45, and 46 sort work items – that’s product backlog items (PBIs) and bugs – based on their prioritization; tasks don’t have their BacklogPriority value set
  • Lines 64, 65, and 66 add the order to the title for work items
  • Lines 79, 80, and 81 add the parent work item’s ID to a task card

Now I want the same information on the digital cards …

After using customized printed task board cards one would like to have similar information on the digital cards – no way with TFS 2013. You’d need more of a replacement like Tiago Pascoal’s Task Board Enhancer. Besides showing the ID on each card it can also mark PBIs / tasks as blocked, collapse PBIs when done, and a lot more useful things.

While the task board improved a lot in TFS 2015 and got most of the features pioneered by Task Board Enhancer there’s still room for improvement:

  • you still cannot print cards
  • it doesn’t remember manual collapsing
  • color marking cards – blocked tasks / PBIs for example – works only in Visual Studio Online
  • you can only add fields from the task / PBI itself to the card but not for example from it’s parent

External References

Advertisements
This entry was posted in Uncategorized and tagged , . Bookmark the permalink.

One Response to Printing Task Board Cards from Team Foundation Server

  1. frinkfree says:

    I have used this extension for a long time and really find it useful. I just wish there was a VS 2015 version.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s