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

Optimization on behaviours

Florian PEREZ
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 23, 2022

Hi all !

I would like to see with the script runner master if you got any tips on behaviours optimizations. 

I found that there too much-repeated part of code on behaviour for me to consider this good and easy to maintain. 

I remember finding a piece of behaviour code using array at start, handling customfield value and then using a .find() to set the hidden field in one time.


can’t find something similar, and I’ve not kept the page in fav. Is someone using something cleaner to declare behaviours.


On another hand, do you have some tips on optimizing behaviours in a huge instance?


Thanks so much all !

5 comments

Comment

Log in or Sign up to comment
Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 23, 2022

That sounds like the type of code I would have suggested.

I don't know that I can easily find an example, but if you share more details of your scenario or even better your existing code, I can try to make a recommendation.

Like Dave Liao likes this
Peter-Dave Sheehan
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 16, 2023

@Florian PEREZ 

Here is how I would rewrite the snippet you shared below...

Please note that based on the offerec script logic, I was only seeing 2 fields ever set visible: alert and categorie 

def opt1 = 'Vulnérabilité'
def opt2 = 'Incident'
def opt3 = '...'
def fieldsConfigs = [
[id: 'customfield_10302', showOptions: [opt2]], //categorie
[id: 'customfield_10303',showOptions: []],//devicetype
[id: 'customfield_10304',showOptions: []], //attacktype
[id: 'customfield_10305',showOptions: []],//securitydevice
[id: 'customfield_10306',showOptions: []],//behaviourtype
[id: 'customfield_10307',showOptions: []], //cvftype
[id: 'customfield_10308', showOptions: [opt1], defaultValue: 10034],//alert
]

def decisionField = getFieldById('customfield_10301')
def decisionFieldVal = decisionField.value as String

fieldsConfigs.each { map ->
def hide = !map.showOptions.any { List<String> it -> decisionFieldVal.contains(it) }
def field = getFieldById(map.id)
field.setHidden(hide)
if (hide) {
field.setFormValue(null)
} else {
if(map.defaultValue) field.setFormValue(map.defaultValue)
}

}

The idea is to create a structured object that contains what you want to do for each field and then go through each item and perform the specified actions.

Like Dave Liao likes this
Dave Liao
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 23, 2022

@Florian PEREZ - this is for ScriptRunner on-premise, yeah?

If you have Behaviors sharing the same code (either the initializer or for specific custom field/s), consider storing the script/s in a File instead of writing code inline?

Unsure if it's possible to share specific chunks of code in a file (or inline) across Behaviors.

p.s. I love your idea for this post!

Florian PEREZ
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
November 24, 2022

Hey @Peter-Dave Sheehan & @Dave Liao 

 


@Dave Liao Of course we're exited about hearing the new behaviour on cloud but I'm talking about on premise behaviour, you guess it right ! 

Btw Unsure if it's possible to share specific chunks of code in a file (or inline) across Behaviors.

This could be a huge part of optimization, but it can make the maintain more complex for other admins and since we're not all pure dev I'm more considering about pure interface optimisation. 


 

I've done some research and find (easily on first page of google :'D) the following article for reference :  https://coyotecrk.com/2016/11/23/best-practices-scriptrunner-behaviours/ 

 

I still find that the part they call recommended code is not so good : 

Good Code

This behaviour is kind of short considering the global capabilities of Scriptrunner Behaviours. I still think there repeated portion of code ( the get fieldById() or the .value.contain() part for exemple). I did not like this as an ex dev knowing the concepts of DRY and code smells and this code is only about one field, imagine if we had 10 or 20 customfields in conditions... 

This was my start point about creating this article. 

Like # people like this
Dave Liao
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
November 24, 2022

That’s a good point, not all admins would necessarily be devs or have dev experience.

I feel like we would want to translate some of the (by necessity) UX from ScriptRunner Cloud to on-prem?

I wonder if I can get someone from Adaptavist to comment on this discussion… @Nic Brough -Adaptavist-  👋 😉 

Florian PEREZ
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 16, 2023

Hi @Peter-Dave Sheehan I came back with an exemple of what I'm trying to improve:  

 

// Hide other fields depending on 'Type'
def decisionField = getFieldById('customfield_10301')
  
// Get a pointer to the fields to hide/show
def categorie = getFieldById('customfield_10302')
def devicetype = getFieldById('customfield_10303')
def attacktype = getFieldById('customfield_10304')
def securitydevice = getFieldById('customfield_10305')
def behaviourtype = getFieldById('customfield_10306')
def vcftype = getFieldById('customfield_10307')
def alert = getFieldById('customfield_10308')
  
