b1d16ae87c
Use OnConnection query string to add group membership rather than making an additional call after connection.
424 lines
18 KiB
Plaintext
424 lines
18 KiB
Plaintext
@model Disco.Web.Models.Job.ShowModel
|
|
@{
|
|
Html.BundleDeferred("~/Style/Shadowbox");
|
|
Html.BundleDeferred("~/ClientScripts/Modules/Shadowbox");
|
|
Html.BundleDeferred("~/ClientScripts/Modules/jQuery-SignalR");
|
|
}
|
|
<table id="jobShowResources">
|
|
<tr>
|
|
<td id="Comments">
|
|
<div class="commentOutput">
|
|
@foreach (var jl in Model.Job.JobLogs.OrderBy(m => m.Timestamp))
|
|
{
|
|
<div data-logid="@jl.Id">
|
|
<span class="author">@jl.TechUser.ToString()</span><span class="remove"></span><span class="timestamp" title="@jl.Timestamp.ToFullDateTime()">@jl.Timestamp.ToFuzzy()</span>
|
|
<span class="comment">@jl.Comments.ToMultilineJobRefString()</span>
|
|
</div>
|
|
}
|
|
</div>
|
|
<div class="commentInput clearfix">
|
|
<textarea class="commentInput" accesskey="l"></textarea>
|
|
<span class="action post commentInputPost"></span>
|
|
</div>
|
|
</td>
|
|
<td id="Attachments">
|
|
<div class="attachmentOutput">
|
|
@foreach (var ja in Model.Job.JobAttachments)
|
|
{
|
|
<a href="@Url.Action(MVC.API.Job.AttachmentDownload(ja.Id))" data-attachmentid="@ja.Id" data-mimetype="@ja.MimeType">
|
|
<span class="icon" title="@ja.Filename">
|
|
<img alt="Attachment Thumbnail" src="@(Url.Action(MVC.API.Job.AttachmentThumbnail(ja.Id)))" /></span>
|
|
<span class="comments" title="@ja.Comments">
|
|
@{if (!string.IsNullOrEmpty(ja.DocumentTemplateId))
|
|
{ @ja.DocumentTemplate.Description}
|
|
else
|
|
{ @ja.Comments }}
|
|
</span><span class="author">@ja.TechUser.ToString()</span><span class="remove"></span><span class="timestamp" title="@ja.Timestamp.ToFullDateTime()">@ja.Timestamp.ToFuzzy()</span>
|
|
</a>
|
|
}
|
|
</div>
|
|
<div class="attachmentInput clearfix">
|
|
<span class="action upload"></span><span class="action photo"></span>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
<div id="dialogUpload" class="hiddenDialog" title="Upload Attachment">
|
|
<div id="silverlightHostUploadAttachment">
|
|
</div>
|
|
</div>
|
|
<div id="dialogRemoveLog" class="hiddenDialog" title="Remove this Comment?">
|
|
<p>
|
|
<span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>
|
|
Are you sure?
|
|
</p>
|
|
</div>
|
|
<div id="dialogRemoveAttachment" class="hiddenDialog" title="Remove this Attachment?">
|
|
<p>
|
|
<span class="ui-icon ui-icon-alert" style="float: left; margin: 0 7px 20px 0;"></span>
|
|
Are you sure?
|
|
</p>
|
|
</div>
|
|
<script>
|
|
Shadowbox.init({
|
|
skipSetup: true,
|
|
modal: true
|
|
});
|
|
|
|
|
|
$(function () {
|
|
var jobId = parseInt('@(Model.Job.Id)');
|
|
|
|
//#region Comments
|
|
var $Comments = $('#Comments');
|
|
var $CommentOutput = $Comments.find('.commentOutput');
|
|
var $CommentOutputContainer = $Comments.find('.commentOutputContainer');
|
|
var $CommentInput = $Comments.find('textarea.commentInput');
|
|
var $dialogRemoveLog;
|
|
|
|
window.setTimeout(function () {
|
|
$CommentOutput[0].scrollTop = $CommentOutput[0].scrollHeight; // Scroll to Bottom
|
|
}, 0);
|
|
$('#jobDetailTabs').on('tabsactivate', function (event, ui) {
|
|
if (ui.newPanel && ui.newPanel.is('#jobDetailTab-Resources')) {
|
|
$CommentOutput[0].scrollTop = $CommentOutput[0].scrollHeight; // Scroll to Bottom
|
|
}
|
|
});
|
|
|
|
$Comments.find('.commentInputPost').click(postComment);
|
|
$CommentInput.keypress(function (e) {
|
|
if (e.which == 13 && !e.shiftKey) {
|
|
postComment();
|
|
return false;
|
|
}
|
|
});
|
|
$CommentOutput.find('span.remove').click(removePost);
|
|
|
|
function postComment() {
|
|
var comment = $CommentInput.val();
|
|
if (comment != '') {
|
|
var data = { comment: comment }
|
|
$.ajax({
|
|
url: '@Url.Action(MVC.API.Job.CommentPost(Model.Job.Id, null))',
|
|
dataType: 'json',
|
|
data: data,
|
|
success: function (d) {
|
|
if (d.Result == 'OK') {
|
|
// Should be added via Repository Notifications
|
|
// addComment(d.Comment, false);
|
|
$CommentInput.val('').attr('disabled', false).focus();
|
|
} else {
|
|
alert('Unable to post comment: ' + d.Result);
|
|
$CommentInput.attr('disabled', false);
|
|
}
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
alert('Unable to post comment: ' + textStatus);
|
|
$CommentInput.attr('disabled', false);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function removePost() {
|
|
$this = $(this);
|
|
var data = { id: $this.closest('div').attr('data-logid') };
|
|
|
|
if (!$dialogRemoveLog) {
|
|
$dialogRemoveLog = $('#dialogRemoveLog').dialog({
|
|
resizable: false,
|
|
height: 140,
|
|
modal: true,
|
|
autoOpen: false
|
|
});
|
|
}
|
|
|
|
$dialogRemoveLog.dialog("enable").dialog('option', 'buttons', {
|
|
"Remove": function () {
|
|
$dialogRemoveLog.dialog("disable");
|
|
$dialogRemoveLog.dialog("option", "buttons", null);
|
|
$.ajax({
|
|
url: '@Url.Action(MVC.API.Job.CommentRemove())',
|
|
dataType: 'json',
|
|
data: data,
|
|
success: function (d) {
|
|
if (d == 'OK') {
|
|
// Should be removed via Repository Notifications
|
|
//$this.closest('div').slideUp(300).delay(300).queue(function () {
|
|
// $(this).remove();
|
|
//});
|
|
} else {
|
|
alert('Unable to remove comment: ' + d);
|
|
}
|
|
$dialogRemoveLog.dialog("close");
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
alert('Unable to remove comment: ' + textStatus);
|
|
$dialogRemoveLog.dialog("close");
|
|
}
|
|
});
|
|
},
|
|
"Cancel": function () {
|
|
$dialogRemoveLog.dialog("close");
|
|
}
|
|
}).dialog('open');
|
|
|
|
return false;
|
|
}
|
|
function loadLiveComment(key) {
|
|
if (key.JobId == jobId) {
|
|
$.ajax({
|
|
url: '@Url.Action(MVC.API.Job.Comment())',
|
|
dataType: 'json',
|
|
data: { id: key.Id },
|
|
success: function (d) {
|
|
if (d && d.JobId == jobId) {
|
|
addComment(d, false);
|
|
}
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
alert('Unable to load live comment ' + id + ': ' + textStatus);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function addComment(c, quick) {
|
|
var e = $('<div><span class="author" /><span class="remove" /><span class="timestamp" /><span class="comment" /></div>');
|
|
e.attr('data-logid', c.Id);
|
|
e.find('.author').text(c.Author);
|
|
e.find('.timestamp').text(c.TimestampFuzzy).attr('title', c.TimestampFull);
|
|
e.find('.remove').click(removePost);
|
|
var eComment = e.find('.comment').text(c.Comments);
|
|
var commentHtml = eComment.text().replace(/\r\n|\r|\n/g, '<br />');
|
|
commentHtml = commentHtml.replace(/\#(\d+)/g, '<a href="@Url.Action(MVC.Job.Show(null))?id=$1">#$1</a>');
|
|
eComment.html(commentHtml);
|
|
|
|
$CommentOutput.append(e);
|
|
|
|
if (!quick) {
|
|
e.animate({ backgroundColor: '#ffff99' }, 500, function () {
|
|
e.animate({ backgroundColor: '#f4f4f4' }, 500);
|
|
});
|
|
$CommentOutput.animate({ scrollTop: $CommentOutput[0].scrollHeight }, 250)
|
|
}
|
|
}
|
|
//#endregion
|
|
|
|
//#region Attachments
|
|
if (!document.DiscoFunctions) {
|
|
document.DiscoFunctions = {};
|
|
}
|
|
// For Silverlight Backwards-compatibility
|
|
// - Repository notifications now handles this
|
|
document.DiscoFunctions.addAttachment = function () { };
|
|
|
|
var $Attachments = $('#Attachments');
|
|
var $attachmentOutput = $Attachments.find('.attachmentOutput');
|
|
var $dialogUpload, $dialogRemoveAttachment;
|
|
|
|
$attachmentOutput.find('span.remove').click(removeLocalAttachment);
|
|
|
|
var onLoadNavigation = null;
|
|
var isLoaded = null;
|
|
Silverlight.createObject(
|
|
'@(Links.ClientBin.Disco_Silverlight_AttachmentUpload_xap)',
|
|
$('#silverlightHostUploadAttachment').get(0),
|
|
'silverlightUploadAttachment',
|
|
{ width: '840px', height: '500px', background: 'white', version: '4.0.60310.0' },
|
|
{
|
|
onLoad: function () {
|
|
if (onLoadNavigation) {
|
|
silverlightUploadAttachment.content.Navigator.Navigate(onLoadNavigation);
|
|
isLoaded = true;
|
|
}
|
|
}
|
|
},
|
|
'UploadUrl=@(Url.Action(MVC.API.Job.AttachmentUpload(Model.Job.Id, null)))'
|
|
);
|
|
|
|
var $attachmentInput = $Attachments.find('.attachmentInput');
|
|
$attachmentInput.find('.photo').click(function () {
|
|
showDialog('/WebCam');
|
|
});
|
|
$attachmentInput.find('.upload').click(function () {
|
|
showDialog('/File');
|
|
});
|
|
|
|
var silverlightUploadAttachment = $('#silverlightUploadAttachment').get(0);
|
|
function showDialog(navigationPath) {
|
|
if (!$dialogUpload) {
|
|
$dialogUpload = $('#dialogUpload').dialog({
|
|
autoOpen: false,
|
|
draggable: false,
|
|
modal: true,
|
|
resizable: false,
|
|
width: 860,
|
|
height: 550,
|
|
close: function () {
|
|
silverlightUploadAttachment.content.Navigator.Navigate('/Hidden');
|
|
}
|
|
});
|
|
}
|
|
$dialogUpload.dialog('open');
|
|
if (isLoaded) {
|
|
silverlightUploadAttachment.content.Navigator.Navigate(navigationPath);
|
|
} else {
|
|
onLoadNavigation = navigationPath;
|
|
}
|
|
};
|
|
function addAttachment(key, quick) {
|
|
|
|
if (key.JobId == jobId) {
|
|
var data = { id: key.Id };
|
|
|
|
$.ajax({
|
|
url: '@Url.Action(MVC.API.Job.Attachment())',
|
|
dataType: 'json',
|
|
data: data,
|
|
success: function (d) {
|
|
if (d.Result == 'OK') {
|
|
var a = d.Attachment;
|
|
|
|
if (parseInt(a.ParentId) == jobId) {
|
|
var e = $('<a><span class="icon"><img alt="Attachment Thumbnail" /></span><span class="comments"></span><span class="author"></span><span class="remove"></span><span class="timestamp"></span></a>');
|
|
|
|
e.attr('data-attachmentid', a.Id).attr('data-mimetype', a.MimeType).attr('href', '@(Url.Action(MVC.API.Job.AttachmentDownload()))/' + a.Id);
|
|
e.find('.icon img').attr('src', '@(Url.Action(MVC.API.Job.AttachmentThumbnail()))/' + a.Id);
|
|
e.find('.comments').text(a.Comments);
|
|
e.find('.author').text(a.Author);
|
|
e.find('.timestamp').text(a.TimestampFuzzy).attr('title', a.TimestampFull);
|
|
e.find('.remove').click(removeLocalAttachment);
|
|
if (!quick)
|
|
e.hide();
|
|
$attachmentOutput.append(e);
|
|
if (!quick)
|
|
e.show('slow');
|
|
if (a.MimeType.toLowerCase().indexOf('image/') == 0)
|
|
e.shadowbox({ gallery: 'attachments', player: 'img', title: a.Comments });
|
|
}
|
|
} else {
|
|
alert('Unable to add attachment: ' + d.Result);
|
|
}
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
alert('Unable to add attachment: ' + textStatus);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
function removeAttachment(key) {
|
|
if (key.JobId == jobId) {
|
|
var $element = $attachmentOutput.find('a[data-attachmentid="' + key.Id + '"]');
|
|
if ($element.length > 0) {
|
|
$element.hide(300).delay(300).queue(function () {
|
|
if ($element.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
|
|
Shadowbox.removeCache(this);
|
|
$element.remove();
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
function removeLocalAttachment() {
|
|
$this = $(this).closest('a');
|
|
|
|
var data = { id: $this.attr('data-attachmentid') };
|
|
|
|
if (!$dialogRemoveAttachment) {
|
|
$dialogRemoveAttachment = $('#dialogRemoveAttachment').dialog({
|
|
resizable: false,
|
|
height: 140,
|
|
modal: true,
|
|
autoOpen: false
|
|
});
|
|
}
|
|
|
|
$dialogRemoveAttachment.dialog("enable").dialog('option', 'buttons', {
|
|
"Remove": function () {
|
|
$dialogRemoveAttachment.dialog("disable");
|
|
$dialogRemoveAttachment.dialog("option", "buttons", null);
|
|
$.ajax({
|
|
url: '@Url.Action(MVC.API.Job.AttachmentRemove())',
|
|
dataType: 'json',
|
|
data: data,
|
|
success: function (d) {
|
|
if (d == 'OK') {
|
|
// Should be removed via Repository Notifications
|
|
//$this.hide(300).delay(300).queue(function () {
|
|
// var $this = $(this);
|
|
// if ($this.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
|
|
// Shadowbox.removeCache(this);
|
|
// $this.remove();
|
|
//});
|
|
} else {
|
|
alert('Unable to remove attachment: ' + d);
|
|
}
|
|
$dialogRemoveAttachment.dialog("close");
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
alert('Unable to remove attachment: ' + textStatus);
|
|
$dialogRemoveAttachment.dialog("close");
|
|
}
|
|
});
|
|
},
|
|
"Cancel": function () {
|
|
$dialogRemoveAttachment.dialog("close");
|
|
}
|
|
}).dialog('open');
|
|
|
|
return false;
|
|
}
|
|
|
|
$attachmentOutput.children('a').each(function () {
|
|
$this = $(this);
|
|
if ($this.attr('data-mimetype').toLowerCase().indexOf('image/') == 0)
|
|
$this.shadowbox({ gallery: 'attachments', player: 'img', title: $this.find('.comments').text() });
|
|
});
|
|
//#endregion
|
|
|
|
//#region LiveEvents
|
|
function liveMessageRecieved(d) {
|
|
if (d) {
|
|
window.setTimeout(function () {
|
|
switch (d.EntityTypeName) {
|
|
case 'JobAttachment':
|
|
switch (d.EventType) {
|
|
case 0: // Added
|
|
addAttachment(d.EntityKey, false);
|
|
break;
|
|
case 1: // Removed
|
|
removeAttachment(d.EntityKey);
|
|
break;
|
|
}
|
|
break;
|
|
case 'JobLog':
|
|
switch (d.EventType) {
|
|
case 0: // Added
|
|
loadLiveComment(d.EntityKey);
|
|
break;
|
|
case 1: // Removed
|
|
if (d.EntityKey.JobId == jobId) {
|
|
$CommentOutput.children('div[data-logid="' + d.EntityKey.Id + '"]').slideUp(300).delay(300).queue(function () {
|
|
$(this).remove();
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}, 100);
|
|
}
|
|
}
|
|
var liveMessagesConnection = $.connection('@(Url.Content("~/API/Repository/Notifications"))', { addToGroups: 'JobLog,JobAttachment' })
|
|
liveMessagesConnection.received(liveMessageRecieved);
|
|
liveMessagesConnection.error(function (e) {
|
|
if (e)
|
|
alert('Error: ' + JSON.stringify(e));
|
|
});
|
|
liveMessagesConnection.start();
|
|
//#endregion
|
|
|
|
});
|
|
|
|
|
|
</script>
|