Question

I saw that Rally made available its custom grid in github, so I downloaded the Rally app-catalog from github. I then went into the src/apps/grid directory and ran 'rally-app-builder build'. That created the deploy directory and the following code in App.html:

<!DOCTYPE html>
<html>
<head>
<title>Custom Grid</title>
<script type="text/javascript" src="/apps/2.0rc2/sdk.js"></script>
<script type="text/javascript">
    Rally.onReady(function () {
            (function(){var Ext=window.Ext4||window.Ext,appAutoScroll=Ext.isIE7||Ext.isIE8,gridAutoScroll=!appAutoScroll;Ext.define("Rally.apps.grid.GridApp",{extend:"Rally.app.App",layout:"fit",requires:["Rally.data.util.Sorter","Rally.data.QueryFilter","Rally.ui.grid.Grid","Rally.ui.grid.plugin.PercentDonePopoverPlugin"],autoScroll:appAutoScroll,launch:function(){Rally.data.ModelFactory.getModel({type:this.getContext().get("objectType"),success:this._createGrid,scope:this})},_getFetchOnlyFields:function(){return["LatestDiscussionAgeInMinutes"]},_createGrid:function(model){var context=this.getContext(),pageSize=context.get("pageSize"),fetch=context.get("fetch"),columns=this._getColumns(fetch),gridConfig={xtype:"rallygrid",model:model,columnCfgs:columns,enableColumnHide:!1,enableRanking:!0,enableBulkEdit:Rally.environment.getContext().isFeatureEnabled("EXT4_GRID_BULK_EDIT"),autoScroll:gridAutoScroll,plugins:this._getPlugins(columns),storeConfig:{fetch:fetch,sorters:Rally.data.util.Sorter.sorters(context.get("order")),context:context.getDataContext(),listeners:{load:this._updateAppContainerSize,scope:this}},pagingToolbarCfg:{pageSizes:[pageSize]}};pageSize&&(pageSize-=0,isNaN(pageSize)||(gridConfig.storeConfig.pageSize=pageSize)),context.get("query")&&(gridConfig.storeConfig.filters=[Rally.data.QueryFilter.fromQueryString(context.get("query"))]),this.add(gridConfig)},_updateAppContainerSize:function(){if(this.appContainer){var grid=this.down("rallygrid");grid.el.setHeight("auto"),grid.body.setHeight("auto"),grid.view.el.setHeight("auto"),this.setSize({height:grid.getHeight()+_.reduce(grid.getDockedItems(),function(acc,item){return acc+item.getHeight()+item.el.getMargin("tb")},0)}),this.appContainer.setPanelHeightToAppHeight()}},_getColumns:function(fetch){return fetch?Ext.Array.difference(fetch.split(","),this._getFetchOnlyFields()):[]},_getPlugins:function(columns){var plugins=[];return Ext.Array.intersect(columns,["PercentDoneByStoryPlanEstimate","PercentDoneByStoryCount"]).length>0&&plugins.push("rallypercentdonepopoverplugin"),plugins}})})();

        Rally.launchApp('Rally.apps.grid.GridApp', {
            name:"Custom Grid",
            parentRepos:""
        });

    });
</script>
</head>
<body></body>
</html>

...but when you paste that into Rally, it just produces and empty app (frame with no contents).

Am I missing something simple here? Are there some tweaks I need to make to get this to work?

Was it helpful?

Solution

I just remembered I fixed the custom grid up quite a bit after 2.0rc2 was cut. You can see that here in the RallySoftware/app-catalog repo. (We only guarantee these apps work with the head revision of the sdk (version x) but in this case the grid correctly works with 2.0rc2 as well).

Note: it does not have a settings panel yet.

Below is the full html with some default settings filled in:

