Question

I would like to start by saying I have read Rally Kanban - hiding Epic Stories but I'm still having trouble on implementing my filter based on the filter process from the Estimation Board app. Currently I'm trying to add an items filter to my query object for my cardboard. The query object calls this._getItems to return an array of items to filter from. As far as I can tell the query calls the function, loads for a second or two, and then displays no results. Any input, suggestions, or alternative solutions are welcomed.

Here's my code

$that._redisplayBoard = function() {


            that._getAndStorePrefData(displayBoard);

            this._getItems = function(callback) {

            //Build types based on checkbox selections
            var queries = [];

                    queries.push({key:"HierarchicalRequirement",
                        type: "HierarchicalRequirement",
                        fetch: "Name,FormattedID,Owner,ObjectID,Rank,PlanEstimate,Children,Ready,Blocked",
                        order: "Rank"

                    });



            function bucketItems(results) {
                var items = [];

                rally.forEach(queries, function(query) {
                    if (results[query.key]) {
                        rally.forEach(results[query.key], function(item) {
                            //exclude epic stories since estimates cannot be altered
                            if ((item._type !== 'HierarchicalRequirement') ||
                                    (item._type === 'HierarchicalRequirement' && item.Children.length === 0)) {
                                items = items.concat(item);

                            }
                        });
      }
                });


               callback(items);
                }

                 rallyDataSource.findAll(queries, bucketItems);

            };

            function displayBoard() {

                artifactTypes = [];



                var cardboardConfig = {

                    types: [],

                    items: that._getItems,

                    attribute: kanbanField,

                    sortAscending: true,

                    maxCardsPerColumn: 200,

                    order: "Rank",

                    cardRenderer: KanbanCardRenderer,

                    cardOptions: {

                        showTaskCompletion: showTaskCompletion,

                        showAgeAfter: showAgeAfter

                    },

                    columnRenderer: KanbanColumnRenderer,

                    columns: columns,

                    fetch: "Name,FormattedID,Owner,ObjectID,Rank,Ready,Blocked,LastUpdateDate,Tags,State,Priority,StoryType,Children"

                };



                if (showTaskCompletion) {

                    cardboardConfig.fetch += ",Tasks";

                }



                if (hideLastColumnIfReleased) {

                    cardboardConfig.query = new rally.sdk.util.Query("Release = null").or(kanbanField + " != " + '"' + lastState + '"');

                }



                if (filterByTagsDropdown && filterByTagsDropdown.getDisplayedValue()) {

                    cardboardConfig.cardOptions.filterBy = { field: FILTER_FIELD, value: filterByTagsDropdown.getDisplayedValue() };

                }



                cardboardConfig.types.push("HierarchicalRequirement");



                if (cardboard) {

                    cardboard.destroy();

                }



                artifactTypes = cardboardConfig.types;






                cardboard = new rally.sdk.ui.CardBoard(cardboardConfig, rallyDataSource);




                cardboard.addEventListener("preUpdate", that._onBeforeItemUpdated); 
                cardboard.addEventListener("onDataRetrieved", function(cardboard,args){ console.log(args.items); }); 

                cardboard.display("kanbanBoard");

            }

        };


        that.display = function(element) {



            //Build app layout

            this._createLayout(element);



            //Redisplay the board

            this._redisplayBoard();

        };

    };
Was it helpful?

Solution

Mark's answer caused an obscure crash when cardboard.setItems(filteredItems) was called. However, since the filtering code is actually manipulating the actual references, it turns out that setItems() method is actually not needed. I pulled it out, and it now filters properly.

OTHER TIPS

Per Charles' hint in Rally Kanban - hiding Epic Stories

Here's how I approached this following Charles' hint for the Rally Catalog Kanban. First, modify the fetch statement inside the cardboardConfig so that it includes the Children collection, thusly:

      fetch: "Name,FormattedID,Children,Owner,ObjectID,Rank,Ready,Blocked,LastUpdateDate,Tags,State"

Next, in between this statement:

      cardboard.addEventListener("preUpdate", that._onBeforeItemUpdated);   

And this statement:

     cardboard.display("kanbanBoard");

Add the following event listener and callback:

    cardboard.addEventListener("onDataRetrieved", 
        function(cardboard, args){
            // Grab items hash
            filteredItems = args.items;

            // loop through hash keys (states)
            for (var key in filteredItems) {

                // Grab the workproducts objects (Stories, defects)                 
                workproducts = filteredItems[key];
                // Array to hold filtered results, childless work products
                childlessWorkProducts = new Array();
                // loop through 'em and filter for the childless
                for (i=0;i<workproducts.length;i++) {
                    thisWorkProduct = workproducts[i];                      
                    // Check first if it's a User Story, since Defects don't have children
                    if (thisWorkProduct._type == "HierarchicalRequirement") {
                        if (thisWorkProduct.Children.length === 0 ) {
                            childlessWorkProducts.push(thisWorkProduct);
                        }
                    } else {
                        // If it's a Defect, it has no children so push it
                        childlessWorkProducts.push(thisWorkProduct);
                    } 
                }
                filteredItems[key] = childlessWorkProducts;
            }
            // un-necessary call to cardboard.setItems() was here - removed
        }
    );

This callback should filter for only leaf-node items.

Not sure this is your problem but your cardboard config does not set the 'query' field. The fetch is the type of all data to retrieve if you want to filter it you add a "query:" value to the config object. Something like :

        var cardboardConfig = {
         types: ["PortfolioItem", "HierarchicalRequirement", "Feature"],
         attribute: dropdownAttribute,
         fetch:"Name,FormattedID,Owner,ObjectID,ClassofService",
         query : fullQuery,
         cardRenderer: PriorityCardRenderer
    };

Where fullQuery can be constructed using the the Rally query object. You find it by searching in the SDK. Hope that maybe helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top