|
/// <summary>
/// Capture original functionality of 'Edit Timesheet' button.
/// Execute it and then append our custom code to add the 'Comment' link.
/// </summary>
var oldShow = ClockPopup.show;
ClockPopup.show = function(){
var result = oldShow.apply(ClockPopup, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(true);
return result;
}
/// <summary>
/// Capture original functionality of 'Previous Date' arrow button.
/// Execute it and then append our custom code to add the 'Comment' link.
/// </summary>
var oldPrevDt = Timesheet.prevDt;
Timesheet.prevDt = function (){
var result = oldPrevDt.apply(Timesheet, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(true);
return result;
}
/// <summary>
/// Capture original functionality of 'Next Date' arrow button.
/// Execute it and then append our custom code to add the 'Comment' link.
/// </summary>
var oldNextDt = Timesheet.nextDt;
Timesheet.nextDt = function (){
var result = oldNextDt.apply(Timesheet, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(true);
return result;
}
/// <summary>
/// Capture original functionality of 'Save' button after an interval has been added.
/// Execute it and then append our custom code to add the 'Comment' links.
/// </summary>
var oldCommit = Timesheet.commit;
Timesheet.commit = function (){
var result = oldCommit.apply(Timesheet, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(true);
return result;
}
/// <summary>
/// Capture original functionality of 'OK' button on pop-up when 'Add Interval' is clicked.
/// Execute it and then append our custom code to add the 'Comment' link.
/// </summary>
var oldSubmitEditor = Timesheet.submitEditor
Timesheet.submitEditor = function (){
var result = oldSubmitEditor.apply(Timesheet, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(false);
return result;
}
/// <summary>
///Capture original functionality of selecting a date from the TimeSheet calendar.
///Execute it and then append our custom code to add the 'Comment' links.
/// </summary>
var oldCalSetDay = cal.setDay;
cal.setDay = function (){
var result = oldCalSetDay.apply(cal, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(true);
return result;
}
/// <summary>
//Capture original functionality of selecting a Time Entry Row for deletion.
//Execute it and then append our custom code to add the 'Comment' links.
/// </summary>
var oldTiByIx = Timesheet.tiByIx;
Timesheet.tiByIx = function () {
var result = oldTiByIx.apply(Timesheet, arguments);
var commentLinkInserter = new CommentLinkInserter();
commentLinkInserter.Insert(false);
return result;
}
/// <summary>
/// Main function called by 'Edit Timesheet' and the Next/Previous date arrow buttons.
/// Checks to see if the Timesheet table is present and that the rows in the timesheet are valid.
/// "Valid" is defined by: The displayed date is not empty of time entries and a comment link isn't already present.
/// See the insertCommentHtml function for a full description of the 'addFullCommentHtml' parameter
/// </summary>
var CommentLinkInserter = function () {
var numberOfRetries = 0;
var insertCommentHtmlLink = function (addFullCommentHtml) {
if (numberOfRetries < 50) {
if (isTimesheetTableValid() && isTimesheetRowValid()) {
insertCommentHtml(addFullCommentHtml);
return true;
}
setTimeout(function () { insertCommentHtmlLink(addFullCommentHtml) }, 200);
numberOfRetries++;
return false;
}
}
/// <summary>
///Check if timesheet table has been generated yet
/// </summary>
var isTimesheetTableValid = function () {
if ($('#idTimesheetTable').length === 0) {
return false;
}
return true;
}
/// <summary>
/// Check if timesheet table row is "valid".
/// "Valid" is defined by: The displayed date is not empty of time entries and a comment link isn't already present.
/// </summary>
var isTimesheetRowValid = function () {
var isCommentLinkAlreadyPresent = $('.commentButton').length;
var isTimeEntryRowValid = $('#idTimesheetTable tr[id^="idTIRow"]').length;
return (isCommentLinkAlreadyPresent === 0 && isTimeEntryRowValid != 0) ? true : false;
}
/// <summary>
/// This method updates the DOM of the timesheet popup to include
/// a 'Comment' link for each existing time entry row.
/// </summary>
var insertCommentHtml = function (addFullCommentHtml) {
var comment;
var commentHtml;
//Add new column for 'Comments'
$('<th></th>').insertAfter($('#idTimesheetTable tbody tr th:last-child'));
$("#idTimesheetTable tbody tr").each(function (index) {
var thisId = $(this).attr("id");
//jQuery workaround: thisId returns "" in FogBugz 8.3.4.2, 'undefined' in 8.7.60.
thisId = (thisId == undefined) ? "" : thisId;
var ixInterval = thisId.substring(thisId.indexOf("_") + 1);
if (thisId != "" && $(this).hasClass("row") && ixInterval > 0) {
commentHtml = '<td colspan="2" class="commentButton"><a href="#" ixInterval="' + ixInterval + '" onclick="CommentEntryPopUp.showCommentPopUp(this); return false;" style="white-space: nowrap;">' + '[Comment]' + '</a></td>';
$(this).append(commentHtml);
updateCommentText(ixInterval, '#idTIRow_' + ixInterval + ' .commentButton a', 'text');
}
else if (thisId != null && $(this).hasClass("row") && ixInterval < 0) {
commentHtml = '<td "colspan="2" class="commentButton"></td>';
$(this).append(commentHtml);
}
/// Check for jquery versions 1.4 or greater, since they're the ones supporting .last jquery method
/// If it's less than 1.4, this plug-in will still work fine except the 'Close' button will be slightly
/// misaligned by one table cell.
if ($().jquery >= '1.4') {
/// The addition of the comment button adds a new td.
/// Therefore, all non-time entry rows must span an extra cell now
/// or else the cell styling will not look right.
var children = $(this).children();
var lastchild = children.last();
var lastchildcolspan = lastchild.attr("colspan") || 1;
lastchild.attr("colspan", parseInt(lastchildcolspan) + 1)
}
});
}
return {
Insert: insertCommentHtmlLink
}
};
/// <summary>
/// FogCreek comment: This is the standard fogbugz popup code, managed by the PopupManager object
/// It also calls updateCommentText to fetch the comment for the interval being shown.
/// </summary>
var CommentEntryPopUp = new function () {
var oSelf = this;
this.showCommentPopUp = function(elPopupAnchor)
{
var comment;
oSelf.Popup.setHtml(
'<form id="CommentEntryPopUpForm" onsubmit="CommentEntryPopUp.Popup.hide(); saveTimeIntervalComment(); return false;">\n' +
'<h1><label for="comment">Comment:</label></h1>' +
'<div>' +
'<input type="hidden" name="ixInterval">' +
'<input type="text" style="padding:0px;width:40em;" id="comment" name="comment">' +
'</div>' +
'<br/><nobr style="float:right;margin-bottom:12px;margin-right:3px;"><input type="submit" value="' + FB_OK + '" class="dlgButton"> ' +
'<input type="button" onclick="CommentEntryPopUp.Popup.hide(); return false;" value="' + FB_CANCEL+ '" class="dlgButton"></nobr>' +
'</form>');
oSelf.Popup.showPopup(elPopupAnchor);
$("#CommentEntryPopUpForm input[name=ixInterval]").val(elPopupAnchor.attributes.getNamedItem('ixInterval').value);
updateCommentText(elPopupAnchor.attributes.getNamedItem('ixInterval').value, '#CommentEntryPopUpForm input[name=comment]','input');
return false;
}
$(document).ready(function(){
oSelf.Popup = api.PopupManager.newPopup("CommentEntryPopUp");
});
}();
/// <summary>
/// Function called after 'Save' is pressed on the Comment Entry pop-up. Saves comment and
/// updates text in the main timesheet view via the 'SetCommentText...' Callback function
/// </summary>
function saveTimeIntervalComment() {
var commentText = $('#CommentEntryPopUpForm input[name=comment]').val();
var ixInterval = $('#CommentEntryPopUpForm input[name=ixInterval]').val();
var targetElement = '#idTIRow_' + ixInterval + ' .commentButton a';
var prefix = TrackerCommentsPlugIn.pluginPrefix;
var url = TrackerCommentsPlugIn.plugInRawPageUrl
+ '&' + prefix + 'action=saveTimeIntervalComment'
+ '&' + prefix + 'actionToken=' + TrackerCommentsPlugIn.PostTimeFunctionToken
+ '&' + prefix + TrackerCommentsPlugIn.TimeIntervalForeignKeyColumnName + '=' + ixInterval
+ '&' + prefix + 'sComment=' + encodeURIComponent(commentText);
jQuery.get(url, function () { setCommentTextForElementText(targetElement, commentText); });
}
/// <summary>
/// Function to update the Comment text that appears after a timesheet entry.
/// </summary>
function updateCommentText(ixInterval, targetElement, targetElementType) {
var prefix = TrackerCommentsPlugIn.pluginPrefix;
var url = TrackerCommentsPlugIn.plugInRawPageUrl
+ '&' + prefix + 'action=updateCommentText'
+ '&' + prefix + 'actionToken=' + TrackerCommentsPlugIn.UpdateCommentFunctionToken
+ '&' + prefix + TrackerCommentsPlugIn.TimeIntervalForeignKeyColumnName + '=' + ixInterval;
url = decodeURIComponent(url);
switch (targetElementType) {
case 'text':
$.get(url, function (commentText) { setCommentTextForElementText(targetElement, commentText); });
break;
case 'input':
$.get(url, function (commentText) { setCommentTextForFormInput(targetElement, commentText); });
break;
default:
alert("Problem in updateTargetTextCallback function. Didn't specify a valid 'targetElementType' parameter.");
}
}
/// <summary>
/// Function used to dynamically rewrite existing comment text in a Form input.
/// </summary>
function setCommentTextForFormInput(targetElement, commentText) {
if (commentText.substring(0, 11) == '!!Failure!!') {
alert('Error: Returned comment was reported as "failed".');
}
else {
$(targetElement).val(commentText);
}
}
/// <summary>
/// Function used to dynamically rewrite existing comment text for general HTML elements.
/// </summary>
function setCommentTextForElementText(targetElement, commentText) {
var truncateLength = 9;
if (commentText.substring(0, 11) == '!!Failure!!') {
alert('Error: Returned comment was reported as "failed".');
}
else {
// If the comment is empty use the default
commentText = (commentText != '')
? commentText
: '[Comment]';
commentText = (commentText.length > truncateLength)
? commentText.substring(0, truncateLength - 3) + '...'
: commentText;
$(targetElement).text(commentText);
}
}
|
Loading...