Iterating Values with a Map With ScriptRunner Behavior

Andrew Wolpers March 2, 2023

I have a multi-select field that I am hoping to have add values as options via a behavior.

The thought is that the values in the multi-select will:

  1. Get the value(s) selected from the issue it is being loaded on
  2. Iterate through the issues to isolate individual values
    1. Compare the values against a map (key = Multi-Select, value = project ID)
    2. Use the project ID to get applicable context values
    3. Add context values to a final list of options
  3. Present the user with the final list of options based on their multi-select field selections

I'm having some issues with the part where I would iterate through the multi select values. I am able to get the values, but when trying to compare them to the map it is never matching.

Here is the script I'm using:


def im = ComponentAccessor.issueManager
def issue = im.getIssueObject('AWOLBP-2') //in a workflow postfunction, you can just comment out this line, the script binding already includes an issue variable
log.warn "Using $issue"

def cfManager = ComponentAccessor.customFieldManager
def optionsManager = ComponentAccessor.optionsManager

// Field and Project Value Map
def projectContextMap = [
'Foo':16601,
'Bar':16901
]

def projectContextMapKey = projectContextMap.key
def projectContextMapId = projectContextMap.value

for (e in projectContextMap){ // checking format of the full map
log.warn "key = ${e.key}, Value = ${e.value}"
}

// Field Configuration Area
def productGroup = cfManager.getCustomFieldObjectsByName('Group')
def groupValue = productGroup ? issue.getCustomFieldValue(productGroup[0]) : "Field doesn't exist"
log.warn "Custom field value type or class" + groupValue.getClass()

groupValue.eachWithIndex {
it, i ->
log.warn "Group Values $i: $it"
}

def productTeam = getFieldById("customfield_19403") // Product Team(s) Jira Test ID 19403
def productTeamObjects = cfManager.customFieldObjects.findByName("Product Team(s)")
log.warn("ProductTeam Objects: $productTeamObjects")

// Iterate through the Group value list and add context values
for (i in groupValue){
log.warn "Present Value for $issue: $i"
if
(projectContextMap.containsKey(i)) {
return true
log.warn
"$i matched with ${projectContextMap.value}"
}

}

Here are the logs where I am seeing the value identified, but not matching a key in the list:

2023-03-02 15:13:12,906 WARN [runner.ScriptBindingsManager]: Present Value for AWOLBP-2: Data Security 2023-03-02 15:13:12,906 WARN [runner.ScriptBindingsManager]: Present Value for AWOLBP-2: ADEMO

 Any guidance on how to get that i value compared with a key would be super helpful!

1 answer

Suggest an answer

Log in or Sign up to answer
0 votes
Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
March 8, 2023

Hi @Andrew Wolpers

From you description, I understand that you want to use the Behaviour to add new values / options in the Multi-Select Field. Is this correct?

If yes, then this is not doable. If you are using the standard Multi-Select field, you can only filter the options that are provided using the Behaviour as shown in this sample code from the Adaptavist Library. You will not be able to use the Behaviour to add new options to it.

I am looking forward to your clarification.

Thank you and Kind regards,

Ram

Andrew Wolpers March 8, 2023

Hey Ram, 

This wouldn't be adding new values. The purpose is to filter down values from a large list, based on what was selected in a multi-select field. 

The sticking point is that I would ideally have it cycle through if multiple matches to the values on the multi-select field were selected. 

For example, say I have a field called "MS 1", a multi-select field. It has values of: [Foo, Bar, Lorem, Ipsum]

And we have another field, let's call that "MS 2" which is another multi-select with values of: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

I want to use a behavior to grab all the fields in "MS 1" whenever there is a match in the map, then compile a list of applicable values from "MS 2", so that only relevant values are shown. 

For example, say that if we were to check the context of "MS 1" and it included [Foo, Ipsum] I would look up the contexts for the values: Foo and Ipsum.