<!DOCTYPE html>
<html>
<head>
    <title>Custom Grid</title>
    <script type="text/javascript" src="/apps/2.0rc2/sdk.js"></script>
    <script type="text/javascript">
        Rally.onReady(function () {
            (function () {
                var Ext = window.Ext4 || window.Ext;
                var appAutoScroll = Ext.isIE7 || Ext.isIE8;
                var gridAutoScroll = !appAutoScroll;

                Ext.define('Rally.apps.grid.GridApp', {
                    extend: 'Rally.app.App',
                    layout: 'fit',

                    requires: [
                        'Rally.data.util.Sorter',
                        'Rally.data.wsapi.Filter',
                        'Rally.ui.grid.Grid',
                        'Rally.data.ModelFactory',
                        'Rally.ui.grid.plugin.PercentDonePopoverPlugin'
                    ],

                    config: {
                        defaultSettings: {
                            types: 'defect',
                            pageSize: 25,
                            fetch: 'FormattedID,Name,Priority,Severity'
                        }
                    },

                    autoScroll: appAutoScroll,

                    launch: function () {
                        var context = this.getContext(),
                                pageSize = this.getSetting('pageSize'),
                                fetch = this.getSetting('fetch'),
                                columns = this._getColumns(fetch);

                        this.add({
                            xtype: 'rallygrid',
                            columnCfgs: columns,
                            enableColumnHide: false,
                            enableRanking: true,
                            enableBulkEdit: context.isFeatureEnabled("EXT4_GRID_BULK_EDIT"),
                            autoScroll: gridAutoScroll,
                            plugins: this._getPlugins(columns),
                            context: this.getContext(),
                            storeConfig: {
                                fetch: fetch,
                                models: this.getSetting('types').split(','),
                                filters: this._getFilters(),
                                pageSize: pageSize,
                                sorters: Rally.data.util.Sorter.sorters(this.getSetting('order')),
                                listeners: {
                                    load: this._updateAppContainerSize,
                                    scope: this
                                }
                            },
                            pagingToolbarCfg: {
                                pageSizes: [pageSize]
                            }
                        });
                    },

                    onTimeboxScopeChange: function (newTimeboxScope) {
                        this.callParent(arguments);

                        this.down('rallygrid').filter(this._getFilters(), true, true);
                    },

                    _getFilters: function () {
                        var filters = [],
                                query = this.getSetting('query'),
                                timeboxScope = this.getContext().getTimeboxScope();
                        if (query) {
                            try {
                                query = new Ext.Template(query).apply({
                                    user: Rally.util.Ref.getRelativeUri(this.getContext().getUser())
                                });
                            } catch (e) {
                            }
                            filters.push(Rally.data.wsapi.Filter.fromQueryString(query));
                        }

                        if (timeboxScope && _.every(this.getSetting('types').split(','), this._isSchedulableType, this)) {
                            filters.push(timeboxScope.getQueryFilter());
                        }
                        return filters;
                    },

                    _isSchedulableType: function (type) {
                        return _.contains(['hierarchicalrequirement', 'task', 'defect', 'defectsuite', 'testset'], type.toLowerCase());
                    },

                    _getFetchOnlyFields: function () {
                        return ['LatestDiscussionAgeInMinutes'];
                    },

                    _updateAppContainerSize: function () {
                        if (this.appContainer) {
                            var grid = this.down('rallygrid');
                            grid.el.setHeight('auto');
                            grid.body.setHeight('auto');
                            grid.view.el.setHeight('auto');
                            this.setSize({height: grid.getHeight() + _.reduce(grid.getDockedItems(), function (acc, item) {
                                return acc + item.getHeight() + item.el.getMargin('tb');
                            }, 0)});
                            this.appContainer.setPanelHeightToAppHeight();
                        }
                    },

                    _getColumns: function (fetch) {
                        if (fetch) {
                            return Ext.Array.difference(fetch.split(','), this._getFetchOnlyFields());
                        }
                        return [];
                    },

                    _getPlugins: function (columns) {
                        var plugins = [];

                        if (Ext.Array.intersect(columns, ['PercentDoneByStoryPlanEstimate', 'PercentDoneByStoryCount']).length > 0) {
                            plugins.push('rallypercentdonepopoverplugin');
                        }

                        return plugins;
                    }
                });
            })();

            Rally.launchApp('Rally.apps.grid.GridApp', {
                name: "Custom Grid"
            });

        });
    </script>
</head>
<body></body>
</html>

Hopefully this gets you by for now. Look for a much improved custom grid app coinciding with the next public sdk release.

OTHER TIPS

You are not missing anything. When we cut the next release it will be working, but right now the app has not been toggled on. What makes it empty is that type below does not resolve:

Rally.data.ModelFactory.getModel({
                type: this.getContext().get('objectType'),
                success: this._createGrid,
                scope: this
            });

unless you hard code it instead, as in type: 'defect' . Unfortunately this is not enough to fix it. The app is not ready to be used yet.

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