Skip to content

Instantly share code, notes, and snippets.

@AkdM
Last active April 8, 2025 10:18
Show Gist options
  • Select an option

  • Save AkdM/127a428014e3fd32668f887d5ddd8b4f to your computer and use it in GitHub Desktop.

Select an option

Save AkdM/127a428014e3fd32668f887d5ddd8b4f to your computer and use it in GitHub Desktop.

Revisions

  1. AkdM revised this gist Apr 8, 2025. 2 changed files with 3 additions and 96 deletions.
    96 changes: 0 additions & 96 deletions JIRA-branch-name-copy.js
    Original file line number Diff line number Diff line change
    @@ -1,96 +0,0 @@
    // ==UserScript==
    // @name JIRA Branch Name Copy
    // @namespace http://tampermonkey.net/
    // @version 1.0
    // @description JIRA branch name button
    // @author Anthony Da Mota
    // @match https://put your domain here/browse/*
    // @icon https://www.google.com/s2/favicons?sz=64&domain=atlassian.com
    // @grant none
    // ==/UserScript==

    (function () {
    function waitForElm(selector) {
    return new Promise(resolve => {
    if (document.querySelector(selector)) {
    return resolve(document.querySelector(selector));
    }

    const observer = new MutationObserver(mutations => {
    if (document.querySelector(selector)) {
    observer.disconnect();
    resolve(document.querySelector(selector));
    }
    });

    // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
    observer.observe(document.body, {
    childList: true,
    subtree: true
    });
    });
    }

    const kebabize = str => {
    return str.replace(/\W+/g, '-').toLowerCase();
    }

    waitForElm('.aui-toolbar2-secondary').then((toolbar) => {
    // Create the button
    const button = document.createElement('a')
    const body = document.querySelector('body')
    button.id = 'jira-branchname-trigger'
    button.role = 'button'
    button.className = 'aui-button toolbar-trigger viewissue-share'
    button.href = '#'
    button.setAttribute('aria-describedby', 'aui-tooltip')
    button.innerHTML = '<span class="icon aui-icon aui-icon-small aui-iconfont-copy"></span> <span class="trigger-label">Copy Branch name</span><p class="assistive">Copy branch name</p>'
    toolbar.appendChild(button)

    // Copy the branchname to clipboard
    button.addEventListener('click', async (event) => {
    event.stopPropagation()
    event.preventDefault()

    // get the ticket id
    const ticketId = document.querySelector('#key-val').textContent.trim()

    // get the ticket name
    const ticketName = kebabize(document.querySelector('#summary-val').textContent.trim())

    // get the ticket prefix from the #type-val.textContent, if the text inside is:
    // `Bug` => `fix`
    // other => `feature`
    const ticketType = document.querySelector('#type-val').textContent.trim()
    let ticketPrefix = 'feature'
    if (ticketType.toLowerCase() === 'bug') ticketPrefix = 'fix'

    // create the branchname
    const branchName = `${ticketPrefix}/${ticketId}-${ticketName}`

    // copy to clipboard
    await navigator.clipboard.writeText(branchName)

    // Add a notification that the branchname has been copied
    const notification = document.createElement('div')
    notification.className = 'aui-message aui-message-success'
    notification.innerHTML = `<p class="title">Branch name copied</p><p>${branchName}</p>`
    notification.style.position = 'absolute'
    notification.style.top = '60px'
    notification.style.right = '20px'
    notification.style.zIndex = '9999'
    notification.style.backgroundColor = '#fff'
    notification.style.border = '1px solid #ccc'
    notification.style.padding = '10px'
    notification.style.borderRadius = '5px'
    notification.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)'
    // add margin left to the title
    notification.querySelector('.title').style.paddingLeft = '30px'
    notification.querySelector('.title').style.paddingTop = '5px'
    body.appendChild(notification)
    setTimeout(() => {
    notification.remove()
    }, 3000)
    })
    })
    })();
    3 changes: 3 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,3 @@
    # JIRA Branch Name Copy

    It's now here: https://github.com/AkdM/JIRA-Branch-Name-Copy
  2. AkdM revised this gist Apr 7, 2025. No changes.
  3. AkdM created this gist Apr 7, 2025.
    96 changes: 96 additions & 0 deletions JIRA-branch-name-copy.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,96 @@
    // ==UserScript==
    // @name JIRA Branch Name Copy
    // @namespace http://tampermonkey.net/
    // @version 1.0
    // @description JIRA branch name button
    // @author Anthony Da Mota
    // @match https://put your domain here/browse/*
    // @icon https://www.google.com/s2/favicons?sz=64&domain=atlassian.com
    // @grant none
    // ==/UserScript==

    (function () {
    function waitForElm(selector) {
    return new Promise(resolve => {
    if (document.querySelector(selector)) {
    return resolve(document.querySelector(selector));
    }

    const observer = new MutationObserver(mutations => {
    if (document.querySelector(selector)) {
    observer.disconnect();
    resolve(document.querySelector(selector));
    }
    });

    // If you get "parameter 1 is not of type 'Node'" error, see https://stackoverflow.com/a/77855838/492336
    observer.observe(document.body, {
    childList: true,
    subtree: true
    });
    });
    }

    const kebabize = str => {
    return str.replace(/\W+/g, '-').toLowerCase();
    }

    waitForElm('.aui-toolbar2-secondary').then((toolbar) => {
    // Create the button
    const button = document.createElement('a')
    const body = document.querySelector('body')
    button.id = 'jira-branchname-trigger'
    button.role = 'button'
    button.className = 'aui-button toolbar-trigger viewissue-share'
    button.href = '#'
    button.setAttribute('aria-describedby', 'aui-tooltip')
    button.innerHTML = '<span class="icon aui-icon aui-icon-small aui-iconfont-copy"></span> <span class="trigger-label">Copy Branch name</span><p class="assistive">Copy branch name</p>'
    toolbar.appendChild(button)

    // Copy the branchname to clipboard
    button.addEventListener('click', async (event) => {
    event.stopPropagation()
    event.preventDefault()

    // get the ticket id
    const ticketId = document.querySelector('#key-val').textContent.trim()

    // get the ticket name
    const ticketName = kebabize(document.querySelector('#summary-val').textContent.trim())

    // get the ticket prefix from the #type-val.textContent, if the text inside is:
    // `Bug` => `fix`
    // other => `feature`
    const ticketType = document.querySelector('#type-val').textContent.trim()
    let ticketPrefix = 'feature'
    if (ticketType.toLowerCase() === 'bug') ticketPrefix = 'fix'

    // create the branchname
    const branchName = `${ticketPrefix}/${ticketId}-${ticketName}`

    // copy to clipboard
    await navigator.clipboard.writeText(branchName)

    // Add a notification that the branchname has been copied
    const notification = document.createElement('div')
    notification.className = 'aui-message aui-message-success'
    notification.innerHTML = `<p class="title">Branch name copied</p><p>${branchName}</p>`
    notification.style.position = 'absolute'
    notification.style.top = '60px'
    notification.style.right = '20px'
    notification.style.zIndex = '9999'
    notification.style.backgroundColor = '#fff'
    notification.style.border = '1px solid #ccc'
    notification.style.padding = '10px'
    notification.style.borderRadius = '5px'
    notification.style.boxShadow = '0 2px 10px rgba(0, 0, 0, 0.1)'
    // add margin left to the title
    notification.querySelector('.title').style.paddingLeft = '30px'
    notification.querySelector('.title').style.paddingTop = '5px'
    body.appendChild(notification)
    setTimeout(() => {
    notification.remove()
    }, 3000)
    })
    })
    })();