JIRA Create Branch Name

Adds a shortcut to create a branch name from a ticket and adds it to the clipboard. Usage: [Control] + [Alt] + Click on a ticket on the board.

目前为 2022-02-25 提交的版本。查看 最新版本

// ==UserScript==
// @name         JIRA Create Branch Name
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Adds a shortcut to create a branch name from a ticket and adds it to the clipboard. Usage: [Control] + [Alt] + Click on a ticket on the board.
// @author       cartok
// @match        https://*.atlassian.net/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=atlassian.net
// @grant        none
// @license      MIT

// ==/UserScript==
(function() {
    const DELIMITER = '-'

    const itemQueries = {
        sprintItem: target => {
            const wrapper = target.closest('.ghx-issue')
            if(!wrapper){
                console.warn('[user-script] Could not find ticket wrapper on sprint board')
                return
            }

            const prefix = (() => {
                const element = wrapper.querySelector('.ghx-highlighted-field')
                // not every task is related to an epic
                if(!element) return 'feature'
                return element.textContent.trim().toLowerCase().replace(/\s+/g, '-')
            })()

            const id = (() => {
                const element = wrapper.querySelector('a.ghx-key')
                if(!element) console.warn(`[user-script] Could not find ticket's issue key element`)
                return wrapper.querySelector('a.ghx-key').href.replace(/.*\/(.*)$/, '$1')
            })()

            const name = (() => {
                const element = wrapper.querySelector('.ghx-summary')
                if(!element) console.warn(`[user-script] Could not find ticket's summary element`)
                return element.textContent.trim().toLowerCase()
            })()

            return { prefix, id, name }
        },
        backglogItem: target => {
            const wrapper = target.closest('.js-issue')
            if(!wrapper){
                console.warn('[user-script] Could not find ticket wrapper on backlog')
                return
            }

            const prefix = (() => {
                const element = wrapper.querySelector('.ghx-label[data-epickey]')
                // not every task is related to an epic
                if(!element) return 'feature'
                return element.textContent.trim().toLowerCase().replace(/\s+/g, '-')
            })()

            const id = (() => {
                const element = wrapper.querySelector('a.ghx-key')
                if(!element) console.warn(`[user-script] Could not find ticket's issue key element`)
                return element.href.replace(/.*\/(.*)$/, '$1')
            })()

            const name = (() => {
                const element = wrapper.querySelector('.ghx-summary')
                if(!element) console.warn(`[user-script] Could not find ticket's summary element`)
                return element.textContent.trim().toLowerCase()
            })()

            return { prefix, id, name }
        }
    }

    function toBranchName ({ prefix, id, name }) {
        name = name
            .replace(/^(\[.*?\])/m, '')
            .replace(/^[^\w]+/, '')
            .replace(/[^\w]+$/, '')
            .replace(/[^\w]+/g, DELIMITER)

        return `${prefix}/${id}-${name}`
    }

    document.addEventListener('click', async event => {
        event.stopPropagation()
        if(event.ctrlKey && event.altKey){
            event.preventDefault()
        }


        // first check targets, do not override any other possible bindings
        const queryResults = Object.values(itemQueries).map(query => query(event.target)).find(Boolean)
        if(!queryResults || !event.ctrlKey || !event.altKey) return

        // do not open the ticket in a new tab when clicking on the link
        event.preventDefault()

        const branchName = toBranchName(queryResults)
        await navigator.clipboard.writeText(branchName)
        console.log(`[user-script] Branchname '${branchName}' copied to clipboard`)
    }, false)
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址