jira-issue-navigate

Go to the next/prev issue using buttons

当前为 2022-05-06 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name jira-issue-navigate
  3. // @version 0.5.0
  4. // @description Go to the next/prev issue using buttons
  5. // @author Amin Yahyaabadi
  6. // @match https://*.atlassian.net/browse/*
  7. // @match https://*.atlassian.net/jira/software/projects/*
  8. // @grant none
  9. // @license MIT
  10. // @namespace AminYa
  11. // @homepage https://github.com/aminya/jira-issue-navigate
  12. // ==/UserScript==
  13. function $1994abed16d377af$var$praseUrl() {
  14. const currentURL = window.location.href;
  15. // parse the URL
  16. const urlMatch = /(.*)\.atlassian\.net\/(browse|jira\/software\/projects)\/(.*)-(\d*)(\?.*)?/;
  17. const res = urlMatch.exec(currentURL);
  18. // if the url doesn't match return
  19. if (res === null) return null;
  20. const [, company, middle, project, issue, queries] = res;
  21. const issueNumber = parseInt(issue, 10);
  22. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  23. const queriesString = queries === undefined ? "" : queries;
  24. return {
  25. company: company,
  26. middle: middle,
  27. project: project,
  28. issueNumber: issueNumber,
  29. queriesString: queriesString
  30. };
  31. }
  32. function $1994abed16d377af$var$createButton(company, middle, project, issueNumber, queriesString, direction) {
  33. // create a button to go to the next issue
  34. const button = document.createElement("a");
  35. button.id = `${direction}-issue-btn`;
  36. button.setAttribute("aria-label", `Go to ${direction} issue`);
  37. button.setAttribute("aria-expanded", "false");
  38. button.setAttribute("aria-haspopup", "true");
  39. button.setAttribute("type", "button");
  40. button.style.borderRadius = "2px";
  41. button.style.alignSelf = "center";
  42. button.style.padding = "7px";
  43. const buttonIcon = document.createElement("div");
  44. buttonIcon.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 20.633 20.633" style="enable-background:new 0 0 20.633 20.633" xml:space="preserve">
  45. <path d="M15.621 9.844 5.971.195A.652.652 0 0 0 5.5 0a.664.664 0 0 0-.473.195l-.013.012a.677.677 0 0 0-.197.475v4.682c0 .178.071.348.197.471l4.481 4.482-4.481 4.479a.667.667 0 0 0-.197.475v4.68c0 .18.071.354.197.475l.013.01a.664.664 0 0 0 .947 0l9.647-9.646a.671.671 0 0 0 0-.946z" />
  46. </svg>`;
  47. button.style.background = "none";
  48. button.style.border = "none";
  49. // rotate the icon if it's the prev button
  50. if (direction === "prev") button.style.transform = "rotate(180deg) translate(0px, 3px)";
  51. // attach the icon
  52. button.appendChild(buttonIcon);
  53. // create a tooltip for the button that shows "Go to next issue" on hover
  54. $1994abed16d377af$var$addTooltip(button);
  55. // set the the button class
  56. const likeButtonSelector = "#jira-issue-header-actions > div > div > div:nth-child(4)";
  57. const likeButton = document.querySelector(likeButtonSelector);
  58. if (likeButton !== null) {
  59. console.debug(`${likeButtonSelector} was not found`);
  60. button.className = likeButton.className;
  61. }
  62. // issue number
  63. let targetIssueNumber;
  64. if (direction === "next") targetIssueNumber = issueNumber + 1;
  65. else targetIssueNumber = issueNumber - 1;
  66. // create the next issue url
  67. const issueURL = `${company}.atlassian.net/${middle}/${project}-${targetIssueNumber}${queriesString}`;
  68. // navigate to the next issue on click
  69. button.setAttribute("href", issueURL);
  70. return button;
  71. }
  72. function $1994abed16d377af$var$addTooltip(button, direction = "next") {
  73. // create a tooltip for the button that shows "Go to next issue" on hover
  74. const buttonTooltip = document.createElement("div");
  75. buttonTooltip.id = `${direction}-issue-btn-tooltip`;
  76. buttonTooltip.setAttribute("style", `position: relative;`);
  77. button.prepend(buttonTooltip);
  78. const buttonTooltipText = document.createElement("div");
  79. buttonTooltipText.innerHTML = direction[0].toUpperCase() + direction.slice(1);
  80. buttonTooltipText.setAttribute("style", `width: 50px;
  81. text-align: center;
  82. border-radius: 4px;
  83. padding: 1px 0;
  84. font-size: small;
  85. background: #172B4D;
  86. color: white;
  87. position: absolute;
  88. z-index: 1;
  89. bottom: 100%;
  90. left: 50%;
  91. margin-left: -30px;
  92. margin-bottom: 15px;
  93. `);
  94. buttonTooltipText.style.visibility = "hidden";
  95. buttonTooltip.prepend(buttonTooltipText);
  96. button.addEventListener("mouseover", ()=>{
  97. button.style.background = "#091e4214";
  98. buttonTooltipText.style.visibility = "visible";
  99. });
  100. button.addEventListener("mouseleave", ()=>{
  101. button.style.background = "none";
  102. buttonTooltipText.style.visibility = "hidden";
  103. });
  104. }
  105. function $1994abed16d377af$var$main() {
  106. const parseResult = $1994abed16d377af$var$praseUrl();
  107. if (parseResult === null) return;
  108. const { company: company , middle: middle , project: project , issueNumber: issueNumber , queriesString: queriesString } = parseResult;
  109. // create a button to go to the next issue
  110. const nextButton = $1994abed16d377af$var$createButton(company, middle, project, issueNumber, queriesString, "next");
  111. const prevButton = $1994abed16d377af$var$createButton(company, middle, project, issueNumber, queriesString, "prev");
  112. // get the toolbar
  113. const toolbarSelector = "#jira-issue-header-actions > div > div";
  114. const toolbar = document.querySelector(toolbarSelector);
  115. if (toolbar === null) {
  116. console.debug(`${toolbarSelector} was not found`);
  117. return;
  118. }
  119. // attach the button to the toolbar
  120. toolbar.prepend(prevButton);
  121. toolbar.prepend(nextButton);
  122. }
  123. setTimeout($1994abed16d377af$var$main, 2000);
  124.  
  125.  
  126. //# sourceMappingURL=main.js.map