floodmeadows / Jira append description from template story

// ==UserScript==
// @name         Jira append description from template story
// @namespace    https://openuserjs.org/users/floodmeadows
// @description  Adds button to copy description from template story and append to current story description
// @copyright    2023, floodmeadows (https://openuserjs.org/users/floodmeadows)
// @license      MIT
// @version      0.1
// @include      https://jira.*.uk/browse/*
// @updateURL    https://openuserjs.org/meta/floodmeadows/Jira_append_description_from_template_story.meta.js
// @downloadURL  https://openuserjs.org/install/floodmeadows/Jira_append_description_from_template_story.user.js
// @grant        none
// ==/UserScript==

/* jshint esversion: 6 */

//--- Customise your template story here ----//
const templateIssueKey = 'HMA-6132';
//-------------------------------------//

const debug = false;
const targetElementForButton = document.getElementById('descriptionmodule-label');

(function () {
    'use strict';

    if (debug) addButton("Clear description", targetElementForButton, clearDescription);
    addButton("Append template from " + templateIssueKey, targetElementForButton, appendTemplateTextToCurrentDescription);
})();

function addButton(buttonText, targetElement, functionName) {
    const button = document.createElement("button");
    button.setAttribute("class", "aui-button");
    button.addEventListener("click", functionName);
    const text = document.createTextNode(buttonText);
    button.appendChild(text);
    targetElement.after(button);
}

function appendTemplateTextToCurrentDescription() {
    //--- Get standard info ---//
    const currentUrl = new URL(document.URL);
    const jiraBaseUrl = currentUrl.protocol + '//' + currentUrl.host;
    const currentIssueKey = document.getElementById("key-val").childNodes[0].nodeValue;
    const currentIssueApiUrl = `${jiraBaseUrl}/rest/api/latest/issue/${currentIssueKey}`;
    const templateIssueApiUrl = `${jiraBaseUrl}/rest/api/latest/issue/${templateIssueKey}`;
    if(debug) console.log('URL: ' + currentIssueApiUrl);

    var headers = new Headers();
    headers.append("Content-Type", "application/json");

    var requestOptions = {
        method: 'GET',
        headers: headers
    };

    /* --- start block for fetching the template issue details --- */
    fetch(templateIssueApiUrl, requestOptions)
        .then(response => {
            const jsonPromise = response.json()
                .then(data => {
                    const templateIssue = data;
                    if (debug) console.log(templateIssue);
                    console.log("Template description = '" + templateIssue.fields.description + ".'");
                    const templateDescription = templateIssue.fields.description;
                    /* --- start block for fetching the current issue details --- */
                    fetch(currentIssueApiUrl, requestOptions)
                        .then(response => {
                        const jsonPromise = response.json()
                        .then(data => {
                            const currentIssue = data;
                            if (debug) console.log(currentIssue);
                            console.log("Current description = '" + currentIssue.fields.description + ".'");
                            const currentDescription = currentIssue.fields.description;
                            var newDescription = "";
                            if (currentDescription != null) {
                                newDescription = currentDescription + "\r\n\r\n" + templateDescription;
                            } else {
                                newDescription = templateDescription;
                            }
                            console.log("New description = '" + newDescription + ".'");
                            updateDescription(newDescription);

                        });
                    })
                        .catch(error => {
                        console.log('Error fetching current issue: ', error);
                        return false;
                    });
                    /* --- end block for fetching the current issue details --- */
                });
            })
        .catch(error => {
            console.log('Error fetching template issue: ', error);
            return false;
        });
        /* --- end block for fetching the template issue details --- */
}

function clearDescription() {
    updateDescription("");
}

function updateDescription(newDescription) {
    //--- Get standard info ---//
    const currentUrl = new URL(document.URL);
    const jiraBaseUrl = currentUrl.protocol + '//' + currentUrl.host;
    const currentIssueKey = document.getElementById("key-val").childNodes[0].nodeValue;
    const updateIssueUrl = `${jiraBaseUrl}/rest/api/latest/issue/${currentIssueKey}`;

    var headers = new Headers();
    headers.append("Content-Type", "application/json");

    var jsonToUpdateIssue = JSON.stringify({
        "fields": {
            "description": newDescription
        }
    });

    if (debug) console.log(jsonToUpdateIssue);

    var requestOptions = {
        method: 'PUT',
        headers: headers,
        body: jsonToUpdateIssue
    };

    fetch(updateIssueUrl, requestOptions)
        .then(response => {
            console.log(response.text());
            if(!debug) window.location.assign(currentUrl);
        })
        .catch(error => console.log('error', error));
}