Azure DevOps Zendesk Link v1.0.0

← Back to User Scripts

Script Content

// ==UserScript==
// @name         Azure DevOps Zendesk Link
// @namespace    http://tampermonkey.net/
// @version      1.0.0
// @description  Adds a button to Azure DevOps work items to open the corresponding Zendesk ticket.
// @author       Jules
// @match        https://dev.azure.com/*/_workitems/edit/*
// @grant        GM_openInTab
// @grant        GM_addStyle
// ==/UserScript==

(function() {
    'use strict';

    const zendeskRegex = /\[Zendesk (\d+)\]/;

    function addButton(titleElement) {
        const match = titleElement.value.match(zendeskRegex);
        if (!match) {
            return;
        }

        const zendeskId = match[1];
        const zendeskUrl = `https://audacia.zendesk.com/agent/tickets/${zendeskId}`;

        // Check if button already exists
        if (document.getElementById('zendesk-link-button')) {
            return;
        }

        const zendeskIconSvg = `
            
               
               
            
        `;

        const button = document.createElement('button');
        button.id = 'zendesk-link-button';
        button.innerHTML = zendeskIconSvg;
        button.onclick = () => {
            GM_openInTab(zendeskUrl, { active: true });
        };

        const titleElementParent = titleElement.parentElement;
        titleElementParent.style.position = 'relative';

        // Add padding to the title element to make space for the button
        titleElement.style.paddingLeft = '40px';

        GM_addStyle(`
            #zendesk-link-button {
                position: absolute;
                left: 0px;
                top: 50%;
                transform: translateY(-50%);
                width: 34px;
                height: 34px;
                z-index: 1000;
                border: none;
                background: transparent;
                cursor: pointer;
                padding: 3px;
            }
            #zendesk-link-button svg {
                width: 100%;
                height: 100%;
            }
        `);

        titleElementParent.appendChild(button);
    }

    const observer = new MutationObserver(() => {
        const titleElement = document.querySelector('[aria-label="Title field"]');
        if (titleElement) {
            addButton(titleElement);
        }
    });

    observer.observe(document.body, {
        childList: true,
        subtree: true
    });
})();