In Groovy, I have updated rows into Table Grid Editor of a certain issue. In the same groovy script, I want to know if it is possible to create a IssueUpdated Event that The Grid has been Updated. I have seen similar IssueUpdated EventDispatch for other custom fields. How about TableGrid Editor ?
The example I found is :
ComponentAccessor.getIssueManager().updateIssue(currentUser, mi, EventDispatchOption.DO_NOT_DISPATCH, false);
Is there similar approach to set CustomFieldValue ?
I want to trigger an event, that the custom field of type table grid editor is updated using Groovy Script.
Hello @Rituraj Nepal
Thank you for your question!
As you might know, the way that Table Grid Editor is recommended to be updated is through it's own API (example).
This action does not produce any Jira Issue Event as the value is simply updated silently in through the plugin's backend.
However, after changing the value of the grid, you can fire the event manually, please see the example code below:
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.Issue;
import com.atlassian.jira.issue.IssueManager;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.security.JiraAuthenticationContext;
import com.atlassian.plugin.PluginAccessor;
import com.atlassian.jira.user.ApplicationUser;
// get an issue
IssueManager issueManager = ComponentAccessor.getOSGiComponentInstanceOfType(IssueManager.class);
Issue issue = issueManager.getIssueObject("TEST-1");
def issueService = ComponentAccessor.getIssueService()
// get TGE custom field
CustomFieldManager customFieldManager = ComponentAccessor.getOSGiComponentInstanceOfType(CustomFieldManager.class);
CustomField tgeCustomField = customFieldManager.getCustomFieldObjectsByName("TGE Test").get(0);
Long tgeCustomFieldId = tgeCustomField.getIdAsLong();
// get current user for both TGE action and Issue Update action
JiraAuthenticationContext jiraAuthenticationContext = ComponentAccessor.getOSGiComponentInstanceOfType(JiraAuthenticationContext.class);
Object userObject = jiraAuthenticationContext.getLoggedInUser();
User user = userObject instanceof ApplicationUser ? ((ApplicationUser) userObject).getDirectoryUser() : (User) userObject;
ApplicationUser appUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
// read grid data
PluginAccessor pluginAccessor = ComponentAccessor.getPluginAccessor();
Class dataManagerClass = pluginAccessor.getClassLoader().findClass("com.idalko.jira.plugins.igrid.api.data.TGEGridTableDataManager");
def tgeGridDataManager = ComponentAccessor.getOSGiComponentInstanceOfType(dataManagerClass);
StringBuilder result = new StringBuilder();
def callResult = null;
try {
callResult = tgeGridDataManager.readGridData(issue.getId(), tgeCustomFieldId, null, null, 0, 10, user);
result.append("Grid ID=" + tgeCustomFieldId + " content before modification: " + callResult.getValues() + "\n");
} catch (Exception e) {
result.append("Grid ID=" + tgeCustomFieldId + " data cannot be retrieved: " + e.getMessage() + "\n");
}
// let's edit the data
Class changeSetClass = pluginAccessor.getClassLoader().findClass("com.idalko.jira.plugins.igrid.api.data.dto.TGEChangeSet");
List changes = new ArrayList();
for (Map<String, Object> row : callResult.getValues()) {
Long rowId = (Long) row.get("id");
String summary = row.get("isummary");
Map<String, Object> newRowValues = new HashMap<String, Object>();
newRowValues.put("isummary", summary + "_changed");
def changeSet = changeSetClass.newInstance();
changeSet.setRowId(rowId);
changeSet.setValues(newRowValues);
changes.add(changeSet);
}
try {
tgeGridDataManager.applyChanges(issue.getId(), tgeCustomFieldId, changes, user);
result.append("Grid ID=" + tgeCustomFieldId + " was successfully updated!\n");
} catch (Exception e) {
result.append("Grid ID=" + tgeCustomFieldId + " data cannot be updated: " + e.getMessage() + "\n");
}
// check if data was changed
try {
callResult = tgeGridDataManager.readGridData(issue.getId(), tgeCustomFieldId, null, null, 0, 10, user);
result.append("Grid ID=" + tgeCustomFieldId + " content after modification: " + callResult.getValues() + "\n");
} catch (Exception e) {
result.append("Grid ID=" + tgeCustomFieldId + " data cannot be retrieved: " + e.getMessage() + "\n");
}
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.description = 'TGE field updated through API'
def validationResult = issueService.validateUpdate(appUser, issue.getId(), issueInputParameters)
if (validationResult.isValid()) {
issueService.update(appUser, validationResult)
} else {
log.warn "Did not update issue: $validationResult.errorCollection.errors"
}
println(result.toString());
return result.toString();
By passing some pre-determined value in the issueInputParameters you can then also catch specifically the events that are created when TGE is updated via script like so:
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.ModifiedValue
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder
// set up required class instances
def customFieldManager = ComponentAccessor.customFieldManager
def issueService = ComponentAccessor.getIssueService()
// the new value of the field
final customFieldName = 'TGE Test'
def issue = event.issue
def customField = customFieldManager.getCustomFieldObjects(issue).findByName(customFieldName)
assert customField : "Could not find custom field with name $customFieldName"
def change = event?.getChangeLog()?.getRelated("ChildChangeItem")?.find {it.field == customFieldName}
if(change){
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.description = 'TGE updated'
def validationResult = issueService.validateUpdate(event.user, event.issue.id, issueInputParameters)
if (validationResult.isValid()) {
issueService.update(event.user, validationResult, EventDispatchOption.DO_NOT_DISPATCH, false)
} else {
log.warn "Did not update issue: $validationResult.errorCollection.errors"
}
}else {
def issueInputParameters = issueService.newIssueInputParameters()
issueInputParameters.description = 'non-TGE field updated'
def validationResult = issueService.validateUpdate(event.user, event.issue.id, issueInputParameters)
if (validationResult.isValid()) {
issueService.update(event.user, validationResult, EventDispatchOption.DO_NOT_DISPATCH, false)
} else {
log.warn "Did not update issue: $validationResult.errorCollection.errors"
}
}
Please note that in this script here, the parameter that is checked is whether the field that is updated has a matching name. In your case, the condition would have to be changed to check for some other parameter that you will be passing on TGE updates.
In summary, however, both updating TGE and firing controlled events with TGE updates through Groovy scripts is very much possible.
Please don't hesitate to contact our support directly if you have further questions!
Best regards,
Sofi - Table Grid team
Super helpfull Sofi!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.