Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in
Celebration

Earn badges and make progress

You're on your way to the next level! Join the Kudos program to earn points and save your progress.

Deleted user Avatar
Deleted user

Level 1: Seed

25 / 150 points

Next: Root

Avatar

1 badge earned

Collect

Participate in fun challenges

Challenges come and go, but your rewards stay with you. Do more to earn more!

Challenges
Coins

Gift kudos to your peers

What goes around comes around! Share the love by gifting kudos to your peers.

Recognition
Ribbon

Rise up in the ranks

Keep earning points to reach the top of the leaderboard. It resets every quarter so you always have a chance!

Leaderboard

Come for the products,
stay for the community

The Atlassian Community can help you and your team get more value out of Atlassian products and practices.

Atlassian Community about banner
4,463,473
Community Members
 
Community Events
176
Community Groups

ScriptRunner Behaviours setting "read only" to all statements, can't set/clear error

Edited
  • Problem Statements
    • I cannot figure out why the read-only section is applying to all statements; it's even locking for Jira-Administrators group even though it's not applied to that statement (from what I can tell)
    • How can I set the error message on the Issue Type field, to be cleared if another project is selected?
    • Can this script be further optimized to improve performance? I'm sure I've got repeats and stragglers.

 

  • Already Tried
    • Removing the getFieldById(ISSUE_TYPE).with setting from individual statements and move to end
    • Adding different settings to each statement (i.e. some are TRUE while others are FALSE)
    • Adding setError and clearError to each statement
    • Adding setError and clearError to the end
    • Combining the remoteUsersRoles into a single statement but it wound up reading none of them (e.g. if ["Project Managers","Program Managers","Team Leads"] in remoteUsersRoles)

 

Thanks in advance to anyone who can help!

 

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.security.roles.ProjectRoleManager
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import static com.atlassian.jira.issue.IssueFieldConstants.ISSUE_TYPE

@BaseScript Field Behaviours fieldBehaviours

def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
def allIssueTypes = ComponentAccess.constantsManager.allIssueTypeObjects
def user = ComponentAccessor.jiraAuthenticationContext.loggedInUser

def issueTypeField = getFieldByID(ISSUE_TYPE)
def remoteUsersRoles = projectRoleManager.getProjectRoles(user, issueContext,projectObject)*.name
def availableIssueTypes = []

def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()

if (ComponentAccessor.getGroupManager().isUserInGroup(currentUser, "jira-administrators")) {
availableIssueTypes.allAll(allIssueTypes.findAll {it.name in ["Initiative", "Bug","Story","Task","Epic","Problem","Incident"] })
}

if ("Project Managers" in remoteUsersRoles) {
availableIssueType.addAll(allIssueTypes.findAll {it.name in ["Initiative"] })
}

if ("Program Managers" in remoteUsersRoles) {
availableIssueType.addAll(allIssueTypes.findAll {it.name in ["Initiative"] })
}

if ("Administrators" in remoteUsersRoles) {
availableIssueType.addAll(allIssueTypes.findAll {it.name in ["Initiative"] })
}

if ("TRelease Coordinators" in remoteUsersRoles) {
def constantsManager = ComponentAccessor.getConstantsManager()
def queryIssueType = constantsManager.getAllIssueTypeObjects().find {it.name == "Sub-task" }
getFieldByID(ISSUE_TYPE).with {
setFormValue(queryIssueType.id)
setReadOnly(true)
}
}

if ("Team Leads" in remoteUsersRoles) {
def constantsManager = ComponentAccessor.getConstantsManager()
def queryIssueType = constantsManager.getAllIssueTypeObjects().find {it.name == "Sub-task" }
getFieldByID(ISSUE_TYPE).with {
setFormValue(queryIssueType.id)
setReadOnly(true)
}
}

if ("Developers" in remoteUsersRoles) {
def constantsManager = ComponentAccessor.getConstantsManager()
def queryIssueType = constantsManager.getAllIssueTypeObjects().find {it.name == "Sub-task" }
getFieldByID(ISSUE_TYPE).with {
setFormValue(queryIssueType.id)
setReadOnly(true)
}
}

