Javascript: read user_managers project
Now let's change our code. Right now we set the value of the Approver field to manager1 if the Reporter field is admin and manager2 in all other cases. But we created the user_managers project for mapping of users and managers and we need to take the manager of the Reporter from this project.
The code for this requirement will be like this:
function setApproverFieldByReporter() {
$.get( "http://localhost:8080/rest/api/2/search?jql=project%3DUS%20and%20%22user%22%20%3D%20" + $("#reporter").val(), function( data ) {
$("#customfield_10301").val( data.issues[0].fields.customfield_10201.name);
});
};
$(function () {
JIRA.bind(JIRA.Events.NEW_CONTENT_ADDED, function (e, $context, reason) {
if (reason == JIRA.CONTENT_ADDED_REASON.dialogReady) {
$("#reporter").change( function(e) {
setApproverFieldByReporter();
});
setApproverFieldByReporter();
}
});
});
setApproverFieldByReporter selects issues from the user_managers project where the user field equals to $("#reporter").val() (which is our Reporter) and sets the Approver field with the chosen value.
Now the complete script looks like this:
<script>
function setApproverFieldByReporter() {
$.get( "http://localhost:8080/rest/api/2/search?jql=project%3DUS%20and%20%22user%22%20%3D%20" + $("#reporter").val(), function( data ) {
$("#customfield_10301").val( data.issues[0].fields.customfield_10201.name);
});
};
function disableAporoverField() {
$("#customfield_10301").focus(function() {
this.blur();
});
};
function hideSummaryField() {
$("input#summary").val("mapping");
$("input#summary").parent().css("display", "None");
}
function hideReadyForWorkButtonConditionally() {
if ($("#customfield_10301-val").text()) {
if (JIRA.Users.LoggedInUser.userName() != $.trim($("#customfield_10301-val").text())) {
$('#action_id_21').addClass('hidden');
}
}
}
$(function () {
JIRA.bind(JIRA.Events.NEW_CONTENT_ADDED, function (e, $context, reason) {
if (reason == JIRA.CONTENT_ADDED_REASON.dialogReady) {
$("#reporter").change( function(e) {
setApproverFieldByReporter();
});
setApproverFieldByReporter();
disableAporoverField();
hideSummaryField();
}
});
hideReadyForWorkButtonConditionally();
});
</script>
If you have a look at this script you will find out that checking for errors are missing. For example, what will you do if there are no managers defined for a user in the user_managers project? Or what will you do if more than 1 manager defined? And so on. If you add this logic your script will become bigger.
Test our JavaScript code
If you start testing our JavaScript code, you will see that the summary field is hidden for all projects. Why? Because we did not say that we need to hide the summary field only for the US project. I will not add this code you can do it yourself.
Also we search the manager for a reporter for all projects, we need to say to our routines that it should be done only for the AP project.
As you remember we have hidden the "Ready For Work" button for non-managers of the Reporter. But we have hidden it only in the issue view screen. But we can transition issues not only in the issue view screen but in many other places in Jira. For example, in the Issue Navigator:
As you can see the "Ready For Work" transition is there. Now you need to find all places where an issue could be transitioned and hide this transition there.
Another problem if I push the AP-2 link in the Issue Navigator the issue view screen will be open. We expect that the "Ready For Work" will be hidden, but it is not true, because our announcement banner script will not be reread. How should we fix it? Should we go back to setInterval? Or maybe we should look for an event in Jira source code?
You see there are many problems which you are going to meet while developing solutions with JavaScript. And your JavaScript code will grow bigger and bigger and you will have more and more bugs.
Readability of JavaScript code
Look at our code:
<script>
function setApproverFieldByReporter() {
$.get( "http://localhost:8080/rest/api/2/search?jql=project%3DUS%20and%20%22user%22%20%3D%20" + $("#reporter").val(), function( data ) {
$("#customfield_10301").val( data.issues[0].fields.customfield_10201.name);
});
};
function disableAporoverField() {
$("#customfield_10301").focus(function() {
this.blur();
});
};
function hideSummaryField() {
$("input#summary").val("mapping");
$("input#summary").parent().css("display", "None");
}
function hideReadyForWorkButtonConditionally() {
if ($("#customfield_10301-val").text()) {
if (JIRA.Users.LoggedInUser.userName() != $.trim($("#customfield_10301-val").text())) {
$('#action_id_21').addClass('hidden');
}
}
}
$(function () {
JIRA.bind(JIRA.Events.NEW_CONTENT_ADDED, function (e, $context, reason) {
if (reason == JIRA.CONTENT_ADDED_REASON.dialogReady) {
$("#reporter").change( function(e) {
setApproverFieldByReporter();
});
setApproverFieldByReporter();
disableAporoverField();
hideSummaryField();
}
});
hideReadyForWorkButtonConditionally();
});
</script>
It is a disaster. We have many magic numbers and strings like customfield_10201, action_id_21, customfield_10301, which make our code not understandable. What is the JIRA.CONTENT_ADDED_REASON.dialogReady? When do we have this reason? It is not transparent.
I would say our code is a complete mess. And all code in announcement banners I have seen look like this. Do you want to make it better? How would you do it? You can not use TypeScript or modern versions of ECMAscript. Your code will be a mess anyway.
Make your JavaScript code transferable
Another problem that we can not move this code to another Jira environment because we use magic ids: customfield_10201, action_id_21, customfield_10301, and these ids will be different in that other environment. You would need to write code which would programatically define ids out of names. Do you think it is possible? No it is not possible. Because multiple custom fields can have the same name. I will talk about it in detail in next parts of this article.
You can say that custom fields can have only unique names in your Jira instance. In this case you can use Jira Rest API to get all custom fields and select custom field id by name. But again it would make your code bigger.
Conclusion on JavaScript in Announcement banner
If you use JavaScript in the announcement banner you have the following problems:
In short I would say you never should go for announcement banner JavaScript code. I will tell you about other solutions which can be used in next parts of this article.
Alexey Matveev
software developer
MagicButtonLabs
Philippines
1,575 accepted answers
1 comment