Skip navigation
All Places > Alfresco Content Services (ECM) > Blog > 2015 > April
2015

The Jira burn-down chart tracks the total work remaining in the sprint and projects the likelihood of achieving the sprint goal. By tracking the remaining work throughout the iteration, a team can manage its progress and respond accordingly. Having spent some time getting to grips with the intricacies of the burn-down chart, I thought that I would share my understanding. 

The green line is the burn-up line which indicates the time spent ie. the sum of all the hours logged against the tasks in the sprint. The red line is the burn-down which indicates the time remaining ie. the total estimated time in the sprint minus all the hours that have been logged. You may well expect that as the sprint progresses, the time burnt-down on the red line will equal the time burnt up on the green line but it seems that this is often not the case. 

Here’s a snippet from a recent burn-down chart for one of my teams, mid-sprint:

 burndown1



You can see that the time indicated on the axis for the burn-down is 84 hours but the time indicated on the axis for the burn-up is 60 hours. So we have logged less time than we estimated we would need. For example:



 timetrack1

If this consistently happens, it tells us something about us overestimating the time we need on our tasks. However, perhaps of more concern would be the converse of this. For example:


 burndown2

Here, we have burnt-up more work than we burnt-down. This is because you can log more hours than you have estimated, for example:

 timetrack2

However, you cannot have a negative time remaining. If you log more than you estimated, the remaining stays at zero. This means that the total represented by the time spent (green) line can exceed the total represented by the time remaining (red) line and indicates that work is taking longer than we estimated. 

What happens if we increase our estimate because we find out, part way through, that a task will take longer than originally thought? This is where we see the upward spikes in the time remaining (red) line, as indicated above. The start point of the ideal work (grey) line and the start point of the burn-down line do not adjust on the axis to reflect that the additional work has been added, so this exacerbates the difference between the apparent burn-down progress and the amount of work completed on the burn-up.  

If your estimates were exactly correct, then adding the time for the scope increases to the apparent burn-down value should then equal the amount of work logged in the burn-up. This isn’t the case in the example above (ie. 35h + 20h + 4h still does not equal 70h) because we are also suffering from under-estimating the time that the tasks will take. 

Given this understanding of what the lines on the graph reflect, it appears that there is useful information to be had here about the accuracy of estimating, especially where we are taking longer on tasks than expected, which may need some further investigation. However, I would only be concerned if this were a regular trend and was matched by a similar discrepancy in the story points estimated and completed within the sprint.  

One final thought is that we do, of course, want the burn-down to reflect reality and not just match the ideal progress line. So being honest about the progress of the work in a sprint is far more important and useful to the team than artificially logging work to achieve a perfect burn down.

I often find when teams move from working as a collection of individuals with a shared purpose, but in different silos that they needs a helping start on when to communicate with each other.

Naturally there are points in time where Scrum creates the opportunities, but those opportunities are not enough for a performing team.

I don’t intend on going into how to communicate in the Scrum ceremonies, but rather share some thoughts on how to start teams effectively talking.

Here are the guideline I give teams:

When you are about to pick up a new user story have a quick chat with the team - all the cross functionals (Coding, testing, documenting, deploying, user experience, etc.) to:

    • … ask if there is anything you can do on a currently in progress user story to help get that completed first.
    • … make sure the story is still good - incorporating anything we may have learnt so far in the sprint. Include the PO in this.
    • … make sure the plan on how to complete the user story is still right - it might need updating based on what we have learnt so far in the sprint.
    • … make sure the tasks represent he plan to complete the user story and have enough information to enable anyone to pick them up.
    • … ensure there are the right people available to work on the user story. If you have specialisms in the team make sure there is someone from the cross functionals to work on the user story, such as a tester to ensure a coder knows what to produce to pass tests.



This conversation would normally be anywhere from 30 seconds to 5 minutes, unless we have learnt something that causes he plan to change considerably.

When you are about to pick up a new task:

    • … ask other team members if they need any help on what they are working on, to help them get their task completed.
    • … check that your approach is going to be correct for the task at hand with another team member. For example
      • a coder may check with a tester before implementing code to ensure they understand the tests, edge cases, negative paths, etc. that they need to cover.
      • a tester may check with coder or user experience to see how they are thinking they would add a button to a user interface to ensure their automated tests would capture it


This is a start for teams, and once they get into the flow they will adjust and improve, probably without even thinking about it.

'When are you moving to Git/GitHub/Bitbucket/decentralised version control software/...' must be the most frequent question I get, both from people inside and outside of Alfresco.

