How to control user-picker fields in Behaviors?

jyh0226@kicco.com March 9, 2021

hi,

 

jira software 7.x was dynamically control the list of users in the user-picker field within the behaviors.

but, starting with jira software 8.x version, it seems impossible to control the user-picker field within the behaviors.

The list of users in the user-picker field should appear differently depending on the conditions, is there any other way?

 

Thank you.

1 answer

1 accepted

1 vote
Answer accepted
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 21, 2021

Hi jyh0226@kicco.com 

To answer your question, you can easily update the user picker based on another field's value using the Behaviour.

Below is a sample working code for your reference:-

def optionsField = getFieldById(fieldChanged)
def optionsValue = optionsField.value.toString()

def userPicker = getFieldByName("User")

if(optionsValue == "DB") {
userPicker.setFormValue("admin")
} else if(optionsValue == "UI") {
userPicker.setFormValue("max")
} else if(optionsValue == "Web Service") {
userPicker.setFormValue("ram")
}

Please note this sample code is not 100% exact to your environment. Hence you will need to modify it accordingly.

You will need to use the Server-Side Behaviour for the code above. The Options field is a single select list, and the User field is a single user picker.

Below is a print screen of the sample behaviour configuration:-

behaviour_config.png

If the option selected is DB in the sample code above, automatically, the user field updates to Admin.

If the option changes to UI, the user is set to Max.

Finally, if the option selected is Web Service, the user field changes to Ram.

I hope this helps to solve your question :)

Thank you and Kind Regards,

Ram

jyh0226@kicco.com October 7, 2021

Hi @Ram Kumar Aravindakshan _Adaptavist_ 

 

I'm sorry for the late reply.
This function is not what we want.
I think what you told me is setting a value in the user picker field.

 

We dynamically changed and used the list output in the user picker field. (in version 7.x).
I asked because the function was changed to the 8.x version and it seemed to have disappeared.
Can I still use that function now?

 

Thank you.

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.
October 9, 2021

Hi jyh0226@kicco.com

Could you please elaborate a little more on your last comment, i.e.

We dynamically changed and used the list output in the user picker field. (in version 7.x).

What do you mean by dynamically changed?

In the server-side behaviour, you need a change in one field to trigger the update in the user picker.

If you could provide a sample code, it would be helpful.

Thank you and Kind Regards,

Ram

jyh0226@kicco.com October 11, 2021

REST Endpoints

=======================================================

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.user.ApplicationUser
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import org.apache.log4j.Category

import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate
GetUsersInRoles(httpMethod: "GET") { MultivaluedMap queryParams, String body, HttpServletRequest request ->
def logger = Category.getInstance("com.onresolve.jira.groovy")

def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
def userManager = ComponentAccessor.getUserManager()
def userSearchService = ComponentAccessor.getUserSearchService()
def projectKey = queryParams.getFirst("project") as String
def selfRole = queryParams.getFirst("self") as String
def roles = queryParams.get("roles") as String[]

logger.info("projectKey=${projectKey}, roles=${roles}")

if (projectKey == null || roles == null) {
def msg = [
"message" : "There is no parameter information. project = ${projectKey}, roles = ${roles}",
"status-code": "INTERNAL_SERVER_ERROR"
]
return Response.ok(new JsonBuilder(msg).toString()).build()
}
def users = [:]
List<ApplicationUser> roleActors = []

def project = ComponentAccessor.getProjectManager().getProjectObjByKey(projectKey)
if(selfRole == "true") {
def user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
def currentUserRoles = projectRoleManager.getProjectRoles(user, project)

currentUserRoles.each {
projectRoleManager.getProjectRoleActors(it, project).getRoleActors().each {
it.getUsers().each{
roleActors.add(it)
}
}
}
}

roles.each {
def projectRole = projectRoleManager.getProjectRole(it)
log.info("roleName=${it}, projectRole=${projectRole}")
if(projectRole == null){
def msg = [
"message" : "Role not Found = ${projectKey}, roles = ${it}",
"status-code": "INTERNAL_SERVER_ERROR"
]
return Response.ok(new JsonBuilder(msg).toString()).build()
}
def projectRoleActors = projectRoleManager.getProjectRoleActors(projectRole, project)
projectRoleActors.each {
it.users.each {
roleActors.add(it)
}
}
}
users = [
items: roleActors.unique().collect {
it ->
[
value : it.getKey(),
label : it.getDisplayName()
]
}
]
return Response.ok(new JsonBuilder(users).toString()).build()
}

=======================================================

 

Behaviours

=======================================================

import org.apache.log4j.Category
import com.atlassian.jira.component.ComponentAccessor


def log = Category.getInstance("com.onresolve.jira.groovy")

def mainTeamValue = getFieldById("customfield_10811").getValue()

if(mainTeamValue == null) {
return
}

def baseurl = new URL(ComponentAccessor.getApplicationProperties().getString("jira.baseurl"))
def query = "?project=${issueContext.getProjectObject().getKey()}"

