PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/webroot/js/main.js

https://github.com/strategist922/tracboard
JavaScript | 706 lines | 550 code | 71 blank | 85 comment | 87 complexity | d9442f4f0e36eb437e0b40787120fd19 MD5 | raw file
Possible License(s): Apache-2.0
  1. /**
  2. * Copyright 2011 Clearspring Technologies
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. function refreshAllColumns(onTicketEdited, onTicketAdded) {
  17. $(".column").each(function() {
  18. refreshColumn($(this).attr("id"), onTicketEdited, onTicketAdded);
  19. });
  20. }
  21. function refreshColumn(columnId, onTicketEdited, onTicketAdded) {
  22. var col = $("#" + columnId);
  23. // Set the UI for mid-loading...
  24. setAsLoading("#" + columnId + " .column-body");
  25. col.find(".column-count").fadeOut();
  26. //col.find(".column-controls").fadeOut();
  27. // Set up the ajax call...
  28. var columnUrl = "get.php";
  29. if (columnId == "backlog") {
  30. columnUrl += "?a=backlogColumn"
  31. } else if (columnId == "not-started" || columnId == "in-dev" || columnId == "in-test" || columnId == "done") {
  32. columnUrl += "?a=phaseTicketColumn"
  33. columnUrl += "&phase=" + columnId;
  34. columnUrl += "&milestone=" + filters.milestone;
  35. } else {
  36. columnUrl += "?a=milestoneColumn";
  37. filters.milestone = columnId;
  38. columnUrl += "&milestone=" + filters.milestone;
  39. }
  40. columnUrl += "&pipeline=" + filters.pipeline;
  41. columnUrl += "&notypes=";
  42. var numExcluded = filters.excludedTypes.length;
  43. if (numExcluded > 0) {
  44. var i = 0;
  45. for (i = 0; i < numExcluded; i++) {
  46. columnUrl += filters.excludedTypes[i];
  47. if (i < (numExcluded-1))
  48. columnUrl += ",";
  49. }
  50. }
  51. columnUrl += "&grouping=" + filters.grouping;
  52. columnUrl += "&coloring=" + filters.coloring;
  53. columnUrl += "&highlight=" + filters.highlightCond;
  54. columnUrl += "&display=" + filters.displayType;
  55. var index = getColumnIndex(columnId);
  56. columnUrl += "&expanded=" + filters.expanded[index];
  57. // Make the call and respond
  58. $.ajax({
  59. url: columnUrl,
  60. context: document.body,
  61. dataType: "html",
  62. success: function(data) {
  63. var selector = "#" + columnId;
  64. $(selector).replaceWith(data);
  65. dbglog("Column refreshed, hooking up events and doing stuff...")
  66. hookupColumnEvents(columnId, onTicketEdited, onTicketAdded);
  67. recolorTickets(true);
  68. fixColumnHeights();
  69. },
  70. error: function(xhr, status) {
  71. alert("Unable to load tickets: " + status);
  72. },
  73. complete: function() {
  74. }
  75. });
  76. }
  77. function setAsLoading(selector) {
  78. var html = '<div style="text-align: center; padding: 20px;"><img src="images/ajax-loader.gif"/></div>';
  79. $(selector).html(html);
  80. }
  81. // Callback takes one arg, the ticket id
  82. function addTicketDlg(pipeline, milestone, status, type, priority, owner, component, scope, blocking, blockedBy, callback) {
  83. dbglog("Popping new ticket dialog: In " + pipeline + " / " + milestone);
  84. // Set up the dialog
  85. $("#add-ticket-dlg #ticket-type").val(type);
  86. $("#add-ticket-dlg #ticket-priority").val(priority);
  87. $("#add-ticket-dlg #ticket-owner").val(owner);
  88. $("#add-ticket-dlg #ticket-component").val(component);
  89. $("#add-ticket-dlg #ticket-scope").val(scope);
  90. if (blocking != "") {
  91. $("#add-ticket-dlg #ticket-blocking").val(blocking);
  92. } else {
  93. $("#add-ticket-dlg #ticket-blocking").val("");
  94. }
  95. if (blockedBy != "") {
  96. $("#add-ticket-dlg #ticket-blocked-by").val(blockedBy);
  97. } else {
  98. $("#add-ticket-dlg #ticket-blocked-by").val("");
  99. }
  100. $("#add-ticket-dlg #ticket-summary").val("");
  101. $("#add-ticket-dlg #ticket-cancel").unbind();
  102. $("#add-ticket-dlg #ticket-cancel").click(function() {
  103. $("#add-ticket-dlg").toggle();
  104. });
  105. $("#add-ticket-dlg #ticket-create-in-trac").unbind();
  106. $("#add-ticket-dlg #ticket-create-in-trac").click(function() {
  107. var url = "http://" + TRAC_SERVER + "/newticket?";
  108. url += "&pipeline=" + pipeline;
  109. url += "&milestone=" + milestone;
  110. url += "&status=" + status;
  111. url += "&type=" + encodeURIComponent($("#add-ticket-dlg #ticket-type").val());
  112. url += "&priority=" + encodeURIComponent($("#add-ticket-dlg #ticket-priority").val());
  113. url += "&owner=" + encodeURIComponent($("#add-ticket-dlg #ticket-owner").val());
  114. url += "&component=" + encodeURIComponent($("#add-ticket-dlg #ticket-component").val());
  115. url += "&scope=" + encodeURIComponent($("#add-ticket-dlg #ticket-scope").val());
  116. url += "&blocking=" + encodeURIComponent($("#add-ticket-dlg #ticket-blocking").val());
  117. url += "&blockedby=" + encodeURIComponent($("#add-ticket-dlg #ticket-blocked-by").val());
  118. url += "&summary=" + encodeURIComponent($("#add-ticket-dlg #ticket-summary").val());
  119. $("#add-ticket-dlg").toggle();
  120. window.open(url, "_blank");
  121. return false;
  122. });
  123. $("#add-ticket-dlg #ticket-create").unbind();
  124. $("#add-ticket-dlg #ticket-create").click(function() {
  125. var newTicketCall = "get.php?a=newTicket";
  126. newTicketCall += "&pipeline=" + pipeline;
  127. newTicketCall += "&milestone=" + milestone;
  128. newTicketCall += "&status=" + status;
  129. newTicketCall += "&type=" + encodeURIComponent($("#add-ticket-dlg #ticket-type").val());
  130. newTicketCall += "&priority=" + encodeURIComponent($("#add-ticket-dlg #ticket-priority").val());
  131. newTicketCall += "&owner=" + encodeURIComponent($("#add-ticket-dlg #ticket-owner").val());
  132. newTicketCall += "&component=" + encodeURIComponent($("#add-ticket-dlg #ticket-component").val());
  133. newTicketCall += "&scope=" + encodeURIComponent($("#add-ticket-dlg #ticket-scope").val());
  134. newTicketCall += "&blocking=" + encodeURIComponent($("#add-ticket-dlg #ticket-blocking").val());
  135. newTicketCall += "&blockedby=" + encodeURIComponent($("#add-ticket-dlg #ticket-blocked-by").val());
  136. newTicketCall += "&summary=" + encodeURIComponent($("#add-ticket-dlg #ticket-summary").val());
  137. $("#add-ticket-dlg").fadeOut();
  138. $(".dialog-wrapper").fadeOut();
  139. dbglog("Ticket creation URL: " + newTicketCall);
  140. $.ajax({
  141. dataType: "json",
  142. url: newTicketCall,
  143. success: function(data) {
  144. callback(data.ticketId);
  145. },
  146. error: function(xrd, status) {
  147. alert("ERROR: " + status);
  148. },
  149. complete: function(data) {
  150. }
  151. });
  152. });
  153. // Ok show it
  154. $("#add-ticket-dlg").toggle();
  155. $("#add-ticket-dlg").center();
  156. $("#add-ticket-dlg #ticket-summary").focus();
  157. }
  158. // Callback takes one arg, the ticket id
  159. function editTicketDlg(milestone, status, id, type, priority, owner, component, scope, blocking, blockedBy, summary, callback) {
  160. dbglog("Popping edit ticket dialog for ticket " + id + " in milestone " + milestone);
  161. // Set up the dialog fields
  162. $("#edit-ticket-dlg #ticket-type").val(type);
  163. $("#edit-ticket-dlg #ticket-priority").val(priority);
  164. $("#edit-ticket-dlg #ticket-owner").val(owner);
  165. $("#edit-ticket-dlg #ticket-component").val(component);
  166. $("#edit-ticket-dlg #ticket-scope").val(scope);
  167. if (blocking != "") {
  168. $("#edit-ticket-dlg #ticket-blocking").val(blocking);
  169. } else {
  170. $("#edit-ticket-dlg #ticket-blocking").val("");
  171. }
  172. if (blockedBy != "") {
  173. $("#edit-ticket-dlg #ticket-blocked-by").val(blockedBy);
  174. } else {
  175. $("#edit-ticket-dlg #ticket-blocked-by").val("");
  176. }
  177. $("#edit-ticket-dlg #ticket-summary").val(summary);
  178. // Enable quick actions appropriately
  179. if (milestone != "backlog" && status != "closed") {
  180. $("#edit-ticket-dlg #backlog-ticket-span").show();
  181. } else {
  182. $("#edit-ticket-dlg #backlog-ticket-span").hide();
  183. }
  184. if (status == "closed") {
  185. $("#edit-ticket-dlg #complete-ticket-span").hide();
  186. $("#edit-ticket-dlg #reopen-ticket-span").show();
  187. } else {
  188. $("#edit-ticket-dlg #complete-ticket-span").show();
  189. $("#edit-ticket-dlg #reopen-ticket-span").hide();
  190. }
  191. // Hook up events
  192. $("#edit-ticket-dlg #complete-ticket").unbind();
  193. $("#edit-ticket-dlg #complete-ticket").click(function() {
  194. $("#edit-ticket-dlg").toggle();
  195. alert("TODO I'm working on it...");
  196. });
  197. $("#edit-ticket-dlg #reopen-ticket").unbind();
  198. $("#edit-ticket-dlg #reopen-ticket").click(function() {
  199. $("#edit-ticket-dlg").toggle();
  200. alert("TODO I'm working on it...");
  201. });
  202. $("#edit-ticket-dlg #backlog-ticket").unbind();
  203. $("#edit-ticket-dlg #backlog-ticket").click(function() {
  204. $("#edit-ticket-dlg").toggle();
  205. alert("TODO I'm working on it...");
  206. });
  207. $("#edit-ticket-dlg #ticket-cancel").unbind();
  208. $("#edit-ticket-dlg #ticket-cancel").click(function() {
  209. $("#edit-ticket-dlg").toggle();
  210. });
  211. $("#edit-ticket-dlg #ticket-edit").unbind();
  212. $("#edit-ticket-dlg #ticket-edit").click(function() {
  213. var call = "get.php?a=editTicket";
  214. call += "&id=" + id;
  215. call += "&status=" + status;
  216. call += "&type=" + encodeURIComponent($("#edit-ticket-dlg #ticket-type").val());
  217. call += "&priority=" + encodeURIComponent($("#edit-ticket-dlg #ticket-priority").val());
  218. call += "&owner=" + encodeURIComponent($("#edit-ticket-dlg #ticket-owner").val());
  219. call += "&component=" + encodeURIComponent($("#edit-ticket-dlg #ticket-component").val());
  220. call += "&scope=" + encodeURIComponent($("#edit-ticket-dlg #ticket-scope").val());
  221. call += "&blocking=" + encodeURIComponent($("#edit-ticket-dlg #ticket-blocking").val());
  222. call += "&blockedby=" + encodeURIComponent($("#edit-ticket-dlg #ticket-blocked-by").val());
  223. call += "&summary=" + encodeURIComponent($("#edit-ticket-dlg #ticket-summary").val());
  224. $("#edit-ticket-dlg").fadeOut();
  225. $(".dialog-wrapper").fadeOut();
  226. $("#edit-ticket-dlg #ticket-summary").val("");
  227. dbglog("Ticket edit URL: " + call);
  228. setAsLoading('.ticket[ticket-id="' + id + '"] .body');
  229. $.ajax({
  230. dataType: "json",
  231. url: call,
  232. success: function(data) {
  233. callback(data.ticketId);
  234. },
  235. error: function(xrd, status) {
  236. alert("ERROR: " + status);
  237. },
  238. complete: function(data) {
  239. }
  240. });
  241. });
  242. // Ok show it
  243. $("#edit-ticket-dlg").toggle();
  244. $("#edit-ticket-dlg").center();
  245. $("#edit-ticket-dlg #ticket-summary").focus();
  246. }
  247. /**
  248. * Doesn't actually edit any ticket, just updates the display of the column to include this new ticket in the right place (group, color).
  249. */
  250. function addTicketToColumn(ticketId, columnId, onTicketEdited, onTicketAdded) {
  251. var ticketCardUrl = "get.php?a=ticketCard&id=" + ticketId;
  252. ticketCardUrl += "&grouping=" + filters.grouping;
  253. ticketCardUrl += "&coloring=" + filters.coloring;
  254. ticketCardUrl += "&highlight=" + filters.highlightCond;
  255. ticketCardUrl += "&display=" + filters.displayType;
  256. $.ajax({
  257. url: ticketCardUrl,
  258. dataType: "html",
  259. success: function(data) {
  260. // Ok we have the HTML for the new tiucket
  261. var ticketHtml = data;
  262. // If we're not grouping, just stick it at the beginning of the column
  263. if (filters.grouping == "none") {
  264. $("#" + columnId + " .column-body").prepend($(ticketHtml).hide().fadeIn(1000));
  265. } else {
  266. // Tickets are grouped, so we need to put it in the right group...find that
  267. var newTicketGroupByFieldVal = $(ticketHtml).attr("groupby-field-val");
  268. var colSelector = "#" + columnId;
  269. var groupSelector = ".group[groupby-field-val='" + newTicketGroupByFieldVal + "']";
  270. if ($(colSelector + " " + groupSelector).length > 0) {
  271. // Found the group, add this ticket to it
  272. $(colSelector + " " + groupSelector + " .groupName").after(ticketHtml);
  273. } else {
  274. // This ticket would be the first in this group, so create that group and put the ticket into it
  275. //alert("Creating new group...");
  276. groupHtml = '<div groupby-field-val="' + newTicketGroupByFieldVal + '" class="group">';
  277. groupHtml += '<div class="groupName">' + newTicketGroupByFieldVal + '&nbsp;(1)</div>';
  278. groupHtml += ticketHtml;
  279. groupHtml += '</div>';
  280. groupHtml += '<div class="clearer"></div>';
  281. $("#" + columnId + " .column-body").prepend(groupHtml);
  282. }
  283. }
  284. // If we're coloring, recolor everything
  285. if (filters.coloring != "uniform") {
  286. recolorTickets(true);
  287. }
  288. // Increment the count of this column
  289. incrementCountDisplay("#" + columnId + " .column-header .column-count");
  290. // Make sure all column events are still working
  291. hookupColumnEvents(columnId, onTicketEdited, onTicketAdded);
  292. // reset style so positioning looks good
  293. $("#"+columnId).find(".ticket").attr("style","position:relative");
  294. }
  295. });
  296. }
  297. function onShowHideExclusiveToggle(val, showExclusively) {
  298. var thisTicketSelector = '.ticket[ticket-' + filters.coloring + '="' + val + '"]';
  299. var otherTicketSelector = '.ticket[ticket-' + filters.coloring + '!="' + val + '"]';
  300. var allTicketSelector = '.ticket';
  301. // Show/hide tickets
  302. if (showExclusively == "true") {
  303. $(thisTicketSelector).show();
  304. $(otherTicketSelector).hide();
  305. } else {
  306. $('.ticket').show();
  307. }
  308. }
  309. /**
  310. * Handles a click on an individual color-key item's show/hide toggle. We show or hide all tickets with the specified value for
  311. * the current coloring filter.
  312. *
  313. * @param val The value of the coloring attribute that is beign toggled
  314. * @param show Whether we are showing, or hiding, the tickets
  315. */
  316. function onShowHideToggle(val, show) {
  317. // All tickets that have this value set get enabled or disabled
  318. var ticketSelector = '.ticket[ticket-' + filters.coloring + '="' + val + '"]';
  319. dbglog("Adjusting items matching '" + ticketSelector + "'");
  320. $(ticketSelector).each(function () {
  321. if (show == "true") $(this).show();
  322. else $(this).hide();
  323. });
  324. }
  325. // TODO replace this with the coloring.js api
  326. function recolorTickets(reset) {
  327. if (reset) resetColoring();
  328. if (filters.coloring != "uniform") {
  329. var selector = ".column .ticket";
  330. colorTickets(selector, "ticket-" + filters.coloring, false);
  331. } else {
  332. // No coloring
  333. }
  334. updateColorKey("colorkey-container", {onItemToggleFuncName: "onShowHideToggle", onItemExclusiveToggleFuncName: "onShowHideExclusiveToggle"});
  335. }
  336. function incrementCountDisplay(selector) {
  337. var countObj = $(selector);
  338. var text = countObj.text();
  339. if (text) {
  340. var num = text.substr(1, text.length-2);
  341. num++;
  342. var newText = "(" + num + ")";
  343. countObj.text(newText);
  344. }
  345. }
  346. function refreshTicketCard(ticketId, filters, onEditCallback) {
  347. var ticketCardUrl = "get.php?a=ticketCard&id=" + ticketId;
  348. ticketCardUrl += "&grouping=" + filters.grouping;
  349. ticketCardUrl += "&coloring=" + filters.coloring;
  350. ticketCardUrl += "&highlight=" + filters.highlightCond;
  351. ticketCardUrl += "&display=" + filters.displayType;
  352. $.ajax({
  353. url: ticketCardUrl,
  354. dataType: "html",
  355. success: function(data) {
  356. // Ok we have the HTML for the new tiucket
  357. var ticketHtml = data;
  358. // Replace the existing ticket's HTML with the new HTML
  359. $(".ticket[ticket-id=" + ticketId + "]").replaceWith(ticketHtml);
  360. // If we're coloring, recolor everything
  361. if (filters.coloring != "uniform") {
  362. var selector = ".ticket";
  363. colorTickets(selector, "ticket-" + filters.coloring, true);
  364. }
  365. // Make sure all column events are still working
  366. hookupCardEvents('.ticket[ticket-id=' + ticketId + ']', onEditCallback);
  367. }
  368. });
  369. }
  370. function onViewUrl(url) {
  371. $.fancybox({
  372. 'titleShow': false,
  373. 'autoScale': false,
  374. 'transitionIn': 'fade',
  375. 'transitionOut': 'none',
  376. 'type': 'iframe',
  377. 'href': url,
  378. 'width': 1100,
  379. 'height': 600
  380. });
  381. }
  382. function hookupCardEvents(cardSelector, onEditCallback) {
  383. // Iterate all selected tickets
  384. $(cardSelector).each(function() {
  385. var ticket = $(this);
  386. var ticketId = ticket.attr("ticket-id");
  387. if (ticket.attr("ticket-evented") == "true") {
  388. dbglog("Ticket " + ticketId + " already has events attached.");
  389. return;
  390. }
  391. ticket.attr("ticket-evented", "true");
  392. dbglog("Hooking events up to ticket " + ticketId);
  393. // Set up trac-view click behavior
  394. var trigger = $(this).find('.viewtrigger')
  395. trigger.unbind();
  396. trigger.click(function() {
  397. window.open(trigger.attr("href"), '_blank');
  398. return false;
  399. });
  400. // Setup edit trigger behavior -- pops up the edit dialog and configures it
  401. var editTrigger = $(this).find(".edittrigger");
  402. dbglog("Hooking up edit trigger (" + editTrigger + ") on ticket " + ticketId);
  403. editTrigger.unbind();
  404. editTrigger.click(function() {
  405. dbglog("Popping edit dialog for ticket " + ticketId + "...");
  406. // Get info on this ticket
  407. var status = ticket.attr("ticket-status");
  408. var id = ticket.attr("ticket-id");
  409. var type = ticket.attr("ticket-type");
  410. var priority = ticket.attr("ticket-priority");
  411. var owner = ticket.attr("ticket-owner");
  412. var component = ticket.attr("ticket-component");
  413. var scope = ticket.attr("ticket-scope");
  414. var blocking = ticket.attr("ticket-blocking");
  415. var blockedBy = ticket.attr("ticket-blocked-by");
  416. var milestone = ticket.attr("ticket-milestone");
  417. var summary = ticket.find(".body").text();
  418. // Show the edit dlg
  419. editTicketDlg(milestone, status, id, type, priority, owner, component, scope, blocking, blockedBy, summary, onEditCallback);
  420. return false;
  421. });
  422. // Setup on-hover preview popups for all tickets
  423. var previewTrigger = $(this).find(".previewtrigger");
  424. var previewHref = 'get.php?a=ticketPreview&id=' + ticketId;
  425. dbglog("Attaching qtip to ticket " + ticketId);
  426. previewTrigger.qtip({
  427. content: {
  428. url: previewHref
  429. },
  430. position: {
  431. adjust: {
  432. screen: true
  433. }
  434. },
  435. style: {
  436. padding: 0,
  437. padding: {
  438. min: 350,
  439. max: 350
  440. }
  441. },
  442. show: {
  443. effect: {
  444. type: "fade"
  445. },
  446. solo: true,
  447. when: {
  448. event: 'mouseover'
  449. },
  450. delay: 250
  451. },
  452. hide: 'mouseout'
  453. });
  454. // Make dragging work
  455. if (ticket.hasClass("draggable")) {
  456. ticket.find(".header").css("cursor", "move");
  457. ticket.draggable({
  458. helper: 'clone',
  459. snap: '.column',
  460. snapMode: 'inner',
  461. opacity: .7,
  462. scrollSpeed: 50,
  463. revert: 'invalid',
  464. handle: '.header',
  465. start: function(evt, ui) {
  466. ticket.addClass("ticket-middrag");
  467. },
  468. drag: function(evt, ui) {
  469. $(".ui-draggable-dragging").width(ticket.width());
  470. },
  471. stop: function(evt, ui) {
  472. ticket.removeClass("ticket-middrag");
  473. }
  474. });
  475. }
  476. });
  477. }
  478. /**
  479. * Sets up the column after its been drawn, hooks up all events and such. onEditCallback takes on arg, the ticket id.
  480. */
  481. function hookupColumnEvents(columnId, onEditCallback, onAddCallback) {
  482. dbglog("Hooking up events on column " + columnId + "; onEdit: " + onEditCallback + ", onAdd: " + onAddCallback);
  483. var column = $(".column");
  484. // Hook up events on all cards in this column
  485. hookupCardEvents('#' + columnId + " .ticket", onEditCallback);
  486. // Hook up add-ticket control
  487. if (column.find(".column-add-story")) {
  488. column.find(".column-add-story").unbind();
  489. column.find(".column-add-story").click(function() {
  490. var pipeline = filters.pipeline;
  491. var milestone;
  492. var status = "new";
  493. if (columnId.indexOf("20") == 0) {
  494. // Dated milestone column...
  495. milestone = columnId;
  496. } else if (columnId == "backlog") {
  497. // Backlog column
  498. milestone = columnId;
  499. } else {
  500. // Status column...
  501. milestone = filters.milestone;
  502. status = columnId;
  503. }
  504. addTicketDlg(pipeline, milestone, status, "story", "normal", " ", "TBD", "n/a", "", "", onAddCallback);
  505. });
  506. }
  507. // Hookup column refresh
  508. if (column.find(".column-reload")) {
  509. column.find(".column-reload").unbind();
  510. column.find(".column-reload").click(function() {
  511. refreshColumn($(this).parents(".column").attr("id"), onEditCallback, onAddCallback);
  512. });
  513. }
  514. // Make this column droppable
  515. $('#' + columnId + '.column').droppable({
  516. accept: '.ticket',
  517. tolerance: 'pointer',
  518. drop: function(evt, ui) {
  519. // Ticket dropped into milestone column...
  520. $tkt = ui.draggable;
  521. var ticketId = $tkt.attr("ticket-id");
  522. var columnId = $(this).attr("id");
  523. //alert("Dropping ticket " + ticketId + " into column " + columnId);
  524. $(this).removeClass("column-bg");
  525. // As long as ticket isn't already in this milestone, do it
  526. var ticketMilestone = $tkt.attr("ticket-milestone");
  527. if (ticketMilestone.toLowerCase() != columnId.toLowerCase()) {
  528. $(".ticket[ticket-id=" + ticketId + "]").remove();
  529. changeTicketMilestone(ticketId, columnId);
  530. }
  531. },
  532. over: function(evt, ui) {
  533. $tkt = ui.draggable;
  534. $(this).addClass("column-bg");
  535. },
  536. out: function(evt, ui) {
  537. $tkt = ui.draggable;
  538. $(this).removeClass("column-bg");
  539. }
  540. });
  541. }
  542. function toggleColumnWidth(toggle, columnId) {
  543. var col = $("#" + columnId);
  544. var newExpanded = 0;
  545. if (col.hasClass("column-expanded")) {
  546. // Go smaller
  547. col.removeClass("column-expanded");
  548. $(toggle).removeClass("column-expander-expanded").addClass("column-expander-compacted");
  549. newExpanded = 0;
  550. col.attr("style","");
  551. fixColumnHeights();
  552. } else {
  553. // Go wider
  554. col.addClass("column-expanded");
  555. $(toggle).removeClass("column-expander-compacted").addClass("column-expander-expanded");
  556. newExpanded = 1;
  557. fixColumnHeights();
  558. }
  559. // Update the record of our state
  560. var index = getColumnIndex(columnId);
  561. filters.expanded[index] = newExpanded;
  562. }
  563. function getColumnIndex(columnId) {
  564. //alert("Looking for index of column with id " + columnId);
  565. var foundIndex = 0;
  566. $(".column").each(function (index) {
  567. //alert("Checking column " + index + ", id " + $(this).attr("id"));
  568. if ($(this).attr("id") == ("" + columnId)) {
  569. //alert("found");
  570. foundIndex = index;
  571. return false;
  572. }
  573. });
  574. return foundIndex;
  575. }
  576. function fixColumnHeights() {
  577. $(".column").equalHeights();
  578. }
  579. // center any DOM element to absolute middle of screen
  580. jQuery.fn.center = function () {
  581. this.css("position","absolute");
  582. this.css("top", ( $(window).height() - this.outerHeight() ) / 2+$(window).scrollTop() + "px");
  583. this.css("left", ( $(window).width() - this.outerWidth() ) / 2+$(window).scrollLeft() + "px");
  584. return this;
  585. }
  586. function toggleColor(elem) {
  587. var coloredBy = $(elem).html();
  588. $(".ticket[colorby-field-val=" + coloredBy +"]").toggle();
  589. $(elem).parent().toggleClass("inactive");
  590. $(elem).toggleClass("inactive");
  591. }
  592. $(document).ready(function() {
  593. // Make sure we can log
  594. if (!window.console) {
  595. console = {};
  596. }
  597. // Cancel handling on the add/edit dialogs
  598. $("#add-story .cancel, #edit-story .cancel").unbind();
  599. $("#add-story .cancel, #edit-story .cancel").click(function() {
  600. $(".storySummary").val("");
  601. $(this).parent().parent().parent().parent().fadeOut();
  602. $(".dialog-wrapper").fadeOut();
  603. });
  604. // Handle ticket detail view chooser
  605. $("select[name=ticketStyle]").change(function() {
  606. var body = true;
  607. var header = true;
  608. var footer = true;
  609. if ($(this).val() == "compact") {
  610. body = false;
  611. header = true;
  612. footer = true;
  613. } else if ($(this).val() == "standard") {
  614. body = true;
  615. header = true;
  616. footer = true;
  617. } else if ($(this).val() == "simple") {
  618. body = true;
  619. header = false;
  620. footer = true;
  621. }
  622. if (header)
  623. $(".ticket .header").attr("style", "display:block");
  624. else
  625. $(".ticket .header").attr("style", "display:none");
  626. if (footer)
  627. $(".ticket .footer").attr("style", "display:block");
  628. else
  629. $(".ticket .footer").attr("style", "display:none");
  630. if (body)
  631. $(".ticket .body").attr("style", "display:block");
  632. else
  633. $(".ticket .body").attr("style", "display:none");
  634. });
  635. });