Foo values are [1, 3, 5] 

Ipsum values are [2, 4, 6]

The total values that should present are: [1, 2, 3, 4, 5, 6] because of the values returned from Foo + Ipsum. 

I have this working as a single match, but I'm having difficulties getting it to match and add the additional values. As a single match it looks like:


import com.onresolve.jira.groovy.user.FieldBehaviours

import groovy.transform.BaseScript

import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.issue.fields.CustomField

import com.atlassian.jira.issue.context.IssueContext

import com.atlassian.jira.issue.context.IssueContextImpl

@BaseScript FieldBehaviours fieldBehaviours

def im = ComponentAccessor.issueManager

def cfManager = ComponentAccessor.customFieldManager

def optionsManager = ComponentAccessor.optionsManager

// Value to Project ID Map

HashMap<String, Integer> contextMap = new HashMap<String, Integer>();

// str is group value, int is mapped project ID

contextMap.put('ADEMO', 16601);

contextMap.put('AWOLBP', 16901);

contextMap.put('Other Option', 16309);

contextMap.put('Another Option', 18402);

contextMap.put('More Options',16601);

contextMap.put('Yeehaw', 16800);



// Field Configuration Area

def teamDisciplines = getFieldById("customfield_25124")

def teamDisciplinesObjects = cfManager.customFieldObjects.findByName("Team(s)")

log.warn("ProductTeam Objects: $teamDisciplinesObjects")

def productLines = getFieldById("customfield_25123")

def productLinesObjects = cfManager.customFieldObjects.findByName("Product Line(s)")

log.warn("ProductTeam Objects: $productLinesObjects")

// Group Field Configuration IE "MS 1"

//def productGroup = customFieldManager.getCustomFieldObject(19703)

def productGroup = getFieldById("customfield_25810")

def groupValueList = productGroup.value as List

def groupValue = productGroup.getValue() as String

// def groupValue = issue.getCustomFieldValue(productGroup) as String

log.warn "Custom field value type or class" + groupValue.getClass()

log.warn "Group Value: $groupValue"

def cleanGroupValue = groupValue.replaceAll("\\[|\\]","")

log.warn "$cleanGroupValue"

// If value is null

if (groupValueList == [null] || groupValueList.contains("Assign for Triage")) {

productGroup.setError("Please select a valid Group for more options")

productGroup.setRequired(true)

teamDisciplines.setReadOnly(true)

productLines.setReadOnly(true)

return "Null group value or Needs Triage."

// If more than 1 value is selected

} else if ( groupValueList.size() > 1 ) {

productGroup.setError("Please only select one option.")

teamDisciplines.setReadOnly(true)

productLines.setReadOnly(true)

}

log.warn("Getting the $cleanGroupValue:" + contextMap.get(cleanGroupValue))

def contextId = contextMap.get(cleanGroupValue)

if (groupValueList != [null]){

teamDisciplines.setReadOnly(false)

productLines.setReadOnly(false)

productGroup.clearHelpText()

def getApplicableContext = new IssueContextImpl(contextId,null)

// Team Disciplines i.e "MS 2" 

def getTeamDisciplineConfig = teamDisciplinesObjects.getRelevantConfig(getApplicableContext)

List teamDisciplinesValueList = optionsManager.getOptions(getTeamDisciplineConfig)

log.warn "Using Team Discipline(s) values: $teamDisciplinesValueList"

def teamDisciplinesOptionsList = []

teamDisciplinesValueList.each {

teamDisciplinesOptionsList.add(it.toString())

}

teamDisciplines.setFieldOptions(teamDisciplinesOptionsList)

log.warn "Team Discipline Values filtered to $teamDisciplinesOptionsList"

} else {

productGroup.setHelpText("Please select a Group to proceed.")

teamDisciplines.setReadOnly(true)

productLines.setReadOnly(true)

}
TAGS
AUG Leaders

Atlassian Community Events