Obtaining the PortfolioItem details for User Stories - rally

I am trying to get the Portfio Item ID and Name for a User Story, using a query like:
var queryConfig = { type : 'HierarchicalRequirement', key : 'stories', fetch: 'FormattedID,Name,PortfolioItem,Parent' };
var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__', '__PROJECT_OID__', '__PROJECT_SCOPING_UP__', '__PROJECT_SCOPING_DOWN__');
and then iterating through it to pull FormattedID, Name and PortfolioItem.FormattedID, but PortfolioItem is always coming back as undefined.
The PortfolioItem the Users Stories are linked to is potentially in another Rally Project (same Workspace) and so I'm not sure if that's it.
Is there anyway I can do this?
Cheers
Martin
Fixed it!!
I needed to add:
rallyDataSource.setApiVersion('1.37');
before the call to:
rallyDataSource.findAll(queryConfig, displayUserStories);
Cheers
Martin

Related

Send Mail to a user if count of open issues greater a specific limit

how could i create a workflow which on every change of the current issue user checks the total amount of open issues for this user and if the amount is greater then lets say 5 the user gets a mail with a little warning message?
I guess this here is close to my topic, but only close:
https://youtrack-support.jetbrains.com/hc/en-us/community/posts/206582955-How-to-count-user-s-issues-
All our users have a mail in youtrack, the workflow should only work for one usergroup/project however.
Thank you and best regards
The How to count user's issues? illustrates the approach that valid for old workflow.
For the new JavaScript workflow, I suggest you use the search method for getting all open issues assigned to the required user. Then, you can use the user.notify method to send an email to this user.
You can find common information about JavaScript workflow in the JavaScript Workflow Quick Start Guide article. I hope this helps.
Here is an example that illustrates how to send a message with the assigned issues count to the user:
var entities = require('#jetbrains/youtrack-scripting-api/entities');
var search = require('#jetbrains/youtrack-scripting-api/search');
exports.rule = entities.Issue.onChange({
title: 'Assignee count',
guard: function(ctx) {
return ctx.issue.isChanged(ctx.Assignee) && ctx.issue.fields.Assignee;
},
action: function(ctx) {
var issue = ctx.issue;
var user = issue.fields.Assignee;
var query = 'for: ' + user.login + ' #Unresolved';
var assignedToUser = search.search(issue.project, query, ctx.currentUser);
var count = assignedToUser.size;
var subj = 'Attention!';
var body = 'You have ' + count + ' assigned issues';
user.notify(subj, body);
},
requirements: {
Assignee: {
type: entities.User.fieldType
}
}
});

Sencha Touch 2: Load a List from a store.queryBy result

I had a List that used to work when it was bound directly to a store but now I want that list to get it's data from a queryBy on the original store.
Looking at the documentation is seems like setItems should do what I want.
var myStore = Ext.getStore('myStoreData');
var myData = myStore.queryBy(function(item) {
return item.get('status') !== null;
});
// At this point myData looks valid and has the data I want.
// Ext.apply.create.Class {all: Array[5], items: Array[5], keys: Array[5], indices: Object, map: Object…}
Ext.getCmp('myListComponent').setItems(myData.items);
I keep getting the error "Object [object Object] has no method 'getItemId'". I tried various other incantations but without success. I also took a look at setData and add but without success.
========================
After getting Thiem's answer I just ended up creating a function that would create a filtered copy of an existing store and then just setting the List store to that. Code below for others edification...
storeCopy: function(store, filterBy) {
var records = [];
var allRecords = null;
if(filterBy)
allRecords= store.queryBy(filterBy);
else
allRecords= store.queryBy(function(){return true;});
allRecords.each(function(r){
var rec = r.copy();
rec.setId(r.getId());
records.push(rec);
});
var store2 = new Ext.data.Store({
recordType: store.recordType
});
store2.add(records);
return store2;
},
Thanks all.
setItems method does a totally different thing. For example, says you have an Ext.Container which consists of a form, some fields, and some interaction buttons. These things are call child components, or items of the container. They are oftenly declared in the items config of the parent container and setItems is designed to programmatically set the value of that config. So it has nothing to do with the store logic.
In your situation, here is one of the solutions:
Create a store instance which contains filtered data.
Use this command: yourList.setStore('yourFilteredStore')
And it should reload... hope this helps

Rally Kanban for Logged In Owner

