Отчет о списке клиентов, который имеет все дефекты в зависимости от версии пользовательской истории
Я хотел бы получить отчет или настраиваемый список, в котором отображаются все дефекты, в которых среда с дефектами является производственной, а выпуск родительской / связанной пользовательской истории совпадает с выпадающим выпуском на пользовательском экране.
Я нашел эту историю, и она близка, я думаю, но не уверен, как связать ее с выпадающим выпуском, а также не уверен, как отобразить пользовательскую историю, с которой связан дефект.
РАЛЛИ: Определите выпуск родительской истории пользователя.
Выходными данными должны быть идентификатор и имя пользовательской истории, а также идентификатор и имя дефекта и, возможно, еще несколько столбцов.
Я знаю, что мог бы сделать это через API, но пытался выяснить, есть ли другой способ в существующих инструментах Rally.
Заранее благодарю за любую помощь!
1 ответ
Тебе повезло! Я не могу писать приложения так часто, как мне бы хотелось, и у меня было немного свободного времени сегодня днем, поэтому я кое-что подобрал для вас. Просто создайте настраиваемую страницу с выделенной версией и добавьте этот код в приложение HTML на этой странице.
Приложение включает в себя средство выбора полей для изменения отображаемого набора полей. Я сделал предположение о некоторых полезных для начала. Он также включает в себя элемент управления для включения печати и экспорта.
<!DOCTYPE html>
<html>
<head>
<title>DefectsByStoryInRelease</title>
<script type="text/javascript" src="/apps/2.0/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function () {
Ext.define('DefectsByStoryInRelease', {
extend: 'Rally.app.TimeboxScopedApp',
componentCls: 'app',
scopeType: 'release',
onScopeChange: function () {
Ext.create('Rally.data.wsapi.TreeStoreBuilder').build({
models: ['defect'],
autoLoad: true,
enableHierarchy: true,
filters: this._getFilters()
}).then({
success: this._onStoreBuilt,
scope: this
});
},
_onStoreBuilt: function (store) {
var modelNames = ['defect'],
context = this.getContext(),
gridBoard = this.down('rallygridboard');
if (gridBoard) {
gridBoard.destroy();
}
this.add({
xtype: 'rallygridboard',
height: this.getHeight() - ((this.getHeader() && this.getHeader().getHeight()) || 0),
context: context,
modelNames: modelNames,
toggleState: 'grid',
stateful: false,
plugins: [
{
ptype: 'rallygridboardfieldpicker',
headerPosition: 'left',
modelNames: modelNames,
stateful: true,
stateId: context.getScopedStateId('fields')
},
{
ptype: 'rallygridboardactionsmenu',
menuItems: [
{
text: 'Export...',
handler: function () {
window.location = Rally.ui.grid.GridCsvExport.buildCsvExportUrl(
this.down('rallygridboard').getGridOrBoard());
},
scope: this
},
{
text: 'Print...',
handler: function () {
Ext.create('Rally.ui.grid.TreeGridPrintDialog', {
grid: this.down('rallygridboard').getGridOrBoard(),
treeGridPrinterConfig: {
largeHeaderText: 'Defects'
}
});
},
scope: this
}
],
buttonConfig: {
iconCls: 'icon-export'
}
}
],
gridConfig: {
store: store,
columnCfgs: [
'Name',
'Requirement',
'State',
'Priority',
'Severity'
]
}
});
},
_getFilters: function () {
var scope = this.getContext().getTimeboxScope(),
release = scope.getRecord(),
filters = [{
property: 'Environment',
value: 'Production'
}];
if (release) {
filters = filters.concat([
{
property: 'Requirement.Release.Name',
value: release.get('Name')
},
{
property: 'Requirement.Release.ReleaseStartDate',
value: release.get('ReleaseStartDate')
},
{
property: 'Requirement.Release.ReleaseDate',
value: release.get('ReleaseDate')
}
]);
} else {
filters.push({
property: 'Requirement.Release',
value: null
});
}
return filters;
}
});
Rally.launchApp('DefectsByStoryInRelease', {
name: "DefectsByStoryInRelease",
parentRepos: ""
});
});
</script>
<style type="text/css">
.app {
/* Add app styles here */
}
</style>