I want a list of all the people who have revised the given user story in addition to other data.
I'm querying the Rally Lookback REST API with the following JSON data:
{
"find" : { "FormattedID": "$STORY" },
"fields" : ["ObjectID", "_ValidFrom", "_ValidTo", "Blocked", "c_KanbanState", "Owner"],
"compress" : true
}
With this query, I get the Owner's OID, like so:
{
"_ValidFrom": "2014-05-09T15:18:29.912Z",
"_ValidTo": "9999-01-01T00:00:00.000Z",
"ObjectID": 18326652440,
"Blocked": false,
"Owner": 13786838413,
"c_KanbanState": "Accepted"
}
Is there a way to hydrate that Owner field? I'd like to see "John Smith", but I'd settle for "jsmith@example.com".
If I have to use the WSAPI for this, is there a way to query for a group of Owner OIDs at once -- if so, a sample would be helpful -- or will I need to loop through the collection of values and query each Owner individually?
As Trever said, in Lookback API user fields cannot be hydrated.
As far as an example that hydrates user fields using wsapi, the code below uses shapshotstore to get snapshots where '_PreviousValues.Blocked' : {$exists: true}
, and then uses Rally.data.ModelFactory to get the DisplayName of owner in each snapshot.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
scopeType: 'iteration',
comboboxConfig: {
labelWidth: 100,
width: 300
},
launch: function() {
var that = this;
var iterationComboBox = Ext.create('Rally.ui.combobox.IterationComboBox',{
listeners:{
ready: function(combobox){
var iterationOid = combobox.getRecord().get('ObjectID');
that._loadStories(iterationOid);
},
select: function(combobox){
var iterationOid = combobox.getRecord().get('ObjectID');
this._loadStories(iterationOid);
},
scope: this
}
});
this.add(iterationComboBox);
},
_loadStories:function(iterationOid){
var that = this;
var snapshotStore = Ext.create('Rally.data.lookback.SnapshotStore', {
autoLoad:true,
find: {
'_TypeHierarchy': 'HierarchicalRequirement',
'_ProjectHierarchy': 12352608219,
'_PreviousValues.Blocked' : {$exists: true},
'Iteration': iterationOid
},
fetch: ['Name','FormattedID','ScheduleState','Blocked','_ValidFrom','_ValidTo', 'BlockedReason','Owner'],
order: 'OpenedDate DESC',
hydrate: ['Blocked','ScheduleState'],
compress: true,
listeners: {
load: function(store,records,success){
console.log("loaded %i records", records.length);
that._onStoriesLoaded(snapshotStore, records);
},
scope:this
}
});
},
_onStoriesLoaded:function(store, records){
var that = this;
var promises = [];
_.each(records, function(story) {
promises.push(that._hydrateOwner(story, that));
});
Deft.Promise.all(promises).then({
success: function(results) {
that._stories = results;
console.log('that._stories', that._stories);
that._makeGrid();
}
});
},
_hydrateOwner:function(story, scope){
var deferred = Ext.create('Deft.Deferred');
var that = scope;
var ownerDisplayName = null;
var userOid = story.get('Owner');
var storyBlocked = story.get('Blocked');
Rally.data.ModelFactory.getModel({
type: 'User',
scope: this,
success: function(model, operation) {
fetch: ['UserName', 'DisplayName'],
model.load(userOid, {
scope: this,
success: function(record, operation) {
owner = record.get('DisplayName');
var fid = story.get('FormattedID');
var state = story.get('ScheduleState');
var name = story.get('Name');
var blocked = story.get('Blocked');
result = {
"fid" : fid,
"name" : name,
"state" : state,
"blocked" : blocked,
"owner" : owner
};
deferred.resolve(result);
}
});
}
});
return deferred;
},
_makeGrid: function() {
if (this.down('#grid')) {
this.down('#grid').destroy();
}
var gridStore = Ext.create('Rally.data.custom.Store', {
data: this._stories
});
var _grid = Ext.create('Rally.ui.grid.Grid', {
itemId: 'grid',
store: gridStore,
columnCfgs: [
{
text: 'Name', dataIndex: 'name'
},
{
text: 'FormattedID', dataIndex: 'fid'
},
{
text: 'ScheduleState', dataIndex: 'state'
},
{
text: 'Blocked', dataIndex: 'blocked'
},
{
text: 'Owner', dataIndex: 'owner'
}
]
});
this.add(_grid);
this._grid.reconfigure(gridStore);
}
});