JombY / Jira Task Navigation Buttons

// ==UserScript==
// @name         Jira Task Navigation Buttons
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Add "Previous Task" and "Next Task" buttons to Jira Cloud.
// @author       JombY
// @license      Apache-2.0
// @match        https://*.atlassian.net/browse/*
// @icon         https://www.google.com/s2/favicons?domain=jira.com
// @grant        none
// ==/UserScript==

/* jshint esversion: 8 */

(function () {
    'use strict';

    const createNavigationButton = (text, icon) => {
        const button = document.createElement('button');
        button.innerHTML = `<span style="font-size: 16px; margin-right: 5px;">${icon}</span> ${text}`;
        button.style.position = 'relative'; // Change to 'relative' from 'fixed'
        button.style.marginBottom = '10px'; // Add margin to separate buttons
        button.style.zIndex = '1'; // Ensure the buttons are above other elements
        return button;
    };

    const navigateToTask = (direction) => {
        const taskNumMatch = window.location.href.match(/([A-Z]+-\d+)/);

        if (taskNumMatch) {
            const [, prefix, number] = taskNumMatch[1].match(/([A-Z]+)-(\d+)/);

            const newTaskNumber = direction === 'previous' ? Number(number) - 1 : Number(number) + 1;

            if (newTaskNumber > 0) {
                const newTaskUrl = `${prefix}-${newTaskNumber}`;
                window.location.href = window.location.href.replace(taskNumMatch[1], newTaskUrl);
            }
        }
    };

    const addButtonToNav = () => {
        const navElement = document.querySelector('#jira-issue-header > div > div > div > nav');
        if (navElement && !navElement.classList.contains('task-navigation-buttons-added')) {
            const previousTaskButton = createNavigationButton('Previous Task', '&longleftarrow;');
            previousTaskButton.addEventListener('click', () => navigateToTask('previous'));
            navElement.appendChild(previousTaskButton);

            const nextTaskButton = createNavigationButton('Next Task', '&LongRightArrow;');
            nextTaskButton.addEventListener('click', () => navigateToTask('next'));
            navElement.appendChild(nextTaskButton);

            navElement.classList.add('task-navigation-buttons-added');
        }
    };

    const observerConfig = { childList: true, subtree: true };
    const observerCallback = (mutationsList) => {
        for (const mutation of mutationsList) {
            if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                addButtonToNav();
            }
        }
    };

    const observer = new MutationObserver(observerCallback);

    // Wait for the DOM to be fully loaded
    if (document.readyState === 'complete' || document.readyState === 'interactive') {
        addButtonToNav();
    } else {
        document.addEventListener('DOMContentLoaded', addButtonToNav);
    }

    // Start observing changes in the DOM
    observer.observe(document.body, observerConfig);
})();