How to add Links to a Workitem in RTC 5.x (JS/Dojo)
Does someone know how to add a "parentLink" to an existing Workitem.
The Idea is to clone a WI and then add the parent link to the cloned WI.
Maybe I can relate the WI on creation with the Link?
I use this class to get the Item:
com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory
var params = {
includeHistory: false,
newWorkItem: true,
projectAreaItemId: pid,
typeId: "com.ibm.team.apt.workItemType.story"
}
var newProxy = WorkItemProxyFactory.getWorkItemProxy(params);
//Create new Item:
newProxy.initialize(projectArea, type, newWorkitem, includeHistory) //Maybe it's possible to add links here?
//Before I add some attributes like name, description etc
//My Idea here was, to extract the Links, and add it in the same way to the new Item.
workItemToSave.storedObject.linkTypes = parentLink; //itemToSave is "newProxy"
//Store, save it on the DB
newProxy.storeWorkItem();
Accepted answer
I don't really like blogging.
But I'll describe it here.
First you should read this Post about how the whole Workitem-System works.
https://jazz.net/wiki/bin/view/Main/WorkItemWebItemProxyDesign
Long story short:
With store and fetch you interact direct with the REST-Client (Store on DB)
Store = Save it on DB
Fetch = Get it from DB
Everything in this "workItemproxy" is kinda like a runtime copy of the actual WI.
Now I gonna try to clarify how to interact with those Workitems.
First, get the workItemProxy class.
dojo.require("com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory");
I instantiate it for easier use:
var WorkItemProxyFactory = com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory;
Now we gonna create a new WIProxy:
var params = {createIfNeeded: true};
var newProxy = WorkItemProxyFactory.getWorkItemProxy(params);
//If you want an WIProxy of an existing WI:
var params = { id: "itemId of the wished WI",
createIfNeeded: true,
doNotCache: true,
doNotGetFromCache:true};
var workingCopyProxy = WorkItemProxyFactory.getWorkItemProxy(params);
//Initialize the WI
//After the initialization, you'll see an unsaved WI in the MenuBar "Work Items".
var params = {projectAreaItemId: "The ItemId of your project",
type: "com.ibm.team.apt.workItemType.story", //Story, epic, whatever you need
newWorkItem: true,
includeHistory: false};
newProxy.initialize(params);
//Get the Links from the workingCopy
var linkTypeArray = workingCopyProxy.object.linkTypes //Here are all Links to this actual WI stored.
//Otherwise you could use:
var linkTypeArray = workingCopyProxy.getLinkTypesToWorkItem(workingCopyProxy);
//If you search specific LinkTypes, use the endpointId
//I.E. linkTypeArray[x].endpointId == 'parent' //To get the parentLink
//Now HOW TO ADD THE WISHED LINKS
var param = {
addLinkType: linkTypeArray, //It has to be an Array
addLinkedProjectAreaItemId: null, //I don't know what this shold do.
addLinkedItemId: newProxy.object.itemId, // It's the ItemId of itself
addLinkIsSource: linkTypeArray[0].isSource, //Mostly this is "false"
}
newProxy.addLinkTarget(param);
//At this point ONLY your runtime copy is actualized! You have to store now your WI to save it on the DB
newProxy.storeWorkItem({
self: this,
operationMsg: "Saving",
applyDelta: true,
onSuccess: function(param) {
//Do what you need
}
});
Et Voilà the Item is created and saved with the wished links.
Comments
One last comment Jonas.
To make it easier for the forum users to understand the context, please clarify next time that you are not talking about attribute customization, but that you create a web UI extension.
Ok, sory for that!
I'll do it better next time
Hello,
I just followed the above code but it seems to be existing work item is not Fetched.
dojo.provide("net.jazz.example.workitem.web.ui.LinkedDefectEditorToolbar"); //$NON-NLS-1$
dojo.require("com.ibm.team.workitem.web.ui2.internal.action.AbstractAction"); //$NON-NLS-1$
dojo.require("com.ibm.team.workitem.web.client.util"); //$NON-NLS-1$
dojo.require("com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory");
(function() {
//I instantiate it for easier use:
var WorkItemProxyFactory = com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory;
dojo.declare("net.jazz.example.workitem.web.ui.LinkedDefectEditorToolbar", [com.ibm.team.workitem.web.ui2.internal.action.AbstractAction,com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory],
{
constructor: function(){
// Calculate current Project Area and Work Item Type
this._existingid = new String(this.workingCopy.getItemId());
this._projectAreaItemId = new String(this.workingCopy.getValue({ path: "attributes.projectArea.id"}));
console.log(this._existingid);
console.log(this._projectAreaItemId);
},
run: function(parms) {
//I instantiate it for easier use:
var WorkItemProxyFactory = com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory;
//Now we gonna create a new WIProxy:
var params = {createIfNeeded: true};
var newProxy = WorkItemProxyFactory.getWorkItemProxy(params);
//If you want an WIProxy of an existing WI:
var exparams = { id: this._existingid,
createIfNeeded: true,
doNotCache: true,
doNotGetFromCache:true};
var workingCopyProxy = WorkItemProxyFactory.getWorkItemProxy(exparams);
//Initialize the WI
//After the initialization, you'll see an unsaved WI in the MenuBar "Work Items".
var newparams = {projectAreaItemId:this._projectAreaItemId,
type: "com.ibm.team.apt.workItemType.story", //Story, epic, whatever you need
newWorkItem: true,
includeHistory: false};
console.log("projectArea:"+projectAreaItemId);
newProxy.initialize(newparams);
//Get the Links from the workingCopy
//var linkTypeArray = workingCopyProxy.object.linkTypes //Here are all Links to this actual WI stored.
//Otherwise you could use:
var linkTypeArray = workingCopyProxy.getLinkTypesToWorkItem(workingCopyProxy);
console.log("linktype:"+linkTypeArray);
//If you search specific LinkTypes, use the endpointId
//I.E. linkTypeArray[x].endpointId == 'parent' //To get the parentLink
//Now HOW TO ADD THE WISHED LINKS
var linkparam = {
addLinkType: linkTypeArray, //It has to be an Array
addLinkedProjectAreaItemId: null, //I don't know what this shold do.
addLinkedItemId: newProxy.object.itemId, // It's the ItemId of itself
addLinkIsSource: linkTypeArray[0].isSource, //Mostly this is "false"
}
newProxy.addLinkTarget(linkparam);
//At this point ONLY your runtime copy is actualized! You have to store now your WI to save it on the DB
newProxy.storeWorkItem({
self: this,
operationMsg: "Saving",
applyDelta: true,
onSuccess: function(param) {
//Do what you need
}
});
}
});
})();
Not sure what went wrong!!
Hello Vinitha,
I'll try my best to clarify this :)
First thing, which would be nice is, where does your code crash.
But I take now some wild guessings.
1:
You've double instanciated the factory.
outside the declare and inside (since the declare statement marks the class boundaries and we need the factory inside)
2:
You're using methods inside the constructor where he doesn't know what to do.
this._existingid = new String(this.workingCopy.getItemId());
Workingcopy is nothing there. Probably here fires the "not fetched" error.
3: Because there are some missing infos, your "var exparams" are not correct. The ID at least.
4: What are the params you've send to the run method?
Because that's where the fetch should happen.
var newProxy = WorkItemProxyFactory.getWorkItemProxy(params);
If it's not one of this this, let me know what happens and where the code went through. So I might recreate the problem you have.
dojo.provide("corp.bury.webui.findingButton.ui.createFindingAction"); //$NON-NLS-1$dojo.require("com.ibm.team.workitem.web.ui2.internal.action.AbstractAction"); //$NON-NLS-1$dojo.require("com.ibm.team.workitem.web.client.util"); //$NON-NLS-1$dojo.require("com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory");(function(){// WorkItem Types list of entities that for which the actions applyvar workItemEnabledType = "review";// Link Type to usevar linkType = "com.ibm.team.workitem.linktype.parentworkitem";// WorkItem Type to generatevar workItem2Gen = "finding";var WorkItemUtil = com.ibm.team.workitem.web.client.util;dojo.declare("corp.bury.webui.findingButton.ui.createFindingAction",com.ibm.team.workitem.web.ui2.internal.action.AbstractAction,{constructor: function(){// Calculate current Project Area and Work Item Typethis._currentWIType = new String(this.workingCopy.getValue({path: "attributes.workItemType.id"}));this._currentPArea = new String(this.workingCopy.getValue({path: "attributes.projectArea.id"}));this._currentWIId = this.workingCopy.getItemId();},run: function(parms){
var WorkItemProxyFactory = com.ibm.team.workitem.web.cache.internal.WorkItemProxyFactory;var params = {createIfNeeded: true};var newProxy = WorkItemProxyFactory.getWorkItemProxy(params);var initializeParams ={projectAreaItemId: this._currentPArea,type: workItem2Gen,newWorkItem: true,includeHistory: false};newProxy.initialize(initializeParams);var addTargetLinkParams ={addLinkIsSource: false,addLinkType: linkType,addLinkedProjectAreaItemId: this._currentPArea,addLinkedItemId: newProxy.object.itemId};newProxy.addLinkTarget(addTargetLinkParams);var attributesToAdd ={attributeList : { description : "Test", summary : "Test Summary" }};newProxy.setAttributes(attributesToAdd);newProxy.storeWorkItem({self: this,operationMsg: "Saving",applyDelta: true,onSuccess: function(param) {//Do what you need}});},isEnabled: function(){// Our action is to be only enabled in the Story Work Item and when no change in "on-fly"return !this.workingCopy.isNew() && !this.workingCopy.isChanged() && (this._currentWIType==workItemEnabledType);},isVisible: function(parms){// The action is visible just in workItemEnabledType Work Itemreturn this._currentWIType==workItemEnabledType;}});})();</pre> </div> Where I'm making mistake?
One other answer
Comments
Hy Sam,
But under Version 4.x it worked for me.
Was there a mayor change within the Link system?
A guess:
If I use the "Create WorkItem Copy" it doesn't copy the ParentLink, but it adds the "Copied from" Link, which is in the same Hierarchy as a parent link.
No idea.. never got links to work (list, create, delete, or follow) in javascript.
the 'copied from' is a side effect by the server side code, cause you did a 'copy' operation
There is a distinction between JavaScript in workitemCustomization, where you can't even access links and creating your own web pages and contributions to them, where you potentially could (as the tool has such capabilities as well)
thanks for that clarification.. I've never done the latter.. (UI is not my thing!)
So I got in a bit deeper.
But I need your help now.
I've found "addLinkTarget()" in workitemProxy
addLinkTarget: function addLinkTarget_$79(parms / addLinkType addLinkedProjectAreaItemId addLinkedItemId addLinkIsSource/) {}
But the params are a bit confusing.
addLinkType: com.ibm.team.workitem.linktype.parentworkitem
addLinkedProjectAreaItemId: //I don't know so I set it to "null"
addLinkedItemId:I don't know, itemId of the Parent won't work.
addLinkIsSource: What's the meaning of this?
Always get this message:
WorkItemProxy: Could not find source for new link item [object Object]
Maybe this could be a timing error.
Because I use it between
newProxy.initialize()
newProxy.storeWorkItem();
Maybe I can only use the addFunction when it's stored?
This is beyond my expertise as well. Sorry.
It would be great is this could be shared somewhere. If it was my work and I knew how it works, I would blog about it. If you really want to it would be cool if you blogged about it e.g. on DeveloperWorks and link that back here.