快速复制,自动working/ready

Add buttons for copying the id/summary/link and for auto working/ready

当前为 2023-07-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Quick Copy and Auto Working/Ready
  3. // @name:zh-CN 快速复制,自动working/ready
  4. // @namespace http://tampermonkey.net/
  5. // @description Add buttons for copying the id/summary/link and for auto working/ready
  6. // @description:zh-cn 快速复制id/summary/link,自动working/ready
  7. // @author Jackie
  8. // @version 0.2
  9. // @match https://idart.mot.com/browse/*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=mot.com
  11. // @run-at document-start
  12. // @grant GM.addStyle
  13. // @grant GM.log
  14. // ==/UserScript==
  15.  
  16. (function () {
  17. 'use strict';
  18.  
  19. let observeDOM = (function () {
  20. let MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  21. let eventListenerSupported = window.addEventListener;
  22.  
  23. return function (obj, onAddCallback, onRemoveCallback) {
  24. if (MutationObserver) {
  25. // define a new observer
  26. let mutationObserver = new MutationObserver(function (mutations, observer) {
  27. if (mutations[0].addedNodes.length && onAddCallback != undefined) {
  28. onAddCallback();
  29. }
  30. });
  31. // have the observer observe foo for changes in children
  32. mutationObserver.observe(obj, {
  33. childList: true
  34. });
  35. } else if (eventListenerSupported) {
  36. obj.addEventListener('DOMNodeInserted', onAddCallback, false);
  37. }
  38. };
  39. })();
  40. detectElementBySelector('.issue-container', ()=>{
  41. addButtons();
  42. observeDOM(document.getElementsByClassName('issue-container')[0], /*onAdd*/ addButtons, /*onRemove*/ addButtons);
  43. }, 100)
  44. })();
  45.  
  46.  
  47. function addButtons() {
  48. addWorkingButton();
  49. addReadyButton();
  50. if(document.getElementById("copy_id")) return;
  51. console.log(`=======================addCopyBtn`);
  52. const container = document.getElementById('stalker');
  53. const issueKey = document.getElementById("key-val");
  54. const issueName = document.getElementById("summary-val");
  55.  
  56. if(!container) return;
  57.  
  58. const divE = document.createElement("div");
  59. divE.id="snackbar";
  60. divE.innerHTML="Copied succesfully"
  61. container.appendChild(divE);
  62.  
  63. const newElement = document.createElement("li");
  64. const idE = document.createElement("a");
  65. idE.innerHTML="Copy id";
  66. idE.className="aui-button aui-button-primary aui-style";
  67. idE.id="copy_id";
  68. idE.onclick= (e) => {
  69. var snackbar = document.getElementById("snackbar");
  70. snackbar.className = "show";
  71.  
  72. navigator.clipboard.writeText(issueKey.childNodes[0].data);
  73.  
  74. setTimeout(function(){
  75. snackbar.className = snackbar.className.replace("show", "");
  76. }, 1500);
  77. };
  78. newElement.appendChild(idE);
  79. issueKey.parentNode.parentNode.appendChild(newElement);
  80.  
  81. const newElement2 = document.createElement("li");
  82. const summaryE = document.createElement("a");
  83. summaryE.className="aui-button aui-button-primary aui-style";
  84. summaryE.innerHTML="Copy summary";
  85. summaryE.id="copy_summary";
  86. summaryE.onclick= (e) => {
  87. var snackbar = document.getElementById("snackbar");
  88. snackbar.className = "show";
  89.  
  90. navigator.clipboard.writeText(issueName.childNodes[0].data);
  91.  
  92. setTimeout(function(){
  93. snackbar.className = snackbar.className.replace("show", "");
  94. }, 1500);
  95. };
  96.  
  97. newElement2.appendChild(summaryE);
  98. issueKey.parentNode.parentNode.appendChild(newElement2);
  99.  
  100. const newElement3 = document.createElement("li");
  101. const linkE = document.createElement("a");
  102. linkE.className="aui-button aui-button-primary aui-style";
  103. linkE.innerHTML="Copy link";
  104. linkE.id="copy_link";
  105. linkE.onclick= (e) => {
  106. var snackbar = document.getElementById("snackbar");
  107. snackbar.className = "show";
  108.  
  109. navigator.clipboard.writeText("https://idart.mot.com/browse/" + issueKey.childNodes[0].data);
  110.  
  111. setTimeout(function(){
  112. snackbar.className = snackbar.className.replace("show", "");
  113. }, 1500);
  114. };
  115.  
  116. newElement3.appendChild(linkE);
  117. issueKey.parentNode.parentNode.appendChild(newElement3);
  118.  
  119. const newElement4 = document.createElement("li");
  120. const idSummaryE = document.createElement("a");
  121. idSummaryE.className="aui-button aui-button-primary aui-style";
  122. idSummaryE.innerHTML="Copy as git title";
  123. idSummaryE.id="copy_id_summary";
  124. idSummaryE.onclick= (e) => {
  125. var snackbar = document.getElementById("snackbar");
  126. snackbar.className = "show";
  127.  
  128. navigator.clipboard.writeText(issueKey.childNodes[0].data + " " + issueName.childNodes[0].data);
  129.  
  130. setTimeout(function(){
  131. snackbar.className = snackbar.className.replace("show", "");
  132. }, 1500);
  133. };
  134.  
  135. newElement4.appendChild(idSummaryE);
  136. issueKey.parentNode.parentNode.appendChild(newElement4);
  137.  
  138. addStyles();
  139. }
  140.  
  141. function addWorkingButton() {
  142. let oriWorkingBtn = document.querySelector('#action_id_131');
  143. let autoWorkingBtn = document.querySelector('#auto_working');
  144. if(!oriWorkingBtn || autoWorkingBtn) return;
  145. oriWorkingBtn.style.display = 'none';
  146. autoWorkingBtn = createWorkFlowButton('auto_working', 'Auto Working');
  147. autoWorkingBtn.onclick = ()=>{
  148. oriWorkingBtn.click();
  149. detectElementBySelector("#customfield_10572", ()=>{
  150. let targetDate = document.querySelector('#customfield_10572');
  151. targetDate.value = getLastDayOfCurrentMonth();
  152. let workingSubmit = document.querySelector('#issue-workflow-transition-submit');
  153. workingSubmit.click();
  154. });
  155. }
  156. oriWorkingBtn.parentElement.prepend(autoWorkingBtn);
  157. }
  158.  
  159. function getLastDayOfCurrentMonth() {
  160. let date = new Date();
  161. let lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0);
  162. let [_,month,day,year] = lastDay.toDateString().split(' ');
  163. return day + '/'+month+'/'+year.substr(2,2);
  164. }
  165.  
  166. function addReadyButton() {
  167. let oriReadyBtn = document.getElementById('action_id_541');
  168. if(!oriReadyBtn) return;
  169. let parent = document.getElementById('opsbar-opsbar-transitions');
  170. if(!parent || document.getElementById('btn_ready')) return;
  171. let btnReady = createWorkFlowButton('btn_ready', 'Auto Ready');
  172. btnReady.onclick = ()=>{
  173. oriReadyBtn.click();
  174. // observer ready dialog
  175. detectElementBySelector("#customfield_10867", ()=>{
  176. let testsExecuted = document.querySelector('#customfield_10867');
  177. testsExecuted.textContent = "Test good";
  178. let dependentCRs = document.querySelector('#customfield_10127');
  179. dependentCRs.value = "NA";
  180. let readySubmit = document.querySelector('#issue-workflow-transition-submit');
  181. readySubmit.click();
  182. });
  183. }
  184.  
  185. parent.appendChild(btnReady);
  186. }
  187.  
  188. function createWorkFlowButton(id, text){
  189. let btn = document.createElement('a');
  190. btn.id = id;
  191. btn.className = "aui-button toolbar-trigger issueaction-workflow-transition";
  192. let span = document.createElement('span');
  193. span.className = "trigger-label";
  194. span.innerHTML = text;
  195. btn.appendChild(span);
  196. return btn;
  197. }
  198.  
  199. function detectElementBySelector(selector, action, delay) {
  200. let queryAction = ()=>{
  201. return document.querySelector(selector);
  202. }
  203.  
  204. if(queryAction()) {
  205. action();
  206. } else {
  207. setTimeout(()=>{
  208. detectElementBySelector(selector, action)
  209. }, delay ? delay : 200);
  210. }
  211.  
  212. }
  213.  
  214. function addStyles() {
  215.  
  216.  
  217. GM.addStyle(`
  218. #snackbar {
  219. visibility: hidden;
  220. min-width: 250px;
  221. margin-left: -125px;
  222. background-color: #333;
  223. color: #fff;
  224. text-align: center;
  225. border-radius: 2px;
  226. padding: 16px;
  227. position: fixed;
  228. z-index: 1;
  229. left: 50%;
  230. top: 50px;
  231. font-size: 17px;
  232. }
  233.  
  234. #snackbar.show {
  235. visibility: visible;
  236. -webkit-animation: fadein 0.5s, fadeout 0.5s 2.5s;
  237. animation: fadein 0.5s, fadeout 0.5s 2.5s;
  238. }
  239.  
  240. @-webkit-keyframes fadein {
  241. from {top: 0; opacity: 0;}
  242. to {top: 50px; opacity: 1;}
  243. }
  244.  
  245. @keyframes fadein {
  246. from {top: 0; opacity: 0;}
  247. to {top: 50px; opacity: 1;}
  248. }
  249.  
  250. @-webkit-keyframes fadeout {
  251. from {top: 50px; opacity: 1;}
  252. to {top: 0; opacity: 0;}
  253. }
  254.  
  255. @keyframes fadeout {
  256. from {top: 50px; opacity: 1;}
  257. to {top: 0; opacity: 0;}
  258. }
  259. `);
  260. }
  261.  
  262. const observeDOM = (function () {
  263. let MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  264. let eventListenerSupported = window.addEventListener;
  265.  
  266. return function (obj, onAddCallback, onRemoveCallback) {
  267. if (MutationObserver) {
  268. // define a new observer
  269. let mutationObserver = new MutationObserver(function (mutations, observer) {
  270. if (mutations[0].addedNodes.length && onAddCallback != undefined) {
  271. onAddCallback();
  272. }
  273. });
  274. // have the observer observe foo for changes in children
  275. mutationObserver.observe(obj, {
  276. childList: true
  277. });
  278. } else if (eventListenerSupported) {
  279. obj.addEventListener('DOMNodeInserted', onAddCallback, false);
  280. }
  281. };
  282. })();