Query to retrieve defects from parent and children - rally

I have inherited code that displays a graph of defects on a project. I have now took my project and split it into two projects, so that now there is a parent project and two children. The code (below) just accumulates the defects from the parent and does not include the data from the children.
snippet:
storeType: "Rally.data.lookback.SnapshotStore",
storeConfig: {
find: { _TypeHierarchy: "Defect", Children: null },
fetch: ["Severity", "State"], hydrate: ["Severity", "State"],
sort: { _ValidFrom: 1 },
filters: [{ property: "Project", value: context.getProject().ObjectID }, { property: "_TypeHierarchy", value: "Defect" }, { property: "Children", value: null}] },
So I'm pretty sure the problem is in this part "value: context.getProject().ObjectID" as it says to get the data from the current project (and not its children). How can I accomplish what I need?

Not sure if you're intending to get lookback (time series) data or current (WSAPI) data from Rally. Your code implies lookback so I will answer with that in mind.
You could try adding to your find clause (and removing the current Project filter):
"_ProjectHierarchy": { $in : [123] }
where 123 is the object id of your parent project. That should get defects from any projects that include you parent project in the hierarchy.

So Igor basically got it above, just writing as a post and not in a commet, this is the code that works - you can see why in the comments above. Please note - I did make one change over what he wrote, as when I used the "__At" it caused not all bugs to be counted - it looked like it only counted bugs since their last update time.
storeConfig: {
find: { _TypeHierarchy: "Defect", _ProjectHierarchy: context.getProject().ObjectID},
fetch: ["Severity", "State"], hydrate: ["Severity", "State"],
sort: { _ValidFrom: 1 },
},

Related

Usergrid query on unknown sub properties

I'm trying to query a collection of data with entities that contain the "related" property:
...,{ related :
{ global: [{name: "foo"}, {name: "bar"}] },
{ local: [{name: "bar"}] },
{ random: [{name: "foo"}] },
{ dingbat: [{name: "baz"}] },
}
I want to write a query which selects all entities which have name="foo" anywhere within the related property.
I can do this just fine:
select * where related.global.name='foo'
However there could be any number of keys within the "related" property so I can't just AND them all into a single query. Trying to do something like this (which doesn't work)
select * where related.*.name='foo'
Is there any way to achieve this?
Not at this time. However, it is something we could consider for the future. We have ElasticSearch for indexing in our 2.1 platform and we can use the '_all' functionality from ES but we have not exposed that in Usergrid yet.

Creating a StoryMap app using the rallycardboard

I'd like to put together a StoryMap app using Initiative (second level) portfolio items as the backbone (columns). To do this the app needs to query for all the second level portfolio items, and then use each PI as a column header in the rallycardboard.
I've gotten the cardboard to display the column headers correctly, but I have not been able to get it to display the cards, which should be the first level of portfolio items (PortfolioItem/Feature).
Here is my code so far:
launch: function() {
this._getInitiativeStore();
},
_getInitiativeStore: function() {
this.initiativeStore = Ext.create('Rally.data.wsapi.Store', {
model: 'PortfolioItem/Initiative',
fetch: ['Name', 'Children'],
autoLoad: true,
listeners: {
load: this._createCardBoard,
scope: this
}
});
},
_createCardBoard: function(store, records) {
var initiativeColumns = [];
Ext.each(records, function(record) {
initiativeColumns.push({
xtype: 'rallycardboardcolumn',
columnHeaderConfig: {
xtype: 'rallycardboardcolumnheader',
fieldToDisplay: 'Name',
record: record,
},
cardConfig: {
xtype: 'rallycard',
record: 'PortfolioItem/Feature'
},
fields: ['Name', 'Parent'],
valueField: 'Parent',
value: record.get('_ref') // BUG FIXED HERE. Was: record.get('Parent')
});
}, this);
var cardBoardConfig = {
xtype: 'rallycardboard',
types: ['PortfolioItem/Feature'],
columns: initiativeColumns,
attribute: 'Parent',
};
var cardBoard = this.add(cardBoardConfig);
console.log('cardboard', cardBoard);
}
I realize I am using this perhaps a bit differently than the authors have planned for, but I'm willing to extend the rallycardboard and rallycolumnheader objects with Ext.define if that's what it takes. I'm starting to look at the Rally source code but its slow going so far.
I was able to figure out the problem by using Ext.define() to override the cardboardcolumn getStoreFilter function to print out its filter value. Probably for somebody good with a browser debugger that would not have been necessary, but I'm not and it pinpointed the problem right away: The "value" field of the initiativeColumn configs should have been record.get('_ref'), not record.get('Parent'). I'll edit the code above so it works.
Now the basic board works great as a story map with portfolio items! Next step is to see if I can incorporate the concept of releases into the map.
Also, I think I found a bug in the 'rallycardboard' constructor-- if I pass it a context reference like: context: { project: 'project/XXX'} where XXX is an OID, it crashes. Instead I need to instantiate a context object and pass that. But that's inconsistent from other items like the wsapi store. Workaround is easy, but it is a bit annoying.

Using BulkRecordUpdater