// Get the select list field value
def decisionFieldVal = decisionField.getValue()
// Hide fields based on value
if (decisionFieldVal.toString().contains("Vulnérabilité"))
{
 categorie.setHidden(true)
 categorie.setFormValue(-1)  
 devicetype.setHidden(true)
 devicetype.setFormValue(-1)  
 attacktype.setHidden(true)
 attacktype.setFormValue(-1)
 securitydevice.setHidden(true)
 securitydevice.setFormValue(-1)
 behaviourtype.setHidden(true)
 behaviourtype.setFormValue(-1)  
 vcftype.setHidden(true)
 vcftype.setFormValue(-1)  
 alert.setHidden(false)
 alert.setFormValue(10034)
}
else if (decisionFieldVal.toString().contains("Incident"))
{
 categorie.setHidden(false)
 devicetype.setHidden(true)
 attacktype.setHidden(true)
 securitydevice.setHidden(true)
 behaviourtype.setHidden(true)
 vcftype.setHidden(true)
 alert.setHidden(true)
 alert.setFormValue(-1)
}
else
{
 categorie.setHidden(true)
 devicetype.setHidden(true)
 attacktype.setHidden(true)
 securitydevice.setHidden(true)
 behaviourtype.setHidden(true)
 vcftype.setHidden(true)
 alert.setHidden(true)
 alert.setFormValue(-1)
}

Hope this can help to figure out what i'm trying to do !   

 

Florian PEREZ
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 16, 2023

And I finally get something OK, I cannot optimise the getFieldById part but the hide/show/required... Can be optimised by using the .each() method. This make the code much more readable :  
def ComposantField = getFieldById('customfield_14087');
def ITServiceField = getFieldById('customfield_14707');
def PerimetreField = getFieldById('customfield_14708');
def ssSystemeField = getFieldById('customfield_12503');
def plateformeField = getFieldById('customfield_12501');
def multiSelectValue = PerimetreField.value as List

if(PerimetreField.getValue() == ["IT","Legacy"]){

        //ComposantField.setHidden(false);
        //ITServiceField.setHidden(false);
        //ssSystemeField.setHidden(true);
        //plateformeField.setHidden(true);
        //ssSystemeField.setRequired(false);
        //plateformeField.setRequired(false);

        [ssSystemeField, plateformeField].each { it.setHidden(true) }
        [ComposantField, ITServiceField].each { it.setHidden(false) }
        [ssSystemeField, plateformeField].each { it.setRequired(false) }

}
else if (PerimetreField.getValue() == "IT")
   {
        //ComposantField.setHidden(true);
        //ssSystemeField.setHidden(true);
        //plateformeField.setHidden(true);
        //ITServiceField.setHidden(false);
        //ssSystemeField.setRequired(false);
        //plateformeField.setRequired(false);

        [ssSystemeField, plateformeField,ComposantField].each { it.setHidden(true) }
        [ComposantField, ITServiceField].each { it.setHidden(false) }
        [ssSystemeField, plateformeField].each { it.setRequired(false) }
   }

else if (PerimetreField.getValue() == "Legacy")
    {
        //ComposantField.setHidden(false);
        //ITServiceField.setHidden(true);
        //ssSystemeField.setHidden(true);
        //plateformeField.setHidden(true);
        //ssSystemeField.setRequired(false);
        //plateformeField.setRequired(false);

        [ComposantField].each { it.setHidden(true) }
        [ITServiceField,ssSystemeField, plateformeField].each { it.setHidden(false) }
        [ssSystemeField, plateformeField].each { it.setRequired(false) }
    }

else if (PerimetreField.getValue() == "GDS")  
    {
        //ComposantField.setHidden(true);
        //ITServiceField.setHidden(true);
        //ssSystemeField.setHidden(false);
        //plateformeField.setHidden(false);
        //ssSystemeField.setRequired(true);
        //plateformeField.setRequired(true);

        [ComposantField,ITServiceField].each { it.setHidden(true) }
        [ssSystemeField, plateformeField].each { it.setHidden(false) }
        [ssSystemeField, plateformeField].each { it.setRequired(true) }
    }

else {
        //ssSystemeField.setRequired(true);
        //plateformeField.setRequired(true);
        //ssSystemeField.setFormValue(" ");    
        //plateformeField.setFormValue(" ");

        [ssSystemeField, plateformeField].each { it.setRequired(true) }
        [ssSystemeField, plateformeField].each { it.setFormValue(" ") }
    }
Like Dave Liao likes this
Dave Liao
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
January 16, 2023

Ooh, I like this!

TAGS
AUG Leaders

Atlassian Community Events