Как мне создать древовидную структуру в ралли дефектов по отношению к истории пользователя

Я могу получить древовидную структуру для пользовательских историй, но хочу, чтобы она была такой же для дефектов, которые также связаны с определенной пользовательской историей, так что на отдельном экране я могу видеть как пользовательские истории, так и связанные дефекты.

1 ответ

Вы можете использовать features: [{ftype:'groupingsummary'}] ExtJS для группировки дефектов по пользовательским историям и даже для суммирования по некоторым другим полям, в коде ниже PlanEstimate. Для группировки дефектов по пользовательской истории используется атрибут Требование по дефекту, который указывает на связанную историю. В этом примере дефекты фильтруются с помощью итерации.

Ext.define('CustomApp', {
    extend: 'Rally.app.TimeboxScopedApp',
    componentCls: 'app',
    scopeType: 'iteration',
    comboboxConfig: {
        fieldLabel: 'Select Iteration:',
        labelWidth: 100
    },
    onScopeChange: function() {
        this.makeStore();
    },
    makeStore: function() {
        var filter = Ext.create('Rally.data.wsapi.Filter', {
            property: 'Requirement',
            operator: '!=',
            value: null
        });

        filter= filter.and(this.getContext().getTimeboxScope().getQueryFilter());
        filter.toString();

        Ext.create('Rally.data.wsapi.Store', {
                model: 'Defect',
                fetch: ['ObjectID', 'FormattedID', 'Name', 'State', 'Requirement', 'PlanEstimate'],
                autoLoad: true,
                filters: [filter],
                listeners: {
                    load: this.onDataLoaded,
                    scope: this
                }
                });
    },
    onDataLoaded: function(store, records){
        if (records.length === 0) {
            this.notifyNoDefects();
        }

        else{
            if (this.notifier) {
                this.notifier.destroy();
            }
            var that = this;
            var promises = [];
            _.each(records, function(defect) {
                promises.push(this.getStory(defect, this));
            },this);

            Deft.Promise.all(promises).then({
                success: function(results) {
                    that.defects = results;
                    that.makeGrid();
                }
            });
        }

    },

    getStory: function(defect, scope) {
        var deferred = Ext.create('Deft.Deferred');
        var that = scope;
            var storyOid = defect.get('Requirement').ObjectID;
            Rally.data.ModelFactory.getModel({
            type: 'HierarchicalRequirement',
            scope: this,
            success: function(model, operation) {
                fetch: ['FormattedID','ScheduleState'],
                model.load(storyOid, {
                    scope: this,
                    success: function(record, operation) {
                        var storyScheduleState = record.get('ScheduleState');
                        var storyFid = record.get('FormattedID');
                        var defectRef = defect.get('_ref');
                        var defectOid  = defect.get('ObjectID');
                        var defectFid = defect.get('FormattedID');
                        var defectPlanEstimate = defect.get('PlanEstimate');
                        var defectName  = defect.get('Name');
                        var defectState = defect.get('State');
                        var story = defect.get('Requirement');

                        result = {
                                    "_ref"          : defectRef,
                                    "ObjectID"      : defectOid,
                                    "FormattedID"   : defectFid,
                                    "Name"          : defectName,
                                    "PlanEstimate"  : defectPlanEstimate,
                                    "State"         : defectState,
                                    "Requirement"   : story,
                                    "StoryState"    : storyScheduleState,
                                    "StoryID"       : storyFid  
                                };
                        deferred.resolve(result);    
                    }
                });
            }
        });
        return deferred; 
    },

    makeGrid: function() {
        var that = this;
        if (this.grid) {
            this.grid.destroy();
        }

        var gridStore = Ext.create('Rally.data.custom.Store', {
            data: that.defects,
            groupField: 'StoryID',
            pageSize: 1000,
        });

        this.grid = Ext.create('Rally.ui.grid.Grid', {
            itemId: 'defectGrid',
            store: gridStore,
            features: [{ftype:'groupingsummary'}],
            minHeight: 500,
            columnCfgs: [
                {
                    text: 'Formatted ID', dataIndex: 'FormattedID', xtype: 'templatecolumn',
                    tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
                },

                {
                    text: 'Name', dataIndex: 'Name', 
                },
                {
                    text: 'State', dataIndex: 'State',
                        summaryRenderer: function() {
                            return "PlanEstimate Total"; 
                        }
                },
                {
                    text: 'PlanEstimate', dataIndex: 'PlanEstimate',
                    summaryType: 'sum'
                },
                {
                    text: 'Story', dataIndex: 'Story',
                    renderer: function(val, meta, record) {
                        return '<a href="https://rally1.rallydev.com/#/detail/userstory/' + record.get('Requirement').ObjectID + '" target="_blank">' + record.get('Requirement').FormattedID + '</a>';
                    }
                },
                {
                    text: 'Story Schedule State', dataIndex: 'StoryState',
                }
            ]
        });

        this.add(this.grid);
        this.grid.reconfigure(gridStore);
    },
    notifyNoDefects: function() {
        if (this.grid) {
            this.grid.destroy();
        }
        if (this.notifier) {
            this.notifier.destroy();
        }
        this.notifier =  Ext.create('Ext.Container',{
                xtype: 'container',
                itemId: 'notifyContainer',
                html: "No Defects found matching selection."
            });
        this.add( this.notifier);  

    }
});

введите описание изображения здесь

Другие вопросы по тегам