When attepming to use a Rally.data.BulkRecordUpdater, I ran into a few problems. First of all, the documentation is incorrect. The example provided:
Rally.data.BulkRecordUpdater({
records: [record1, record2],
propertiesToUpdate: {
Parent: '/hierarchicalrequirement/123.js'
},
success: function(readOnlyRecords){
//all updates finished, except for given read only records
},
scope: this
});
should be:
Rally.data.BulkRecordUpdater.updateRecords({
records: [record1, record2],
propertiesToUpdate: {
Parent: '/hierarchicalrequirement/123.js'
},
success: function(readOnlyRecords){
//all updates finished, except for given read only records
},
scope: this
});
Secondly, when trying to use this method to update records I keep getting an error for being unable to call the method 'get' - I am assuming that this is because the records I am providing are not in the correct format. I am simply calling this on records I pull from a wsapi query. I have tried putting the object inside of another object:
{data: record}
but it still does not seem to help. Any ideas would be greatly appreciated!
Thanks for pointing out the doc issue. I'm filing a defect to fix this.
The records should be instances of Rally.domain.WsapiModel. If you are using Rally.data.WsapiDataStore to retrieve them then you should be all set. Are you doing something different?
For what it's worth, we're also currently working on another, better way to do batch updates of records. Look for it in a future SDK!
See this example if it helps
_justFunction: function(_childObj) {
records = ["abc", "xyz"];
var store = Ext.create('Rally.data.custom.Store', {
data: records,
listeners: {
load: that._updateAll,
scope: that
},
});
},
_updateAll: function(store,data) {
Rally.data.BulkRecordUpdater.updateRecords({
records: data,
propertiesToUpdate: {
Parent: _newParent.get("_ref")
},
success: function(readOnlyRecords){
//all updates finished, except for given read only records
},
scope: that
});
},

Inconsistencies in RPM hierarchy scoping

I am working to create an RPM tree that can be used to select leaf stories from different levels of the RPM hierarchy.
I was able to get close to the desired functionality by using the method described here, however there appear to be some inconsistencies in the number of leaf stories being returned at each level of the RPM.
The following Image shows the tree (Project names covered for privacy purposes). The yellow badges show the number of leaf stories found below that level of the RPM hierarchy. As you can see from the image, the numbers are inconsistent. (Below the Initiative shows 23 leaf stories and below one of the Rollups shows 44.) There are in fact 44 leaf stories below that Rollup so the problem appears to be from querying at the Initiative level.
Here is the function I wrote which is intended to return an array of all the OIDs for leaf stories below the selected RPM node:
function getDescendants(OID, callback) {
Ext.create('Rally.data.lookback.SnapshotStore', {
autoLoad: true,
pageSize: 1000000,
fetch: ['ObjectID'],
filters: [
{ property: '_ItemHierarchy', value: OID },
{ property: 'Children', value: null },
{ property: '__At', value: new Date().toISOString() },
{ property: '_TypeHierarchy', value: 'HierarchicalRequirement' }
],
listeners: {
load: function(model, data, success) {
if (data && data.length && success) {
var descendants = [];
Ext.Array.each(data, function(story) {
descendants.push(story.get('ObjectID'));
});
callback(Ext.Array.unique(descendants));
} else {
callback([]);
}
}
}
});
}
That query looks correct to me. I think you've encountered a known defect that existed in the data stream to the Lookback API. The problem in the stream has been corrected, but the work to go back and correct the faulty history is still in the team backlog. If you want to track its progress with Support, the defect has ID DE15647.
The workaround (since you're only querying the current data) is to un-parent and re-parent affected items.
Sorry.
Edit: Some more detail on the problem - For a period of time, whenever a PortfolioItem (Strategy, Theme, Feature, Initiative) was created and had its parent set at the same time, the Lookback API service didn't get notified of the new PortfolioItem's parent. This problem is now resolved, but the old data is still to be fixed. You could search for PIs that potentially have this problem by looking for ones in that _ItemHierarchy with a null Parent field.
To get the PIs with null parents (potential orphans):
fetch: ['ObjectID', '_ValidFrom', '_ValidTo'],
filters: [
{ property: '_ItemHierarchy', value: OID }, // only include this if you're limiting to a sub-hierarchy
{ property: '_TypeHierarchy', value: 'PortfolioItem' },
{ property: 'Parent', value: null },
{ property: '__At', value: 'current' }
]
For each of these 'orphans', check for a parent that has it as a child:
fetch: ['ObjectID'],
filters: [
{ property: 'Children', value: currentChild.ObjectID },
{ property: '_TypeHierarchy', value: 'PortfolioItem' },
{ property: '_ValidFrom', operator: '<=' value: currentChild._ValidFrom.toISOString() },
{ property: '_ValidTo', operator: '>' value: currentChild._ValidFrom.toISOString() }
]
For each one, if you find a parent that's claiming the child (at the time the child was created), you know you've a snapshot affected by this problem and can fix it by clearing its parent in ALM, saving, then resetting its parent and saving again. I included __At: 'current' in the first check, since there's a chance the orphaned PI had a different parent assigned later and you wouldn't want to overwrite that. Hope this helps.

getNextIteration

Using API 2.0, I am working on a super kanban board, and when rendering the card I want a button that will move the story to the next sprint.
I started with adding the iteration combo, but that is overkill. I can add the button and the code, but is there a way to get the next iteration?
I dont see anything out there, thought I would ask here before I started coding.
The kanban board is iteration specific, so i could move up a sprint or two and still want to push it forward, so figure I have to grab the current iteration and somehow get the next one...
Thoughts?
You can query for iterations where the start date is after today, ordered by start date. That should give you the next iteration in records[0]...
Ext.create('Rally.data.WsapiDataStore', {
model: 'Iteration',
fetch: ['Name', 'StartDate', 'EndDate'],
autoLoad: true,
sorters: [
{
property: 'StartDate'
direction: 'ASC'
}
],
filters: [
{
property: 'StartDate',
operator: '>',
value: Rally.util.DateTime.toIsoString(new Date())
}
],
listeners: {
load: function(store, records) {
var nextIteration = records[0];
}
}
});