Copy the grid content to another grid

Introduction

It is possible to do with TGE Java API and the ScriptRunner add-on

Please ensure that you have ScriptRunner and TGE version 1.18.0 or later installed on your JIRA.

Suppose you want to copy the content of one TGE grid to another TGE grid on some transition. Create a scripted post-function in the desired transition and paste there the following script.

In this script we assume that both grids have the same configuration (i.e the same number, names and configuration of the columns). Copying of the grid data to the grid with different columns is also possible, but it requires additional script customization.

 

Script

/** * copyGridToAnotherGrid.groovy * * Copies data from source grid to destination grid. * Grids should have the same set of columns. In other case addRows() API call will throw an appropriate error. * * Configuration: * - tgeSourceCustomFieldName - name of the source grid custom field * - tgeDestinationCustomFieldName - name of the destination grid custom field */ import com.atlassian.crowd.embedded.api.User import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.CustomFieldManager import com.atlassian.jira.issue.fields.CustomField import com.atlassian.jira.security.JiraAuthenticationContext import com.atlassian.jira.user.ApplicationUser import com.atlassian.jira.user.ApplicationUsers import com.atlassian.plugin.PluginAccessor import org.apache.log4j.Logger // configuration (update it to match your JIRA settings) String tgeSourceCustomFieldName = "TGE_SRC"; String tgeDestinationCustomFieldName = "TGE_DST"; // set up logger Logger log = Logger.getLogger("com.idalko.scripts"); // find source TGE custom field PluginAccessor pluginAccessor = ComponentAccessor.getPluginAccessor(); CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager(); CustomField tgeSourceCustomField = customFieldManager.getCustomFieldObjectByName(tgeSourceCustomFieldName); if (tgeSourceCustomField == null) { log.error("Source grid '" + tgeSourceCustomFieldName + "' is not found"); return; } Long tgeSourceCustomFieldId = tgeSourceCustomField.getIdAsLong(); // find destination TGE custom field CustomField tgeDestinationCustomField = customFieldManager.getCustomFieldObjectByName(tgeDestinationCustomFieldName); if (tgeDestinationCustomField == null) { log.error("Destination grid '" + tgeDestinationCustomFieldName + "' is not found"); return; } Long tgeDestinationCustomFieldId = tgeDestinationCustomField.getIdAsLong(); // get current user JiraAuthenticationContext jiraAuthenticationContext = ComponentAccessor.getOSGiComponentInstanceOfType(JiraAuthenticationContext.class); Object userObject = jiraAuthenticationContext.getLoggedInUser(); ApplicationUser applicationUser = userObject instanceof ApplicationUser ? (ApplicationUser) userObject : ApplicationUsers.from(userObject); User user = userObject instanceof ApplicationUser ? ((ApplicationUser) userObject).getDirectoryUser() : (User) userObject; // read grid data from the source grid Class dataManagerClass = pluginAccessor.getClassLoader().findClass("com.idalko.jira.plugins.igrid.api.data.TGEGridTableDataManager"); def tgeGridDataManager = ComponentAccessor.getOSGiComponentInstanceOfType(dataManagerClass); List<Map<String, Object>> sourceGridData = new ArrayList<Map<String, Object>>(); try { def callResult = tgeGridDataManager.readGridData(issue.getId(), tgeSourceCustomFieldId, null, null, 0, 1000, user); sourceGridData = callResult.getValues(); log.debug("Grid ID=" + tgeSourceCustomFieldId + " content: " + sourceGridData); } catch (Exception e) { log.debug("Grid ID=" + tgeSourceCustomFieldId + " data cannot be retrieved: " + e.getMessage()); } // get the list of grid columns Class tgeConfigManagerClass = pluginAccessor.getClassLoader().findClass("com.idalko.jira.plugins.igrid.api.config.grid.TGEGridConfigManager"); def tgeConfigManager = ComponentAccessor.getOSGiComponentInstanceOfType(tgeConfigManagerClass); def tgeGrid = tgeConfigManager.getGridConfigOrNull(tgeSourceCustomFieldId); def columnConfigs = tgeGrid.getColumnConfigs(); List<String> columnConfigNames = new LinkedList<String>(); for (def columnConfig : columnConfigs) { String columnConfigName = columnConfig.getConfigName(); columnConfigNames.add(columnConfigName); } log.debug("Grid ID=" + tgeSourceCustomFieldId + " has following columns: " + columnConfigNames); // transform fetched data List<Map<String, Object>> gridDataToAdd = new LinkedList<Map<String, Object>>(); for (Map<String, Object> gridRow : sourceGridData) { Map<String, Object> rowToAdd = new HashMap<String, Object>(); for (String columnName : columnConfigNames) { def columnValue = gridRow.get(columnName); if (columnValue instanceof Map) { columnValue = columnValue.get("value"); } rowToAdd.put(columnName, columnValue); } gridDataToAdd.add(rowToAdd); } log.debug("Transformed data to add: " + gridDataToAdd); // copy grid data to destination grid try { tgeGridDataManager.addRows(issue.getId(), tgeDestinationCustomFieldId, gridDataToAdd, user); log.debug(gridDataToAdd.size() + " grid rows are added to Grid ID=" + tgeDestinationCustomFieldId); } catch (Exception e) { log.debug("Grids rows cannot be added due to error: " + e.getMessage()); }

At the beginning of the script you can see configuration section. The names of the source grid and destination grid are specified there. Change them to match your grid configuration.

// configuration (update it to match your JIRA settings) String tgeSourceCustomFieldName = "TGE_SRC"; String tgeDestinationCustomFieldName = "TGE_DST";