I usually start by explaining that Alfresco is on GitHub! The Alfresco organisation there currently owns 35 public repositories, and many of them are very active. All our mobile code has been there forever; for instance: (iOS + Android) * (SDK + App), as well as Aikau, Gytheio, the Alfresco SDK, etc. The recent announcement that Google Code is going to shut down triggered another batch of migrations to GitHub, such as Jive Toolkit, dropbox integration, and more.


Of course, what the question really means is: 'When is the Alfresco Platform codebase moving? Not some petty integration or client app.' :-) Well, we do have a mirror of the Community Edition source on GitHub. But as for moving the whole code base there, the answer is: never -- at least in its current form. Here are a few reasons why.

    • It doesn't fit!

      GitHub has a limit of 1GB per repository. We hit that limit for the mirror, and had to filter a few big folders. (Even Linux had to cut down the history of the repository to move there!) Of course, we used to commit big jar files in the source. We don't any more, but even then, we still cross the limit. And it's not just GitHub but all DVCS: holding all the history of the repository in your local copy has a big impact if you have a 10 year old code base of one million lines of code!

 

    • Continuity with past releases

      We could make a clean cut, leaving the Old World in Subversion and having the Brave New World in Git. That would work, but it would make merging modifications from earlier maintenance branches very hard -- and most of our commits are of that kind! We have 4 active service pack branches (4.1.x, 4.2.x, 5.0.x) and 18 active hotfix branches (from 3.4.14.x to 5.0.1.x) All fixes have to be merged forward, so that people don't get regressions when upgrading. Doing this is tedious enough without having to switch software in the middle!

 

    • Access rights

      Our Subversion repository is currently a patchwork of access rights, and DVCS don't support that -- the idea being that you spread your software in smaller repositories, and manage the rights for each repository. Even in a given branch, we have folders which are public (Community Edition), others which are reserved to customers (Enterprise Edition) and others which are private (Cloud Edition).

 

    • Big team, big problems

      I don't want to manage a Git repository where 50 people (and counting!) commit daily. DVCS are inherently more complicated than centralised systems (think of what identifies a revision, for instance), which certainly allows for more power, but also more headaches in big teams where not everyone has a PhD in Gitology!


However, don't despair. We are not stuck in this situation forever! As you saw earlier this week, we are currently working hard to make the code more modular, and to extract from our big codebase some independent, consistent pieces that can be released separately. You've seen this already with Aikau and Share (but it also happened a while ago with Records Management, and all the integrations).

As we extract smaller chunks, it can make sense to move them over to GitHub, because they will then be more manageable and will have a small team of people responsible for it. The goal here is twofold: externally, to release more frequently to our audience, and internally, to allow more parallel developments to happen and be more agile.

I hope you are as excited as we are about this change - this is much more interesting than just changing our SCM software!

 

Introduction

One of the Alfresco Solutions Engineers recently contacted me to ask how easy it would be to add a table view into the new filtered search page in Alfresco 5.0. Fortunately this page is built using the Aikau framework, so this is actually an incredibly easy task to accomplish. This blog will take you through the process. If you have trouble following the steps or just want to try it out then download the example extension module from here.

 

Extension Module Creation

The best practice to customizing Alfresco Share is to first create an extension module, and for Aikau pages this is a very straightforward process. First of all ensure that Share is running in “client-debug” mode.

 

Now login to Share and perform a search so that the filtered search page is displayed.

 

Filtered search page

 

Open the “Debug” drop-down menu and select “Toggle Developer View

 

Debug Menu

 

You should see a page that looks like this:

 

Developer View

 

Now click on the link at the very top of the page that says “Click to generate extension JAR”. This will generate a JAR file containing all files required to customize the filtered search page.

 

Unpack the JAR file and open the “/alfresco/site-webscripts/org/alfresco/share/pages/faceted-search/customization/faceted-search.get.js” file in your editor of choice.

 

Now go back to the filtered search page (still in developer view) and click on the info icon for the main list. It should display a tooltip indicating that the widget selected has an id of “FCTSRCH_SEARCH_RESULTS_LIST”.

 

Selecting the Search List

 

Copy the “Find Widget Code Snippet”, it should be:

widgetUtils.findObject(model.jsonModel.widgets, 'id', 'FCTSRCH_SEARCH_RESULTS_LIST');

 

Paste this into the “faceted-search.get.js” file that is open in your editor. This snippet of code is all you need to target a widget on an Aikau page (obviously each snippet of code is different for each widget on the page), and in this case you have targeted the main search results list.

 

