// ==UserScript== // @name Gitlab My Merge Requests // @namespace http://tampermonkey.net/ // @version 3.0 // @description Show Link to opened Merge Requests created by user // @author 0w0miki // @icon https://www.google.com/s2/favicons?sz=64&domain=gitlab.com // @match https://gitlab.com/* // @grant GM_setValue // @grant GM_getValue // @license MIT // @downloadURL none // ==/UserScript== (function() { 'use strict'; function $(selector) { return document.querySelector(selector); } function addCreateMrButton(list) { let buttonHtml = list.children[0].outerHTML; buttonHtml = buttonHtml.replace('assignee_username', 'scope=all&state=opened&author_username'); buttonHtml = buttonHtml.replace('merge_requests_assigned', 'merge_requests_created'); buttonHtml = buttonHtml.replaceAll('Assigned', 'Created'); list.insertAdjacentHTML('beforeend', buttonHtml); } function setCreateMRCount(count) { document.querySelectorAll('a[data-track-label="merge_requests_created"] span.badge').forEach(node => { node.textContent = count; }); } const mrList = document.querySelectorAll('ul :has(>li [data-track-label*="merge_requests"])'); mrList.forEach(list => { addCreateMrButton(list); }); const lastMrCount = GM_getValue("open_mr_count") || 0; setCreateMRCount(lastMrCount); // Gitlab API include archived projects, use dashboard page for consistent experience const my_mr_url = $('a[data-track-label="merge_requests_assigned"]').href.replace('assignee_username', 'scope=all&state=opened&author_username'); fetch(my_mr_url) .then(response => response.text()) .then(html => { const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const open_mr_count = doc.querySelector('a#state-opened > span.badge').textContent; setCreateMRCount(open_mr_count); GM_setValue("open_mr_count", open_mr_count); }); })();