C€ Portfolio Overview - Jira 5 Rapid Board - Dev

Customization for cards displayed on the Jira RapidBoard forked from "IS24 Portfolio Overview - Jira 5 Rapid Board" http://userscripts.org/scripts/show/172077

当前为 2014-06-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name C€ Portfolio Overview - Jira 5 Rapid Board - Dev
  3. // @namespace de.controlexpert.jira.rapidboard
  4. // @description Customization for cards displayed on the Jira RapidBoard forked from "IS24 Portfolio Overview - Jira 5 Rapid Board" http://userscripts.org/scripts/show/172077
  5. // @include https://jira.controlexpert.com/secure/RapidBoard.jspa?rapidView=*
  6. // @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
  7. // @version v2 _ce
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. /* ===============
  12. * Version History
  13. * ===============
  14. * v2 _ce 2014-03-28 - Start in BirdView with colourized cards
  15. * v1.01 _ce 2014-03-28 - Description of the card contain now key and summary in title attribute (tooltip)
  16. */
  17.  
  18. /* -------------
  19. * Configuration
  20. * -------------
  21. */
  22.  
  23. const BACKGROUND_COLOR = "rgba(22, 75, 106, 1)";
  24.  
  25. const MENU_BACKGROUND_COLOR = "rgba(26, 90, 127, 1)";
  26.  
  27. const MENU_HOVER_COLOR = "rgb(31,108,150)";
  28.  
  29. const ISSUE_HOVER_COLOR = "rgba(153, 173, 194, 1)";
  30.  
  31. const ISSUE_HEIGHT = 60;
  32.  
  33. const ISSUE_GRABBER_HEIGHT = 77;
  34.  
  35. const ISSUE_WIDTH = 88;
  36.  
  37. const ISSUE_FONT_SIZE = "8pt";
  38.  
  39. const SWIMLANE_HEADER_SIZE = "18pt";
  40.  
  41. const COLUMN_HEADER_SIZE = "18pt";
  42.  
  43. const FOREGROUND_COLOR = "white";
  44.  
  45. const YELLOW_MARKER_COLOR = "rgba(247,223,86,1)";
  46.  
  47. const RED_MARKER_COLOR = "rgba(181,75,50,1)";
  48.  
  49. /* Number of the development column */
  50. var columnId = 2;
  51.  
  52. /* tickets that are more days than this in development are marked red */
  53. const DAYS_RED = 180;
  54.  
  55. /* tickets that are more days than this in development are marked red */
  56. const DAYS_YELLOW = 28;
  57.  
  58. var inProgressBarMode = false;
  59. var inColorizeServiceLineMode = false;
  60.  
  61. /* The JQuery selector to a dom node to which custom buttons for zoom and other features are added */
  62. //var NODE_TO_ADD_CUSTOM_BUTTONS = "div#ghx-controls-work dl:last-child";
  63. var NODE_TO_ADD_CUSTOM_BUTTONS = "div#ghx-controls-work dl";
  64.  
  65. var ghxPool = $("#ghx-pool");
  66. var allGhxIssues = ghxPool.find("div.ghx-issue");
  67. var allFirstGhxIssues = ghxPool.find("div.ghx-issue:first-child");
  68.  
  69. /* Fix for Greasemonkey 1.0 bug, see http://www.greasespot.net/2012/08/greasemonkey-10-jquery-broken-with.html */
  70. $ = this.$ = this.jQuery = jQuery.noConflict(true);
  71.  
  72. function addCss(css) {
  73. var newCss = document.createElement("style");
  74. newCss.type = "text/css";
  75. newCss.innerHTML = css;
  76. $("head")[0].appendChild(newCss);
  77. }
  78.  
  79.  
  80. function overwriteStaticCss() {
  81. log("overwriteStaticCss...");
  82. /* =================
  83. * Overall Background
  84. * ==================*/
  85.  
  86. /* make backgrounds blue */
  87. addCss("#content { background: " + BACKGROUND_COLOR + " }");
  88. addCss("#ghx-pool { background: " + BACKGROUND_COLOR + " }");
  89. addCss("#ghx-column-headers { background: " + BACKGROUND_COLOR + " }");
  90. addCss("#ghx-column-header-group.ghx-fixed {background: none}");
  91.  
  92. /* =================
  93. * Header
  94. * ==================*/
  95. addCss(".aui-theme-default #header #logo a img { padding:0 }");
  96. addCss("#ghx-header { padding-left:0 }");
  97. addCss("#ghx-work { border:none }");
  98. addCss("#ghx-operations {padding:0}");
  99. addCss(".aui-theme-default #header .global { background: " + BACKGROUND_COLOR + " }");
  100. addCss(".aui-theme-default #content { margin:0; padding-top:0; padding-bottom:0; padding-left:16px }");
  101. addCss(".aui-theme-default #header .global .secondary>ul>li { background: " + BACKGROUND_COLOR + "}");
  102. addCss("h2#ghx-board-name { color: " + FOREGROUND_COLOR + ";font-weight:bold }");
  103.  
  104. // Hide some stuff that is not helping us here
  105. addCss(".alertHeader { display:none }");
  106. addCss("#ghx-modes { display:none }");
  107. addCss(".SpartezAC-print { display:none }");
  108. addCss(".ghx-compact-toggle { display:none }");
  109. addCss(".local { display:none }");
  110. addCss("#js-swimlane-header-stalker {display:none !important}");
  111. addCss(".ghx-feedback {display:none}");
  112.  
  113.  
  114. /* =================
  115. * Buttons
  116. * ==================*/
  117. addCss(".aui-theme-default a, .aui-theme-default a:link, .aui-theme-default a:visited { color:white;background: " + MENU_BACKGROUND_COLOR + ";border:none;margin:0;padding-top:5px;padding-bottom:5px;padding-left:5px;padding-right:5px }");
  118. addCss(".aui-theme-default a:hover { color:white;background: " + MENU_HOVER_COLOR + ";margin:2px;border:none;margin:0;text-decoration:none }");
  119. addCss(".aui-theme-default .aui-list .aui-list-item-link { color:white }");
  120. addCss(".ghx-controls-filters dd a.ghx-active {color:white;border:none;background: " + MENU_HOVER_COLOR + "}");
  121. addCss("#ghx-release {display:none}");
  122. addCss(".aui-theme-default #header #logo a { background: " + BACKGROUND_COLOR + "}");
  123.  
  124. /* ==========
  125. * Issue Cards
  126. * ===========*/
  127.  
  128. addCss(".ghx-issue:hover {background:" + ISSUE_HOVER_COLOR + "}");
  129.  
  130. /* add a shadow to cards */
  131. addCss(".ghx-issue { box-shadow: none; background:white}");
  132. /* make issues floating and round corners*/
  133. addCss(".ghx-issue { float: left; cursor: pointer; border-radius: 0 0 10px 0;margin:2px}");
  134. addCss(".ghx-grabber { background:white; display:none}");
  135. addCss(".ghx-issue .ghx-grabber:after { background:none;}");
  136. /* Hide epic symbol */
  137. addCss(".ghx-issue { padding-left: 12px; padding-top: 8px }");
  138. addCss(".ghx-issue-fields .ghx-type { display: none }");
  139.  
  140. addCss(".ghx-issue:first-child { border: none }");
  141. /* hide priority symbol */
  142. addCss(".ghx-priority { display:none }");
  143.  
  144. /* make text on the "cards" bigger so that more is visible */
  145. addCss(".ghx-summary { font-size: " + ISSUE_FONT_SIZE + " }");
  146. addCss(".ghx-issue-fields { padding-right: 0px !important; }");
  147. addCss(".ghx-issue-fields .ghx-key {font-size: " + ISSUE_FONT_SIZE + "; height: 13px; line-height: 0.98em; overflow:visible; vertical-align:baseline}");
  148. addCss(".ghx-issue-fields .ghx-key a { background: none;color: " + BACKGROUND_COLOR + "; word-wrap: break-word;display:block}");
  149. addCss(".ghx-issue-fields .ghx-summary span, .ghx-issue-subtask .ghx-issue-fields .ghx-summary span { height: 5em; line-height: 0.98em }");
  150.  
  151. /* Care for tasks */
  152. addCss(".ghx-issue-subtask .ghx-issue-fields .ghx-summary { font-size: " + ISSUE_FONT_SIZE + " }");
  153. addCss(".ghx-issue-subtask .ghx-issue-fields .ghx-key, .ghx-issue-subtask .ghx-issue-fields .ghx-summary {font-size: " + ISSUE_FONT_SIZE + "; height: 13px; line-height: 0.98em }");
  154. addCss(".ghx-issue-subtask .ghx-issue-fields .ghx-key, .ghx-issue-subtask .ghx-issue-fields .ghx-summary { color: " + BACKGROUND_COLOR + "; word-wrap: break-word;display:block}");
  155. addCss(".ghx-issue-subtask .ghx-issue-fields .ghx-key a { white-space: normal}");
  156.  
  157. /* make avatars invisible */
  158. addCss(".ghx-issue .ghx-avatar img { height: 35px; width: 35px; opacity: 0.5; display:none }");
  159.  
  160. /* remove lines through resolved issue keys */
  161. addCss(".ghx-issue.ghx-done .ghx-key a { text-decoration: none; }");
  162. addCss(".ghx-issue.ghx-done .ghx-key a:hover { text-decoration: underline; }");
  163.  
  164. /* hide days spent dots */
  165. addCss(".ghx-days { display:none}");
  166.  
  167. /* ====================
  168. * Columns and Swimlanes
  169. * =====================*/
  170. addCss("#ghx-pool {padding:0}");
  171.  
  172. /* make column and swim lane headers bigger and modify colors */
  173. addCss(".ghx-swimlane-header { font-size: " + SWIMLANE_HEADER_SIZE + "; background: " + BACKGROUND_COLOR + "; border:none;color: " + FOREGROUND_COLOR + "; font-size: " + COLUMN_HEADER_SIZE + ";");
  174. addCss(".ghx-column-headers h2 { font-weight:normal;margin:0;line-height:1.2}");
  175. addCss("#ghx-column-header-group {left: 28px !important}");
  176. // add a separator border
  177. addCss(".ghx-info:after {background-color: #fff;content: '';height: 1px;position: absolute;width: 95%;top: 25px;}");
  178. addCss(".ghx-swimlane-header:after {display: none}");
  179. addCss(".ghx-column-headers .ghx-column, .ghx-columns .ghx-column { background: " + BACKGROUND_COLOR + "; color: " + FOREGROUND_COLOR + " ;border:none; padding:0}");
  180. addCss(".ghx-column-headers .ghx-column h2 { color: " + FOREGROUND_COLOR + "; font-size: " + COLUMN_HEADER_SIZE + "; float: left }");
  181. addCss("li.ghx-column { padding-left: 15px;}");
  182.  
  183. /* number of issues */
  184. addCss(".ghx-column-headers .ghx-qty { color: " + FOREGROUND_COLOR + ";background:" + BACKGROUND_COLOR + ";border:none;font-weight:normal; margin-left:5px}");
  185. addCss(".ghx-columns {padding-left:13px}");
  186. addCss(".ghx-qty { color: " + FOREGROUND_COLOR + ";background:" + BACKGROUND_COLOR + ";border:none;position:relative;margin:0; font-size:" + COLUMN_HEADER_SIZE + ";font-weight:normal }");
  187. addCss(".ghx-description {color: " + FOREGROUND_COLOR + ";margin-right:5px}");
  188. log("overwriteStaticCss done");
  189. }
  190.  
  191. function markLateTickets() {
  192. log("markLateTickets...");
  193. if(inColorizeServiceLineMode) {
  194. log("markinColorizeServiceLineMode aborting...");
  195. return;
  196. }
  197. $(".ghx-grabber").css("display","none");
  198. $("li.ghx-column[data-column-id=" + columnId + "] div.ghx-issue").each(function () {
  199. var days = $().find(".ghx-days").attr("title");
  200. days = Number(days.substring(0, days.indexOf(" ")));
  201.  
  202. if (days > DAYS_RED) {
  203. $(this).find(".ghx-grabber").css("background", RED_MARKER_COLOR).css("display", "block");
  204. } else if (days > DAYS_YELLOW) {
  205. $(this).find(".ghx-grabber").css("background", YELLOW_MARKER_COLOR).css("display", "block");
  206. }
  207. });
  208. log("markLateTickets done");
  209. }
  210.  
  211.  
  212.  
  213. function adjustColumnSizes() {
  214. log("adjustColumnSizes...");
  215. $(".ghx-column-headers li:first-child").css("width", "25%");
  216. $(".ghx-column-headers li:last-child").css("width", "25%");
  217.  
  218. $(".ghx-columns li:first-child").each(function () {
  219. $(this).css("width", "25%");
  220. });
  221.  
  222. $(".ghx-columns li:last-child").each(function () {
  223. $(this).css("width", "25%");
  224. });
  225. log("adjustColumnSizes done");
  226. }
  227.  
  228.  
  229.  
  230. function enterProgressBarView() {
  231. log("entering progress bar view...")
  232. $(".ghx-summary").css("display", "none");
  233. $(".ghx-issue-fields .ghx-key").css("font-size", "6pt");
  234. $("div.ghx-issue").css("padding-left","0").css("padding-top","0").css("margin","1px").width(ISSUE_WIDTH / 2.8).height(ISSUE_HEIGHT / 5.0);
  235. $("div.ghx-issue:first-child").css("padding-left","0").css("padding-top","0").css("margin","1px").width(ISSUE_WIDTH / 2.8).height(ISSUE_HEIGHT / 5.0);
  236. $(".ghx-issue .ghx-grabber").height(ISSUE_GRABBER_HEIGHT / 3.3);
  237. $(".ghx-issue:first-child .ghx-grabber").height(ISSUE_GRABBER_HEIGHT / 3.4);
  238. $(".ghx-swimlane-header .ghx-heading").css("margin","0px");
  239. $(".ghx-column-headers .ghx-column h2").css("font-size", "8pt");
  240. $(".ghx-swimlane-header").css("font-size", "8pt");
  241. $(".ghx-qty").css("font-size", "8pt");
  242. $(".ghx-columns .ghx-column").css("padding-bottom", 0);
  243. $(".ghx-issue .ghx-avatar img").height("10px").width("10px");
  244. $(".ghx-description").css("display","none");
  245. log("progress bar view entered");
  246. }
  247.  
  248. function leaveProgressBarView() {
  249. log("leaving progress bar view");
  250. $(".ghx-summary").css("display", "inline");
  251. $(".ghx-issue-fields .ghx-key").css("font-size", "10pt");
  252. log("1");
  253. $("div.ghx-issue").css("padding-left","12px").css("padding-top","8px").css("margin","2px");
  254. $("div.ghx-issue").width(ISSUE_WIDTH);
  255. $("div.ghx-issue").height(ISSUE_HEIGHT);
  256. log("2");
  257. $("div.ghx-issue:first-child").css("padding-left","12px").css("padding-top","8px").css("margin","2px").width(ISSUE_WIDTH).height(ISSUE_HEIGHT);
  258. log("3");
  259. $(".ghx-issue .ghx-grabber").height(ISSUE_GRABBER_HEIGHT);
  260. $(".ghx-issue:first-child .ghx-grabber").height(ISSUE_GRABBER_HEIGHT);
  261. $(".ghx-swimlane-header .ghx-heading").css("margin-top","10px");
  262. log("4");
  263. $(".ghx-column-headers .ghx-column h2").css("font-size", SWIMLANE_HEADER_SIZE);
  264. $(".ghx-swimlane-header").css("font-size", COLUMN_HEADER_SIZE);
  265. $(".ghx-qty").css("font-size", COLUMN_HEADER_SIZE);
  266. $(".ghx-columns .ghx-column").css("padding-bottom", 32);
  267. $(".ghx-issue .ghx-avatar img").height("35px").width("35px");
  268. $(".ghx-description").css("display","inline-block");
  269. log("progress bar view left");
  270. }
  271.  
  272. function refreshProgressBarView() {
  273. log("refreshing progress bar view...");
  274. if (inProgressBarMode) {
  275. enterProgressBarView();
  276. } else {
  277. leaveProgressBarView();
  278. }
  279. log("progress bar view refreshed");
  280. }
  281.  
  282. function enterColorizeAgeMode() {
  283. log("enterColorizeAgeMode...");
  284. markLateTickets();
  285. log("enterColorizeAgeMode done");
  286. }
  287.  
  288. function enterColorizeServiceLineMode() {
  289. log("enterColorizeServiceLineMode...");
  290. $(".ghx-grabber").css("display","block");
  291. GH.EpicView.updateEpicColor
  292. log("enterColorizeServiceLineMode done");
  293. }
  294.  
  295. function toggleIssueColorization() {
  296. if (inColorizeServiceLineMode) {
  297. inColorizeServiceLineMode = !inColorizeServiceLineMode;
  298. enterColorizeAgeMode();
  299. } else {
  300. inColorizeServiceLineMode = !inColorizeServiceLineMode;
  301. enterColorizeServiceLineMode();
  302. }
  303. if ("Colorize ServiceLines" == $("#colorText").text()) {
  304. $("#colorText").text("Colorize age");
  305. } else {
  306. $("#colorText").text("Colorize ServiceLines");
  307. }
  308. }
  309.  
  310. function toggleProgressBarView() {
  311. if (inProgressBarMode) {
  312. leaveProgressBarView();
  313. } else {
  314. enterProgressBarView();
  315. }
  316. inProgressBarMode = !inProgressBarMode;
  317. if ("Zoom out" == $("#zoomText").text()) {
  318. $("#zoomText").text("Zoom in");
  319. } else {
  320. $("#zoomText").text("Zoom out");
  321. }
  322. }
  323.  
  324.  
  325.  
  326. function convertFilterButtonsIntoPullDown() {
  327. log("convertFilterButtonsIntoPullDown...");
  328. // Wait for the list of quick filters to be available
  329. $("div#ghx-controls-work dl").onAvailable(function() {
  330. $("div#ghx-controls-work dl:first-child > dt").css("display","none");
  331. // Add a new list to the above div and put one item inside which will be the button to hover the pull down menu
  332. $("<dl><dt id='slFilterButton' style='font-weight:normal;line-height:1.4;background:" + MENU_BACKGROUND_COLOR + ";background-position: 8% 50%;background-repeat: no-repeat;background-image: url(\"/rest/api/1.0/dropdowns?color=%23ffffff&bgcolor=%23114070\");padding-top:4px;padding-left:24px;padding-right:5px;padding-bottom:5px;color:white;font-size:10pt;cursor: pointer'>Filter by...</dt></dl>").appendTo($("div#ghx-controls-work"));
  333. // Now move all ServiceLine, Department or other orga filters into the newly created list
  334. $("dd:not(:contains('SL '))dd:not(:contains('DEP '))dd:not(:contains('Supporting Teams'))dd:not(:contains('External'))dd:not(:contains('PMI'))dd:not(:contains('Project Management'))").detach().appendTo($("div#ghx-controls-work dl:last-child"));
  335. // Reformat the original list that now contains all ServiceLine filters, etc. so that it is hidden and lies under the "Filter by..." button.
  336. $("div#ghx-controls-work dl:first-child").css('list-style', 'none').css('position', 'absolute').css('left', '15px').css('top', '25px').css('float', 'left').css('display', 'none').css('z-index', '99').css('width', '180px').css('margin', '0').css('padding', '0').css('background', MENU_BACKGROUND_COLOR);
  337. $("div#ghx-controls-work dl:first-child > dd").css('width', '180px').css('margin', '0').css('padding', '0').css('border', 'none').css('clear', 'both');
  338. // Reformat the new list with the moved itemss
  339. $("div#ghx-controls-work dl:last-child > dd").css("font-size","10pt").css("padding-top","4px").css("padding-right","5px").css("padding-bottom","5px").css("background",MENU_BACKGROUND_COLOR).css("color","white");
  340. // Slide down the original list under the button and make it visible
  341. $("#slFilterButton").on("mouseenter", function () {
  342. $(this).css('background', MENU_HOVER_COLOR).css('background-position', '8% 50%').css('background-repeat', 'no-repeat').css('background-image', 'url(\"/rest/api/1.0/dropdowns?color=%23ffffff&bgcolor=%23114070\")');
  343. $("div#ghx-controls-work dl:first-child").slideDown('fast');
  344. })
  345.  
  346. // Slide up again and hide the list
  347. $("div#ghx-controls-work dl:first-child").hover(function () {
  348. }, function () {
  349. $("#slFilterButton").css('background', MENU_BACKGROUND_COLOR).css('background-position', '8% 50%').css('background-repeat', 'no-repeat').css('background-image', 'url(\"/rest/api/1.0/dropdowns?color=%23ffffff&bgcolor=%23114070\")');
  350. $("div#ghx-controls-work dl:first-child").slideUp('slow');
  351. })
  352. });
  353. log("convertFilterButtonsIntoPullDown done");
  354. }
  355.  
  356. function addColorizeButtonToButtonBar() {
  357. $(NODE_TO_ADD_CUSTOM_BUTTONS).onAvailable(function () {
  358. $("<dd id='colorizeButton' style='padding-top:6px;background:" + MENU_BACKGROUND_COLOR + ";color:white;font-size:10pt;cursor: pointer;padding-left:5px;padding-top:4px;padding-bottom:5px;padding-right:5px'><span id='colorText'>Colorize ServiceLines</span></dd>").appendTo(NODE_TO_ADD_CUSTOM_BUTTONS);
  359.  
  360. $("#colorizeButton").on("click",function () {
  361. toggleIssueColorization()
  362. }).on("mouseenter",function () {
  363. $(this).css('background', MENU_HOVER_COLOR);
  364. }).on("mouseleave", function () {
  365. $(this).css('background', MENU_BACKGROUND_COLOR);
  366. })
  367. }
  368. )
  369. }
  370.  
  371. function addZoomButtonToButtonBar() {
  372. $(NODE_TO_ADD_CUSTOM_BUTTONS).onAvailable(function () {
  373. $("<dd id='zoomButton' style='padding-top:6px;background:" + MENU_BACKGROUND_COLOR + ";color:white;font-size:10pt;cursor: pointer;padding-left:5px;padding-top:4px;padding-bottom:5px;padding-right:5px'><span id='zoomText'>Zoom out</span></dd>").appendTo(NODE_TO_ADD_CUSTOM_BUTTONS);
  374.  
  375. $("#zoomButton").on("click",function () {
  376. toggleProgressBarView()
  377. }).on("mouseenter",function () {
  378. $(this).css('background', MENU_HOVER_COLOR);
  379. }).on("mouseleave", function () {
  380. $(this).css('background', MENU_BACKGROUND_COLOR);
  381. })
  382. }
  383. )
  384. }
  385.  
  386. function addShowAssigneeButtonToButtonBar() {
  387. $(NODE_TO_ADD_CUSTOM_BUTTONS).onAvailable(function () {
  388. $("<dd id='showAsigneeButton' style='padding-top:6px;background:" + MENU_BACKGROUND_COLOR + ";color:white;font-size:10pt;cursor: pointer;padding-left:5px;padding-top:4px;padding-bottom:5px;padding-right:5px'><span id='showAsigneesText'>Show asignees</span></dd>").appendTo(NODE_TO_ADD_CUSTOM_BUTTONS);
  389.  
  390. $("#showAsigneeButton").on("click",function () {
  391. showAsignees();
  392. }).on("mouseenter",function () {
  393. $(this).css('background', MENU_HOVER_COLOR);
  394. }).on("mouseleave", function () {
  395. $(this).css('background', MENU_BACKGROUND_COLOR);
  396. })
  397. }
  398. )
  399. }
  400.  
  401. function showAsignees() {
  402. if($(".ghx-issue .ghx-avatar img").css("display") == "block") {
  403. $("#showAsigneesText").text("Show asignees");
  404. $(".ghx-issue .ghx-avatar img").css("display","none");
  405. } else {
  406. $("#showAsigneesText").text("Hide asignees");
  407. $(".ghx-issue .ghx-avatar img").css("display","block");
  408. }
  409. }
  410.  
  411.  
  412. function identifyInProgressColumnId() {
  413. $("#ghx-column-headers li.ghx-column h2").onAvailable(function() {
  414. $("#ghx-column-headers li.ghx-column h2").each(function() {
  415. var columnName = $(this).text().trim();
  416. if (columnName == "In Progress") {
  417. columnId = $(this).parent().attr("data-id");
  418. }
  419. })
  420. });
  421. }
  422.  
  423. function joinTitlesOfKeyAndSummery(){
  424. log("joinTitlesOfKeyAndSummery...");
  425. var res = $(".ghx-issue-fields").not(" .ghx-key-link [title*='\n']").each(function() {
  426. var keyEl = $(this).children(".ghx-key").children(".ghx-key-link").not("[title*='\n']");
  427. if (keyEl.length>0){
  428. var summaryEl = $(this).children(".ghx-summary");
  429. var newTitleText = keyEl.attr("title").trim() + "\n" + summaryEl.attr("title").trim()
  430. var newline = "&#xD;";
  431. keyEl.attr("title", newTitleText);
  432. summaryEl.attr("title", newTitleText);
  433. }
  434. });
  435. log(res.length + " elements affected");
  436. log("joinTitlesOfKeyAndSummery done");
  437. }
  438.  
  439. function beautifyBoard() {
  440. log("beautifyBoard...");
  441. overwriteStaticCss();
  442. overwriteCssAfterRefresh();
  443. addZoomButtonToButtonBar();
  444. addShowAssigneeButtonToButtonBar();
  445. addColorizeButtonToButtonBar();
  446. convertFilterButtonsIntoPullDown();
  447. log("beautifyBoard done");
  448. }
  449.  
  450. function overwriteCssAfterRefresh() {
  451. log("overwriteCssAfterRefresh...");
  452. $(".ghx-issue").onAvailable(function () {
  453. log("available");
  454. identifyInProgressColumnId();
  455. adjustColumnSizes();
  456. markLateTickets();
  457. refreshProgressBarView();
  458. joinTitlesOfKeyAndSummery();
  459. });
  460. $("#zoomText").onAvailable(function(){
  461. //$("#zoomText").click();
  462. log("zoomed: "+$("#zoomText"));
  463. });
  464. log("overwriteCssAfterRefresh done");
  465. }
  466.  
  467.  
  468. var DOMTimeout = null;
  469.  
  470.  
  471. $(document).ready(function () {
  472. console.log(new Date().toLocaleTimeString() + " document is ready");
  473. beautifyBoard();
  474. $("#ghx-work").on("DOMNodeInserted", function (event) {
  475. if('A' != event.target.nodeName) {
  476. return;
  477. }
  478. if(DOMTimeout) {
  479. clearTimeout(DOMTimeout);
  480. }
  481. //DOMTimeout = setTimeout(function() {
  482. //
  483. // overwriteCssAfterRefresh();
  484. //
  485. //}, 150);
  486. });
  487. });
  488.  
  489. function log(text) {
  490. console.log(new Date().toLocaleTimeString() + " " + text);
  491. }
  492.  
  493. /* Adds functionality to jQuery to wait for an element to be available;
  494. * this is useful for the rapid board because most of the page is loaded
  495. * after document ready by Ajax */
  496. $.fn.onAvailable = function (fn) {
  497. var sel = this.selector;
  498. var timer;
  499. if (this.length > 0) {
  500. fn.call(this);
  501. }
  502. else {
  503. timer = setInterval(function () {
  504. if ($(sel).length > 0) {
  505. fn.call($(sel));
  506. clearInterval(timer);
  507. }
  508. }, 1000);
  509. }
  510. };