if ("Testers" in remoteUsersRoles) {
def constantsManager = ComponentAccessor.getConstantsManager()
def queryIssueType = constantsManager.getAllIssueTypeObjects().find {it.name == "Sub-task" }
getFieldByID(ISSUE_TYPE).with {
setFormValue(queryIssueType.id)
setReadOnly(true)
}
}

issueTypeField.setFieldOptions(availableIssueTypes)

 

1 answer

1 accepted

0 votes
Answer accepted

Hi @Lacey McDonnell 

First, in order to have issueType behaviour be reset when you change projects, you behaviour project mapping needs to be set to "All Projects" and "All Issue Types".

Otherwise, the script only fires in the mapped project, and doesn't reset when you change the project unless you close and re-open the form.

Then, your script has to decide whether to apply or clear the behaviour.

The challenge with that is if you have other scripts/configs that touch on the issueType, you will need to combine them all into one so you don't have conflicting rules.

 

Now, you asked about ideas for simplifying or avoiding redundancy ... and preventing the read-only statements from running on admins and other roles ... here is a re-written script (untested) that might achieve all your goals.

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.security.roles.ProjectRoleManager
import com.onresolve.jira.groovy.user.FieldBehaviours
import groovy.transform.BaseScript
import static com.atlassian.jira.issue.IssueFieldConstants.ISSUE_TYPE

//@BaseScript Field Behaviours fieldBehaviours

def groupManager = ComponentAccessor.groupManager
def projectRoleManager = ComponentAccessor.getComponent(ProjectRoleManager)
//useing project-specific issue types instead of all issue types from your instance.
def allIssueTypes = ComponentAccessor.issueTypeSchemeManager.getIssueTypesForProject(issueContext.projectObject)
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser

def issueTypeField = getFieldById(ISSUE_TYPE)
def remoteUsersRoles = projectRoleManager.getProjectRoles(user, issueContext.projectObject)*.name
def availableIssueTypes = []

def projectParams = [
[
pkey: 'ABC', //the key to a project where the following parameters should be applicable
groupTypeMap:[
groups: ['jira-administrators'],
types: ["Initiative", "Bug","Story","Task","Epic","Problem","Incident"]
],
roleTypeMap: [
limit : [
roles: ['Project Managers', 'Program Manager', 'Administrators'],
types: ['Initiative'],
],
set : [
roles: ['TRelease Coordinators','Team Leads', 'Developers', 'Testers'],
type: 'Sub-Task'
]
]
],
//add other project block like the one above if necessary
]
def projectParam = projectParams.find{it.pkey == issueContext.projectObject.key}
if(projectParam){
if(projectParam.groupTypeMap.groups.any{ groupManager.isUserInGroup(currentUser, it as String)}){
availableIssueTypes.addAll(allIssueTypes.findAll{it.name in projectParam.groupTypeMap.types})
issueTypeField.setFieldOptions(availableIssueTypes)
} else {
if(projectParam.roleTypeMap.limit.roles.any{it in remoteUsersRoles}){
availableIssueTypes.addAll(allIssueTypes.findAll{it.name in projectParam.roleTypeMap.limit.types})
} else {
if(projectParam.roleTypeMap.set.roles.any{it in remoteUsersRoles}){
issueTypeField.setReadOnly(true).setFormValue(allIssueTypes.find{ it.name == projectParam.roleTypeMap.set.type}.id)
return //we don't need to process/adjust availableIssueType if the field is read-only
}
}
}
issueTypeField.setFieldOptions(availableIssueTypes)
} else {
//not a controlled project ... reset everything
issueTypeField.with{
setReadOnly(false)
setFieldOptions(allIssueTypes) //not sure if this is necessary. The field options should get re-loaded when you change project
}

You will see that I collapsed all the repeats into a single set of logic.. and added a priority order by first checking if the user is in a group, then checking the role for limiting the list and finally checking the role for setting the value. So the next condition is only evaluated if the first one fails.

A lot of this is based on the data structure in projectParams. This put the data you want the logic to be based on to be separate from where the logic is evaluated. This way, you can just add new roles or issuetypes in the correct place without having to write new blocks of code.

If you needed to deploy a separate set of rules for another project, you should be able to, in theory, just add another block in the data structure.

Hope this helps

Suggest an answer

Log in or Sign up to answer
TAGS

Atlassian Community Events