if(mainTeamValue == "HW") {
query += ("&roles=" + URLEncoder.encode("H/W Administrators","UTF-8") + "&roles=" + URLEncoder.encode("H/W Developers","UTF-8"))
} else if(mainTeamValue == "SW") {
query += ("&roles=" + URLEncoder.encode("S/W Administrators","UTF-8") + "&roles=" + URLEncoder.encode("S/W Developers","UTF-8"))
} else if(mainTeamValue == "Vision") {
query += ("&roles=" + URLEncoder.encode("Vision Administrators","UTF-8") + "&roles=" + URLEncoder.encode("Vision Developers","UTF-8"))
} else if(mainTeamValue == "COK") {
query += ("&roles=" + URLEncoder.encode("COK Administrators","UTF-8") + "&roles=" + URLEncoder.encode("COK Developers","UTF-8"))
} else if(mainTeamValue == "TIB") {
query += ("&roles=" + URLEncoder.encode("TIB Administrators","UTF-8") + "&roles=" + URLEncoder.encode("TIB Developers","UTF-8"))
} else if(mainTeamValue == "QA") {
query += ("&roles=" + URLEncoder.encode("QA Administrators","UTF-8") + "&roles=" + URLEncoder.encode("QA Assignee","UTF-8"))
} else if(mainTeamValue == "CS") {
query += (
"&roles=" + URLEncoder.encode("CS1 Team Administrators","UTF-8") +
"&roles=" + URLEncoder.encode("CS1 Team Assignee","UTF-8") +
"&roles=" + URLEncoder.encode("CS2 Team Administrators","UTF-8") +
"&roles=" + URLEncoder.encode("CS2 Team Assignee","UTF-8") +
"&roles=" + URLEncoder.encode("CS3 Team Administrators","UTF-8") +
"&roles=" + URLEncoder.encode("CS3 Team Assignee","UTF-8")
)
}

def resturl = baseurl.toString() + "/rest/scriptrunner/latest/custom/GetUsersInRoles"
def assigneeRest = resturl + query
def approverRest = resturl + query.toString().substring(0, query.toString().lastIndexOf("&"))

if(getActionName() != "Create") {
getFieldById("customfield_10606").convertToSingleSelect([
ajaxOptions: [
url : assigneeRest,
query: true, // keep going back to the sever for each keystroke
minQueryLength: 1,
keyInputPeriod: 500,
formatResponse: "general"
]
])
}

=======================================================

 

As shown in the sample code above, the 7.x version was able to dynamically control the list of users to be output from the User Picker.

/*
customfield_10606: User Picker
customfield_10811: Select List

*/

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.
October 16, 2021

Hi jyh0226@kicco.com

From the update you have provided, it appears that you want to invoke the values for the List from the REST Endpoint. 

So, if any new user is added or removed from the Roles, it should dynamically update. Is this correct?

If so, you can still do this in Jira 8 and ScriptRunner.

Below is the updated REST Endpoint example for your reference:-

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.atlassian.jira.user.ApplicationUser
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript

import javax.servlet.http.HttpServletRequest
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response

@BaseScript CustomEndpointDelegate delegate

GetUsersInRoles(httpMethod: 'GET') { MultivaluedMap queryParams, String body, HttpServletRequest request ->

def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)

def projectKey = queryParams.getFirst('project') as String
def selfRole = queryParams.getFirst('self') as String
def roles = queryParams.get('roles') as String []

def project = ComponentAccessor.projectManager.getProjectObjByKey(projectKey)

List<ApplicationUser> roleActors = []

log.warn "projectKey=${projectKey}, roles=${roles}"

if (projectKey == null || roles == null) {

def msg = [
'message' : "There is no parameter information. project = ${projectKey}, roles = ${roles}",
'status-code': 'INTERNAL_SERVER_ERROR'
]
return Response.ok(new JsonBuilder(msg).toString()).build()
}


if(selfRole == 'true') {
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def currentUserRoles = projectRoleManager.getProjectRoles(user, project)

currentUserRoles.each {
projectRoleManager.getProjectRoleActors(it, project).roleActors.each {
it.users.each{
roleActors.add(it)
}
}
}
}
roles.each {
def projectRole = projectRoleManager.getProjectRole(it)
log.warn "roleName=${it}, projectRole=${projectRole}"
if(projectRole == null){
def msg = [
'message' : "Role not Found = ${projectKey}, roles = ${it}",
'status-code': 'INTERNAL_SERVER_ERROR'
]
return Response.ok(new JsonBuilder(msg).toString()).build()
}
def projectRoleActors = projectRoleManager.getProjectRoleActors(projectRole, project)

projectRoleActors.each {
it.users.findAll {
roleActors.addAll(it)
}
}
}
def users = [
items: roleActors.unique().collect {
it ->
[
value : it.key,
label : it.displayName
]
}
]
return Response.ok(new JsonBuilder(users).toString()).build()
}

 Below is the working sample Behaviour code:-

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

@BaseScript FieldBehaviours behaviours
def role = getFieldById(fieldChanged)
def roleValue = role.value.toString()

def userByRole = getFieldByName('Users By Role')

def project = issueContext.projectObject
def projectKey = project.key

userByRole.convertToShortText().setFormValue('')

userByRole.convertToMultiSelect([
ajaxOptions: [
url : "${baseUrl}/rest/scriptrunner/latest/custom/GetUsersInRoles?roles=${roleValue}&project=${projectKey}",
query : true,
minQueryLength: 4,
keyInputPeriod: 500,
formatResponse: 'general'
],
])

Please note, the sample codes provided are not 100% exact to your environment. Hence, you will need to make the required modifications.

Below is a print screen of the Behaviour configuration:-

behaviour_config.png

 

Also, I include a few test print screens for your reference:-

1) If the Administrators Role is selected, the Users who belong to the Administrators role will be displayed in the second list as shown in the image below:-

admin_options.png

2) If the Developers Role is selected, the Users who belong to the Developers role will be displayed as shown in the image below:-

developer_options.png

I hope this helps to answer your question. :)

Thank you and Kind Regards,

Ram

Suggest an answer

Log in or Sign up to answer