I'm new to Rally's SDK. I'm trying to create a Kanban board that only shows the cards where the owner field = the person who's logged in (i.e. a My Kanban Board). What code should I add and where should I add it?
The following isn't my ideal answer to this issue, but I'd thought I'd post in case it helps someone else. I took the code from the Filter Epic post as suggested and modified it. It's not ideal for me because the filter occurs after the initial data pull, so it is only filtering the first 100 records the initial query pulled. Ideally, I want to change the initial pull of data to filter on username.
After this code in the Filtering Epic:
for (i=0;i<workproducts.length;i++) {
thisWorkProduct = workproducts[i];
Add:
//get the owner field value
var owner = "";
if (thisWorkProduct.Owner) {
if (thisWorkProduct.Owner.DisplayName) {
owner = thisWorkProduct.Owner.DisplayName;
}
else if (thisWorkProduct.Owner.UserName) {
owner = thisWorkProduct.Owner.UserName;
}
}
And then change:
if (thisWorkProduct.Children.length === 0) {
To:
if ((thisWorkProduct.Children.length === 0) && (owner === "__USER_NAME__")) {
And add in an if in the defects else (so it will now look like this):
else {
// If it's a Defect, it has no children so push it
if (owner === "__USER_NAME__") {
childlessWorkProducts.push(thisWorkProduct);
}
It's probably not the most efficient code because I'm new to javascript.
And if anyone has suggestions on how to do the username filter in the initial data pull, I'd love to hear them.
You can filter on the initial data pull by including a query in the cardboardConfig object:
var cardboardConfig = {
//... other properties
query: new rally.sdk.util.Query('Owner = /user/__USER_OID__')
};
Check out this answer:
Filtering epics from Kanban board
It would be pretty straightforward to adapt the filtering callback to filter by Owner instead of just child-less artifacts.

Dojo: Can't update drop down list after adding a new group

I've been playing around with IBM's tutorial at this link.
http://www.ibm.com/developerworks/web/tutorials/wa-dojotoolkit/section6.html
I've done very well so far, but I can't seem to get the drop down list to populate the new group entry. Even the original code isn't working.
//Refresh the data store for the groups dropdown (in case groups added, edited or deleted)
function refreshGroupDropDown() {
var theStore = dijit.byId("edit_contact_group").store;
theStore.close();
theStore.url = "data/groups.php";
theStore.fetch();
}
Thanks!
Update: Still having trouble. I tried this below and still nothing. The function refreshGroupDropDown() is called when the user opens the edit contact windows or new contact window.
//Refresh the data store for the groups dropdown (in case groups added, edited or deleted)
function refreshGroupDropDown() {
var new_store = new ItemFileReadStore({url: 'data/groups.php' , clearOnClose: true});
var theStore = dijit.byId("edit_contact_group");
theStore.store = new_store;
theStore.close();
theStore.fetch();
}
//Clears the "Edit Contact" form, sets it up for adding a new contact
function newContact() {
var contact = contactsGrid.selection.getSelected()[0];
refreshGroupDropDown();
dojo.byId("edit_contact_real_id").value = "";
dojo.byId("edit_contact_id").value = "[NEW]";
dijit.byId("edit_contact_group").reset();
dijit.byId("edit_contact_first_name").reset();
dijit.byId("edit_contact_last_name").reset();
dijit.byId("edit_contact_email_address").reset();
dijit.byId("edit_contact_home_phone").reset();
dijit.byId("edit_contact_work_phone").reset();
dijit.byId("editContactDialog").set("title", "New Contact");
dijit.byId("editContactDialog").show();
}
//Process the adding of a new group to the database
function doNewGroup(e) {
e.preventDefault();
e.stopPropagation();
dojo.byId("new_group_ajax").value = "1";
if(this.isValid()) {
dojo.xhrPost({
form: this.domNode,
handleAs: "json",
load: function(data) {
if(data.success) {
okDialog.set("title","Group created successfully");
okDialogMsg.innerHTML = "The group <strong>"+data.name+"</strong> was created successfully.";
groupsStore.newItem({"id":data.id.toString(),"name":data.name}, {"parent": groupsModel.root, "attribute":"groups"});
groupsStore.save();
newGroupDialog.hide();
okDialog.show();
}
else {
okDialog.set("title","Error creating group");
okDialogMsg.innerHTML = data.error;
okDialog.show();
}
},
error: function(error) {
okDialog.set("title","Error creating group");
okDialogMsg.innerHTML = error;
okDialog.show();
}
});
}
}
Hopefully this helps! I'm a beginner so any help is appreciated.
I figured it out! The issue was with the index.html. The input tag for the groups drop-down list looks like this
<input dojoType="dijit.form.FilteringSelect" name="move_contact_new" store="groupsStore" searchAttr="name" query="{type:'node'}" id="move_contact_new" required="true" style="margin-bottom: 6px" />
The query attribute was never set correctly. Once I deleted query="{type:'node'}" the groups re-populate after adding, editing, or deleting groups.
A beginner answer for a beginner question.
Hope this can help any beginners out there.
Based on what you've posted, the only problem I see is with the line var theStore = dijit.byId("edit_contact_group").store;because it doesn't acutally create a dataStore. You need to make sure you also include something like `var edit_contact_group = new dojo.data.ItemFileReadStore();or an equivalent. Othewise, have you connected the refreshGroupDropDown() function to the appropriated event ('onclick' or whatever) using dojo.connect()? Have you loaded the function refreshGroupDropDown() using dojo.ready? ie. dojo.ready(function(){refreshGroupDropDown();});Those are always the first things that come to mind...

How to refresh datagrid

I create dojox.grid.datagrid and I fill content from array like on example last example on page. During time, I change value of that array in code. How to refresh content of that grid ? How to load new data from changed array ?
To change values in the grid, you will need to change the value in the grid's store. The grid data is bound to the store data, and the grid will update itself as needed.
So the key is to understand Dojo's data api and how stores work in Dojo. Rather than manipulating the data directly in the grid, manipulate it in the store.
Ideally, the store is your array that you manipulate as the application runs and you should not be needing to sync the array to the grid. Just use the ItemFileWriteStore as your data holder unless thats not possible.
Also, using the dojo data identity api makes it much simple to find items in the grid if that is possible. Assuming you know when an item is updated, deleted, or changed in your application you should be able to modify the grid store as needed when the action happens. This is definitely the preferred approach. If you can't do that you will have to do a general fetch and use the onComplete callback to manually sync your arrays which will be very slow and won't scale well, in which case you may as well just create a new store all together and assign it to the grid with grid.setStore(myNewStore)
Here is a fiddle with a basic create, update, and delete operation: http://jsfiddle.net/BC7yT/11/
These examples all take advantage of declaring an identity when creating the store.
var store = new dojo.data.ItemFileWriteStore({
data: {
identifier : 'planet',
items: itemList
}
});
UPDATE AN EXISITNG ITEM:
//If the store is not in your scope you can get it from the grid
var store = grid.store;
//fetchItemByIdentity would be faster here, but this uses query just to show
//it is also possible
store.fetch({query : {planet : 'Zoron'},
onItem : function (item ) {
var humans = store.getValue(item, 'humanPop');
humans += 200;
store.setValue(item, 'humanPop', humans);
}
});
INSERT A NEW ITEM:
store.newItem({planet: 'Endron', humanPop : 40000, alienPop : 9000});
} catch (e) {
//An item with the same identity already exists
}
DELETE AN ITEM:
store.fetchItemByIdentity({ 'identity' : 'Gaxula', onItem : function (item ) {
if(item == null) {
//Item does not exist
} else {
store.deleteItem(item);
}
}});
The following code snippet can be used to update the grid:
var newStore = new dojo.data.ItemFileReadStore({data: {... some new data ...});
var grid = dijit.byId("gridId");
grid.setStore(newStore);
EDIT:
Dogo data grid reference guide (add/remove rows example, updating grid data examples )
(I suppose you already have a working grid and you want to completely change the grid's store)
Create a new datastore with your new value :
dataStore = new ObjectStore({ objectStore:new Memory({ data: data.items }) });
(data is the reponse from an ajax request for me)
Change your grid's store with the new one :
grid.store = dataStore;
Render :
grid.render();
This Will update Grid Store and refresh the View of the Grid in latest Version of Dojo 1.9
grid.store = store;
grid._refresh();
I had a server-side filtered EnhancedGrid, which was refreshing happily by changing the store, and shown in the other answers.
However I had another EnhancedGrid that would not refresh when a filter was applied. It may have been to do with the fact it was filtered client side (but data still coming from server using JsonRest store), but I don't really know the cause. Eitherway, the solution was to refresh with the following code:
grid.setFilter(grid.getFilter());
It's hacky and strange, but if it all else fails...
with this i can update a specifi row. this example is for a treegrid.
var idx = this.treeGrid.getItemIndex(item);
if(typeof idx == "string"){
this.treeGrid.updateRow(idx.split('/')[0]);
}else if(idx > -1){
this.treeGrid.updateRow(idx);
}