在拉力树网格中使用项目组合项构建项目



我想构建项目团队级别的项目组合项

项目 -1 - 功能 -1 - 特点-2

项目 - 2 - 功能 -1 - 特点-2

我无法在拉力树生成器中获得作为孩子的项目和功能,我尝试过如下:

Rally.onReady(function() {
Ext.define('Rally.example.SimpleTreeGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['PortfolioItem/Feature'],
autoLoad: true,
enableHierarchy: true
}).then({
success: this._onStoreBuilt,
scope: this
});
},
_onStoreBuilt: function(store) {
this.add({
xtype: 'rallytreegrid',
store: store,
context: this.getContext(),
enableEditing: false,
enableBulkEdit: false,
shouldShowRowActionsColumn: false,
enableRanking: false,
childEls: ["title"],
columnCfgs: [
'Name',
'State',
'Owner'
]
});
}
});

Rally.launchApp('Rally.example.SimpleTreeGrid', {
name: 'Simple Tree Grid Example'
});
});

知道了..!我以网格分组为参考并构建了网格

_createGrid: function ()
{
var filter = Ext.create('Rally.data.wsapi.Filter', { property: 'Release.Name', operator: '=', value: ReleaseBoxValue });
if (!this.down('#storygrid'))
{
this.grid = this.add({
xtype: 'rallygrid',
itemId: 'storygrid',
columnCfgs: [
{
text: 'Formatted ID', dataIndex: 'FormattedID', xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name', dataIndex: 'Name'
},                                 
{
text: 'Accepted', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(acceptedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Completed', dataIndex: 'FormattedID',
renderer: function (value)
{                                         
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(completedPercentage, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Defined', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(definedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Grooming', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(grommedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'In-Progress', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(inProgressStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Grand Total', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Optum Accepted Stories', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(acceptedStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
},
{
text: 'Stories yet to be accepted', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(completedPercentage, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;                                          
}
}
,
{
text: 'Total Stories', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var userStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
userStoriesCount++;
}
}, this);
html = '<span>' + userStoriesCount + '</span>';
return html;
}
}
,
{
text: 'Optum Accepted Stories (%)', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var accepetedCount = 0;
_.each(acceptedStories, function (record)
{
if (record.key == Release)
{
accepetedCount++;
}
}, this);

var totalStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
totalStoriesCount++;
}
}, this);
var decTotal = accepetedCount / totalStoriesCount;
if (!isNaN(decTotal))
{
html = '<span>' + Math.round((decTotal) * 100) + '%</span>';
}
else
{
html = '<span>0%</span>';
}
return html;
}
}
,
{
text: 'Stories yet to be accepted (%)', dataIndex: 'FormattedID',
renderer: function (value)
{
var Release = value;

var html = "";
var completedCount = 0;
_.each(completedPercentage, function (record)
{
if (record.key == Release)
{
completedCount++;
}
}, this);

var totalStoriesCount = 0;
_.each(totalStories, function (record)
{
if (record.key == Release)
{
totalStoriesCount++;
}
}, this);
var decTotal = completedCount / totalStoriesCount;
if (!isNaN(decTotal))
{
html = '<span>' + Math.round((decTotal) * 100) + '%</span>';
}
else
{
html = '<span>0%</span>';
}
return html;
}
}
],
context: this.getContext(),
features: [{
ftype: 'groupingsummary',
groupHeaderTpl: '{name} ({rows.length})'
}
],
filters: [filter],
storeConfig: {
model: 'portfolioitem/feature',
groupField: 'Name',
groupDir: 'ASC',                                
fetch: ['FormattedID', 'Name', 'Release', 'Project', 'UserStories', 'HierarchicalRequirement'],
filters: [filter],
getGroupString: function (record)
{
var owner = record.get('Project');
return (owner && owner._refObjectName) || 'No Name';
}
}
});
}
else
{
var filter = Ext.create('Rally.data.wsapi.Filter', { property: 'Release.Name', operator: '=', value: ReleaseBoxValue });
var treeGrid = this.down('rallygrid'),
treeStore = treeGrid.getStore();
treeStore.clearFilter(true);
treeStore.filter(filter);
}
}

最新更新