Understanding the extension

Lists in Aikau are used to manage data and delegate the rendering of that data to one or more views . We want to add an additional view into the search page.

 

There is lots of information in the Aikau tutorial on creating views, so I'm not going to repeat that information here, but if you're not familiar with defining a list then you should certainly work your way through the tutorial.

 

To add a new view you just need to “push” a new widget declaration into the “widgets” array of the search lists “config” object. You can create any view you like, but as a relatively simple example you could create the following (this would be the complete contents of the faceted-search.get.js file):

var widget = widgetUtils.findObject(model.jsonModel.widgets, 'id', 'FCTSRCH_SEARCH_RESULTS_LIST');
if (widget && widget.config && widget.config.widgets)
{
   widget.config.widgets.push({
      name: 'alfresco/documentlibrary/views/AlfSearchListView',
      config: {
         viewSelectionConfig: {
            label: 'Table View',
            iconClass: 'alf-tableview-icon'
         },
         widgetsForHeader: [
            {
               name: 'alfresco/documentlibrary/views/layouts/HeaderCell',
               config: {
                  label: 'Name'
               }
            },
            {
               name: 'alfresco/documentlibrary/views/layouts/HeaderCell',
               config: {
                  label: 'Description'
               }
            }
         ],
         widgets: [
            {
               name: 'alfresco/search/AlfSearchResult',
               config: {
                  widgets: [
                     {
                        name: 'alfresco/documentlibrary/views/layouts/Row',
                        config: {
                           widgets: [
                              {
                                 name: 'alfresco/documentlibrary/views/layouts/Cell',
                                 config: {
                                    additionalCssClasses: 'mediumpad',
                                    widgets: [
                                       {
                                          name: 'alfresco/renderers/SearchResultPropertyLink',
                                          config: {
                                             propertyToRender: 'displayName'
                                          }
                                       }
                                    ]
                                 }
                              },
                              {
                                 name: 'alfresco/documentlibrary/views/layouts/Cell',
                                 config: {
                                    additionalCssClasses: 'mediumpad',
                                    widgets: [
                                       {
                                          name: 'alfresco/renderers/Property',
                                          config: {
                                             propertyToRender: 'description'
                                          }
                                       }
                                    ]
                                 }
                              }
                           ]
                        }
                     }
                  ]
               }
            }
         ]
      }
   });
}

 

We're pushing in a new 'alfresco/documentlibrary/views/AlfDocumentListView' that uses the table view icon ('alf-tableview-icon'), has a label of “Table View” (which we could have localized if we wanted) and a value of “table”.

 

The view has two header cells (for name and description) and each item in the list is rendered as an 'alfresco/documentlibrary/views/layouts/Row' widget containing two 'alfresco/documentlibrary/views/layouts/Cell' widgets.

 

The first cell contains 'alfresco/renderers/SearchResultPropertyLink' that renders the “displayName” of the item and the second is a simple 'alfresco/renderers/Property' that renders the description.

 

Testing out the view

Re-package the extension files as a JAR file, copy that JAR file into the “share/WEB-INF/lib” folder and then restart the server. When you perform a search you should see your table view as an option.

Selecting the view

Selecting the table view will show the search results as:

Search Table View

You can add more columns to your table view, but it's important to understand that the API used on the search page only retrieves a very small set of Node data. The data that is available for each node found is:

    • displayName
    • description
    • mimetype
    • modifiedBy (user display name)
    • modifiedByUser (username)
    • modifiedOn
    • name
    • title
    • nodeRef
    • path (within a site)
    • site (if the node is in a site)
    • size (in bytes)
    • tags
    • type (e.g. “document”)


If you want to display more than than this limited set of data then there are a couple of options available.

 

One approach that you could take is to use the “alfresco/documentlibrary/views/layouts/XhrLayout” widget that allows an initial version of the view to be rendered for an item (using the limited data set) and when that item is clicked the full node data is requested and the “full” view is then rendered using that data. However, this widget is only a prototype and should only be used as an example.

 

Another option would be to extend the “alfresco/documentlibrary/AlfSearchList” widget to request the full data for each node before the view is rendered. This would naturally slow down the rendering of search results but would allow you to display any of the data available for that node.

 

Deprecations

The example used in this blog will work on 5.0, but you should be aware that some of the widgets referenced have now been deprecated in later versions of Alfresco. The deprecated widgets won't be removed for a long time, but if you’re customizing 5.0.1 onwards then you should look to use the latest versions. All deprecations are listed in the release notes for Aikau.

Filter Blog

By date: By tag: