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

Script Runner create issue from WebUI Fragment

Jordan Berry February 27, 2020

Here is what I am trying to do:

Have a button live on an issue page, where the user can click it.

When clicked, I want that button to create another issue, inheriting some of the current issues field values.

In an ideal world, I would also like to be able to prompt a screen to get some user information, but that isn't a direct requirement right now

Is this something I can achieve with ScriptRunner? If so, how do I start getting the UI element to start calling a script?

It is working going through post functions, but I am trying to break this away from workflows, as they are getting messy.

 

1 answer

Suggest an answer

Log in or Sign up to answer
0 votes
Peter-Dave Sheehan
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 4, 2020

Hi @Jordan Berry 

While this can all be done with scriptrunner, this is getting into add-on territory in terms of complexity.

I know you said you have it working via workflows, but just in case your implementation is different or others come across this post, this is what I'd recommend:

  • For the "button" add a workflow transition (from any status to the same status).
  • Then for prompting for information, you use custom jira fields in a transition screen.
  • Only the final piece requires scriptrunner but in a much more limited way and potentially without any scripting. In the post function, you can use the built-in script function "clone issue and link".

But I can see the appeal of separating this from the workflow so that it can be enabled across multiple projects/workflows with one central design.

If you really want to get in the business of using web fragments and custom dialog, then I'd recommend you start with a simple example as described here and prepare yourself for a fairly long learning journey. You may wish to consult this area as you build your dialog.

I've done this myself with just about the full range of capabilities that Scriptrunner offers

  • DB resources to read/store values in a custom db
  • REST API to serve the UI element and data and receive POSTs from the form
  • Scripted JQL to enable functions to search for data stored in my db for this custom tool
  • Web Item fragments to have the button on the issues to start with
  • Web Item resources to host all the javascript used by the dialog
  • It generates events and sends custom emails

Here is what that dialog looks like:

2020-03-04 19_04_35-Commit Approvals - JIRA QAD Inc. - Corporate Issue Tracker - https___projects.qa.png

This has dropdown and popups and user preferences and type-ahead select2 drop-downs. We use it in conjunction with our subversion pre-commit hooks to control if commits using a certain Jira ticket should be allowed or not. Devs must request approval before attempting to commit and Release Managers must approve those requests. This is only during the release period while we're in code freeze mode.

So can it be done? Sure. 

Should you? That depends on you. I certainly enjoyed my learning and I'm proud of what I achieved.

Sorry, this post ran away from me :/

I hope some tidbit in here helps.

Jordan Berry March 6, 2020

Hey Peter,

Thank you for the breakdown! I was doing some more digging and I think using the create issue web fragment with behaviours may be the way I go, but I really like the approach and cleanliness of what you have shown.

Right now we have it all working with Postfunctions, but they are making the workflows convoluted, and they are causing a lot of slowdown in the project/jira instance. Trying to take as much away from that workflow as possible at the moment

Peter-Dave Sheehan
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 6, 2020

Yeah, a post function that creates many clones can take a while.

If the slowdown is not an actual server resource issue, one thing you can try, but requires creating the clone via custom script instead of built-in options, is to use the Threa.start construct: 

Thread.start{ 
//code to create your issues
}

This will start the threads to create the issues asynchronously so that the postfunction will terminate immediately and the user won't have to wait for the issues to be created before the app is available for subsequent changes.

Jon Schewe April 19, 2021

I'm looking to do something similar. Can you point me to the documentation for how to get data out of the dialog? Is the right answer to create a Web Resource with javascript that handles the button click and sends that data to another REST endpoint?

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 19, 2021

If I didn't include this link in my original response, here is the Adaptavist rudimentary documentation: https://docs.adaptavist.com/sr4js/6.23.0/features/script-fragments/custom-fragments/web-item#id-.WebItemv6.19.0-Dialogs(Advanced)

But yes, the answer is to write some javascript that your dialog will trigger and that javascript would call either native REST API in jira, custom scriptrunner REST API or even some other site's API.
You can put all the javascript in a web resource. Or you can include it in the dialog html.

In my most recent implementation of a dialog like this, I built the dialog entirely using MarkupBuilder and, after my dialog footer, I added this:

com.atlassian.jira.config.util.JiraHome
/*...*/
script(type:'text/javascript'){
def jiraHome= ComponentAccessor.getComponent(JiraHome).home
def scriptFile = new File("$jiraHome/scripts/path/to/my/jsvascript/file.js")
xml.mkp.yieldUnescaped( scriptFile.getText('UTF-8'))
}

 This is working out pretty well for me.

Jon Schewe April 19, 2021

I like the idea of putting everything inside the HTML. To be clear this is inside a REST endpoint and you put this inside the dialog html that is returned to Response. Correct?

 

Something like this:

approveRequest(
httpMethod: "GET", groups: ["all_affiliates"]
) { MultivaluedMap queryParams, body, HttpServletRequest request ->

def dialog =
"""<section role="dialog" id="sr-dialog" class="aui-layer aui-dialog2 aui-dialog2-medium" aria-hidden="true" data-aui-remove-on-hide="true">
<header class="aui-dialog2-header">
<h2 class="aui-dialog2-header-main">Request Approval</h2>
<a class="aui-dialog2-header-close">

<span class="aui-icon aui-icon-small aui-iconfont-close-dialog aui-close-button">Cancel</span>
</a>
</header>
<div class="aui-dialog2-content">
<div>
Query params: ${queryParams}
</div>

<footer class="aui-dialog2-footer">
<div class="aui-dialog2-footer-actions">
<!-- FIXME needs to do action -->
<button class="aui-button aui-button-primary">Okay</button>

<button id="dialog-close-button" class="aui-button aui-button-link">Cancel</button>
</div>
</footer>
</section>



script(type:'text/javascript') {

...

}

"""

Response.ok().type(MediaType.TEXT_HTML).entity(dialog.toString()).build()
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 19, 2021

Yes, in the REST endpoint that returns your dialog.

But don't mix MarkupBuilder with raw HTML sting.

In your example, you'd want to include

def dialog = """
<section role="dialog" id="sr-dialog" class="aui-layer aui-dialog2 aui-dialog2-medium" aria-hidden="true" data-aui-remove-on-hide="true">
<header>...</header>
<div class="aui-dialog2-content"> ... </div
<footer>...</footer>
<script type="text/javascript>
  /*your js code here */
</script>
<section>
"""

Or if you want to keep your js code in a separate file and combine them at runtime (like my example, 

import com.atlassian.jira.config.util.JiraHome
def jiraHome= ComponentAccessor.getComponent(JiraHome).home
def scriptFile = new File("$jiraHome/scripts/path/to/my/jsvascript/file.js")

def dialog = """
<section role="dialog" id="sr-dialog" class="aui-layer aui-dialog2 aui-dialog2-medium" aria-hidden="true" data-aui-remove-on-hide="true">
<header>...</header>
<div class="aui-dialog2-content"> ... </div
<footer>...</footer>
<script type="text/javascript">
  ${scriptFile.getText('UTF-8')}
</script>
<section>
"""
Like Jon Schewe likes this
Jon Schewe April 19, 2021

Thank you, that helps a lot!

In the end what I really need to do is get a comment from a user and then execute a transition on a different issue. Do you know of an easy way to do that?

https://community.atlassian.com/t5/Jira-Software-questions/How-to-add-a-button-that-executes-a-transition-on-another-ticket/qaq-p/1661311#M133139

TAGS
AUG Leaders

Atlassian Community Events