JIRA Subtask Move Plugin

Plugin to allow moving of sub-tasks in JIRA

  1. // ==UserScript==
  2. // @name JIRA Subtask Move Plugin
  3. // @description Plugin to allow moving of sub-tasks in JIRA
  4. // @version 0.5.2
  5. // @author Max Schlüssel <lokoxe@gmail.com>
  6. // @namespace https://ghostkernel.org/
  7. // @match *://*/*
  8. // @grant GM_addStyle
  9. // ==/UserScript==
  10.  
  11. (function($) {
  12. 'use strict';
  13.  
  14. if($ == undefined) return;
  15. if(!$("body").is("#jira")) {
  16. return;
  17. }
  18.  
  19. // Add styling for our dragging knob
  20. GM_addStyle(" \
  21. .issuerow .dragger { \
  22. display: block; \
  23. height: 10px; \
  24. margin-top: 15px; \
  25. margin-right: 5px; \
  26. border: none !important; \
  27. cursor: move; \
  28. background: repeating-linear-gradient(0, \
  29. transparent 0%, \
  30. transparent 2%, #aaa 2%, \
  31. #aaa 3%, transparent 3%);\
  32. } \
  33. .issuerow.dragged { \
  34. background-color: #eee !important; \
  35. } \
  36. ");
  37.  
  38. $(document).ready(function() {
  39. var issueRows = $(".issuerow");
  40.  
  41. var draggedRow = null;
  42. var dropSequence = null;
  43. var insertAfter = false;
  44.  
  45. // Create a dragger knob on each issue row
  46. issueRows.each(function() {
  47. var issueRow = $(this);
  48. var dragger = $("<td>");
  49. dragger.addClass("dragger");
  50. issueRow.prepend(dragger);
  51. dropSequence = null;
  52.  
  53. // Start dragging
  54. dragger.bind("mousedown.drag", function(e) {
  55. e.preventDefault();
  56. draggedRow = dragger.parent();
  57. draggedRow.addClass("dragged");
  58. });
  59. });
  60.  
  61. // Update dragged row & move it to new position
  62. $(document).bind("mousemove.drag", function(e) {
  63. e.preventDefault();
  64. if(draggedRow == null) {
  65. return;
  66. }
  67.  
  68. var el = $(e.target);
  69. var hoveredRow = el.closest(".issuerow");
  70. if(hoveredRow.length > 0) {
  71. if(!draggedRow.is(hoveredRow)) {
  72. draggedRow.detach();
  73. if(e.offsetY < 20) {
  74. insertAfter = false;
  75. draggedRow.insertBefore(hoveredRow);
  76. } else {
  77. insertAfter = true;
  78. draggedRow.insertAfter(hoveredRow);
  79. }
  80. }
  81. dropSequence = draggedRow.index();
  82. }
  83. });
  84.  
  85. // Perform the actual task update
  86. $(document).bind("mouseup.drag", function(e) {
  87. if(draggedRow != null && dropSequence != null) {
  88. e.preventDefault();
  89. // Take original move URL & build update URL
  90. var moveUrl = draggedRow.find(".subtask-reorder a").first().attr("href");
  91. var currentSequence = moveUrl.substring(moveUrl.indexOf("&currentSubTaskSequence=") + "&currentSubTaskSequence=".length, moveUrl.indexOf("&subTaskSequence="));
  92. if(currentSequence != dropSequence) {
  93. var id = moveUrl.substring(moveUrl.indexOf("id=") + "id=".length, moveUrl.indexOf("&currentSubTaskSequence="));
  94. var newLink = "/secure/MoveIssueLink.jspa?id=" + id + "&currentSubTaskSequence=" + currentSequence + "&subTaskSequence=" + dropSequence + "#view-subtasks";
  95. window.location = newLink;
  96. }
  97.  
  98. // Reset dragged row
  99. draggedRow.removeClass("dragged");
  100. draggedRow = null;
  101. }
  102. });
  103. });
  104. })($);