Create a Table Grid Updated Trigger using Groovy Script

Rituraj Nepal June 13, 2024

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 : 

 

        MutableIssue mi = (MutableIssue) issue;
        mi.setCustomFieldValue(customfield, value);

 

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.


2 answers

1 accepted

1 vote
Answer accepted
Sofi Rosinska June 14, 2024

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

francis
Marketplace Partner
Marketplace Partners provide apps and integrations available on the Atlassian Marketplace that extend the power of Atlassian products.
June 14, 2024

Super helpfull Sofi!

0 votes
Rituraj Nepal June 13, 2024

d

Suggest an answer

Log in or Sign up to answer
DEPLOYMENT TYPE
CLOUD
PRODUCT PLAN
PREMIUM
TAGS
AUG Leaders

Atlassian Community Events