// --
// Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
// --
// This software comes with ABSOLUTELY NO WARRANTY. For details, see
// the enclosed file COPYING for license information (GPL). If you
// did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
// --
"use strict";
var Core = Core || {};
Core.Agent = Core.Agent || {};
/**
* @namespace Core.Agent.TicketZoom
* @memberof Core.Agent
* @author OTRS AG
* @description
* This namespace contains the special module functions for TicketZoom.
*/
Core.Agent.TicketZoom = (function (TargetNS) {
/**
* @private
* @name CheckURLHashTimeout
* @memberof Core.Agent.TicketZoom
* @member {Object}
* @description
* CheckURLHashTimeout
*/
var CheckURLHashTimeout,
/**
* @private
* @name InitialArticleID
* @memberof Core.Agent.TicketZoom
* @member {String}
* @description
* InitialArticleID
*/
InitialArticleID;
/**
* @name MarkTicketAsSeen
* @memberof Core.Agent.TicketZoom
* @function
* @param {String} TicketID - TicketID of ticket which gets shown
* @description
* Mark all articles as seen in frontend and backend.
* Article Filters will not be considered
*/
TargetNS.MarkTicketAsSeen = function (TicketID) {
TargetNS.TicketMarkAsSeenTimeout = window.setTimeout(function () {
var Data = {
Action: 'AgentTicketZoom',
Subaction: 'TicketMarkAsSeen',
TicketID: TicketID
};
// Mark old row as read
$('#ArticleTable .ArticleID').closest('tr').removeClass('UnreadArticles').find('span.UnreadArticles').remove();
// Mark article as seen in backend
Core.AJAX.FunctionCall(
Core.Config.Get('CGIHandle'),
Data,
function () {}
);
}, 3000);
};
/**
* @name MarkAsSeen
* @memberof Core.Agent.TicketZoom
* @function
* @param {String} TicketID - TicketID of ticket which get's shown.
* @param {String} ArticleID - ArticleID of article which get's shown.
* @param {String} [Timeout=3000] - Timeout in milliseconds
* @description
* Mark an article as seen in frontend and backend.
*/
TargetNS.MarkAsSeen = function (TicketID, ArticleID, Timeout) {
// assign default timeout
if (typeof Timeout === 'undefined') {
Timeout = 3000;
}
TargetNS.MarkAsSeenTimeout = window.setTimeout(function () {
var Data = {
Action: 'AgentTicketZoom',
Subaction: 'MarkAsSeen',
TicketID: TicketID,
ArticleID: ArticleID
};
// Mark old row as readed
$('#ArticleTable .ArticleID[value=' + ArticleID + ']').closest('tr').removeClass('UnreadArticles').find('span.UnreadArticles').remove();
$('.TimelineView li#ArticleID_' + ArticleID).find('.UnreadArticles').fadeOut(function() {
$(this).closest('li').addClass('Seen');
});
// Mark article as seen in backend
Core.AJAX.FunctionCall(
Core.Config.Get('CGIHandle'),
Data,
function () {}
);
}, parseInt(Timeout, 10));
};
/**
* @name IframeAutoHeight
* @memberof Core.Agent.TicketZoom
* @function
* @param {jQueryObject} $Iframe - The iframe which should be auto-heighted
* @description
* Set iframe height automatically based on real content height and default config setting.
*/
TargetNS.IframeAutoHeight = function ($Iframe) {
var NewHeight,
IframeBodyHeight,
ArticleHeightMax = Core.Config.Get('Ticket::Frontend::HTMLArticleHeightMax');
if (isJQueryObject($Iframe)) {
IframeBodyHeight = $Iframe.contents().find('body').height();
NewHeight = $Iframe.contents().height();
if (!NewHeight || isNaN(NewHeight)) {
NewHeight = Core.Config.Get('Ticket::Frontend::HTMLArticleHeightDefault');
}
else {
if (IframeBodyHeight > ArticleHeightMax
|| NewHeight > ArticleHeightMax) {
NewHeight = ArticleHeightMax;
}
else if (IframeBodyHeight > NewHeight) {
NewHeight = IframeBodyHeight;
}
}
// add delta for scrollbar
NewHeight = parseInt(NewHeight, 10) + 25;
// make sure the minimum height is in line with the avatar images
if (NewHeight < 46) {
NewHeight = 46;
}
$Iframe.height(NewHeight + 'px');
}
};
/**
* @private
* @name LoadArticle
* @memberof Core.Agent.TicketZoom
* @function
* @param {String} ArticleURL - The URL which should be loaded via AJAX
* @param {String} ArticleID - The article number of the loaded article
* @description
* This function loads the given article via ajax.
*/
function LoadArticle(ArticleURL, ArticleID) {
// Clear timeout for URL hash check, because hash is now changed manually
window.clearTimeout(CheckURLHashTimeout);
// Add loader to the widget
$('#ArticleItems .WidgetBox').addClass('Loading');
Core.AJAX.ContentUpdate($('#ArticleItems'), ArticleURL, function () {
// Top position of Scroller element (surrounds article table)
var ScrollerY = parseInt($('div.Scroller').offset().top, 10),
// Height of scroller element
ScrollerHeight = parseInt($('div.Scroller').height(), 10),
// Top position of active article (offset based on screen position)
ActiveArticlePosY = parseInt($('#ArticleTable tbody tr.Active').offset().top, 10),
// Height of active article
ActiveArticleHeight = parseInt($('#ArticleTable tbody tr.Active').height(), 10),
// Bottom position of active article
ActiveArticleBottomY = ActiveArticlePosY + ActiveArticleHeight,
// Bottom position of scroller element
ScrollerBottomY = ScrollerY + ScrollerHeight,
// Offset of scroller element (relative)
ScrollerOffset = $('div.Scroller').get(0).scrollTop,
// article menu
ArticleIndex, Index, MenuItems = Core.Config.Get('MenuItems') || [];
$('#ArticleItems a.AsPopup').on('click', function () {
var Matches,
PopupType = 'TicketAction';
Matches = $(this).attr('class').match(/PopupType_(\w+)/);
if (Matches) {
PopupType = Matches[1];
}
Core.UI.Popup.OpenPopup($(this).attr('href'), PopupType);
return false;
});
// Add event bindings to new widget.
ArticleDetailsEvents();
Core.UI.InitWidgetActionToggle();
// Add hash to the URL to provide direct URLs and history back/forward functionality
// If new ArticleID is again the InitialArticleID than remove hash from URL
if (ArticleID === InitialArticleID) {
location.hash = '';
TargetNS.ActiveURLHash = ArticleID;
}
else {
location.hash = '#' + ArticleID;
TargetNS.ActiveURLHash = ArticleID;
}
// add switchable toggle for new article
$('label.Switchable').off('click.Switch').on('click.Switch', function() {
$(this).next('p.Value').find('.Switch').toggleClass('Hidden');
});
//Remove Loading class
$('#ArticleItems .WidgetBox').removeClass('Loading');
// Scroll to new active article
// if article is not visible and is above the visible area, move the visible area
// add 5px of delta for better usability (top border is definetly visible)
if (ActiveArticlePosY < ScrollerY) {
$('div.Scroller').get(0).scrollTop = ScrollerOffset + (ActiveArticlePosY - ScrollerY) - 5;
}
// if article is not visible and is below the visible area, move the visible area
// add 5px of delta for better usability (bottom border is definetly visible)
else if (ScrollerBottomY < ActiveArticleBottomY) {
$('div.Scroller').get(0).scrollTop = ScrollerOffset + (ActiveArticleBottomY - ScrollerBottomY) + 5;
}
// Initiate URL hash check again
TargetNS.CheckURLHash();
// If session is over and login screen
// is showed in article area
Core.Agent.CheckSessionExpiredAndReload();
// create open popup event for dropdown elements
if (MenuItems.length > 0) {
for (ArticleIndex in MenuItems) {
for (Index in MenuItems[ArticleIndex]) {
if (MenuItems[ArticleIndex][Index].ItemType === 'Dropdown' && MenuItems[ArticleIndex][Index].Type === 'OnLoad') {
if (MenuItems[ArticleIndex][Index].DropdownType === 'Forward') {
Core.Agent.TicketZoom.ArticleActionMenuDropdown(MenuItems[ArticleIndex][Index].FormID, "ForwardTemplateID");
}
else if (MenuItems[ArticleIndex][Index].DropdownType === 'Reply') {
Core.Agent.TicketZoom.ArticleActionMenuDropdown(MenuItems[ArticleIndex][Index].FormID, "ResponseID");
}
}
}
}
}
// Initialize modern input fields in article actions.
Core.UI.InputFields.Activate($('#ArticleItems'));
});
}
/**
* @name ArticleActionMenuDropdown
* @memberof Core.Agent.TicketZoom
* @function
* @param {String} FormID - ID of html element for which event is created
* @param {String} Name - Name of html element for which event is created
* @description
* This function creates onchange open popup event for dropdown html element.
*/
TargetNS.ArticleActionMenuDropdown = function (FormID, Name) {
var URL;
$('#' + FormID + ' select[name=' + Name + ']').on('change', function () {
if ($(this).val() > 0) {
URL = Core.Config.Get('Baselink') + $(this).parents().serialize();
Core.UI.Popup.OpenPopup(URL, 'TicketAction');
// reset the select box so that it can be used again from the same window
$(this).val('0');
}
});
};
/**
* @name LoadArticleFromExternal
* @memberof Core.Agent.TicketZoom
* @function
* @param {String} ArticleID - The article number of the loaded article
* @param {Object} WindowObject
* @description
* Used in OTRS Business Solution (TM). Loads an article in the Zoom from another window context (e.g. popup).
*/
TargetNS.LoadArticleFromExternal = function (ArticleID, WindowObject) {
var $Element = $('#ArticleTable td.No input.ArticleID[value=' + ArticleID + ']'),
ArticleURL;
// Check if we are in timeline view
// in this case we can jump directly to the article
if ($('.ArticleView .Timeline').hasClass('Active')) {
window.location.hash = '#ArticleID_' + ArticleID;
}
else {
if (!$Element.length) {
if (typeof WindowObject === 'undefined') {
WindowObject = window;
}
WindowObject.alert(Core.Config.Get('Language.AttachmentViewMessage'));
return;
}
ArticleURL = $Element.siblings('.ArticleInfo').val();
LoadArticle(ArticleURL, ArticleID);
}
};
/**
* @name CheckURLHash
* @memberof Core.Agent.TicketZoom
* @function
* @description
* This function checks if the url hash (representing the current article)
* has changed and initiates an article load. A change can happen by clicking
* 'back' in the browser, for example.
*/
TargetNS.CheckURLHash = function () {
var URLHash = location.hash.replace(/#/, ''),
$ArticleElement;
// if URLHash is empty, that means we are watching the initial article,
// save this information in URLHash as if it would have been in the URL
if (URLHash === '') {
URLHash = InitialArticleID;
}
// if not defined yet
if (typeof TargetNS.ActiveURLHash === 'undefined') {
TargetNS.ActiveURLHash = InitialArticleID;
}
// if defined and saved value is different to latest value (= user has used history back or forward)
else if (TargetNS.ActiveURLHash !== URLHash) {
TargetNS.ActiveURLHash = URLHash;
// if article ID is found in article list (= article id is valid)
$ArticleElement = $('#ArticleTable').find('input.ArticleID[value=' + TargetNS.ActiveURLHash + ']');
if ($ArticleElement.length) {
// Add active state to new row
$($ArticleElement).closest('table').find('tr').removeClass('Active').end().end().closest('tr').addClass('Active');
// Load content of new article
LoadArticle($ArticleElement.closest('td').find('input.ArticleInfo').val(), TargetNS.ActiveURLHash);
}
}
// start check again in 500ms
window.clearTimeout(CheckURLHashTimeout);
CheckURLHashTimeout = window.setTimeout(function () {
TargetNS.CheckURLHash();
}, 500);
};
/**
* @private
* @name ArticleViewEvents
* @memberof Core.Agent.TicketZoom
* @function
* @description
* This function initializes article view settings dialog.
*/
function ArticleViewEvents() {
var $ArticleViewSettingsObj = $('#ArticleViewSettings'),
ArticleViewSettingsDialogHTML;
if (!$ArticleViewSettingsObj.length) {
return;
}
ArticleViewSettingsDialogHTML = Core.Template.Render('Agent/TicketZoom/ArticleViewSettingsDialog', {
'ArticleViewStrg': Core.Config.Get('ArticleViewStrg')
});
// Calendar settings button
$ArticleViewSettingsObj.off('click.AgentTicketZoom').on('click.AgentTicketZoom', function (Event) {
Core.UI.Dialog.ShowContentDialog(ArticleViewSettingsDialogHTML, Core.Language.Translate('Settings'), '10px', 'Center', true,
[
{
Label: Core.Language.Translate('Close this dialog'),
Type: 'Close'
}
], true);
$('#ArticleView').off('change').on('change', function() {
if (!parseInt(Core.Config.Get('OTRSBusinessIsInstalled'), 10) && ($(this).val() === null || $(this).val() === '')) {
Core.UI.Dialog.CloseDialog($('.Dialog:visible'));
Core.Agent.ShowOTRSBusinessRequiredDialog();
return false;
}
else {
Core.UI.Dialog.MakeDialogWait();
$('#ArticleView').closest('form').submit();
}
});
Event.preventDefault();
Event.stopPropagation();
return false;
});
}
/**
* @private
* @name ArticleFilterEvents
* @memberof Core.Agent.TicketZoom
* @function
* @param {String} ArticleFilterDialog - parameter which defines what kind of dialog will be created
* @param {String} TicketID - ID of ticket which is shown
* @description
* This function sets and resets article filter.
*/
function ArticleFilterEvents(ArticleFilterDialog, TicketID) {
if (ArticleFilterDialog === 1) {
$('#SetArticleFilter').on('click', function () {
Core.UI.Dialog.ShowContentDialog($('#ArticleFilterDialog'), Core.Language.Translate("Article filter"), '20px', 'Center', true, [
{
Label: Core.Language.Translate("Apply"),
Function: function () {
var Data = Core.AJAX.SerializeForm($('#ArticleFilterDialogForm'));
Core.AJAX.FunctionCall(Core.Config.Get('CGIHandle'), Data, function () {
location.reload();
}, 'text');
}
},
{
Label: Core.Language.Translate("Reset"),
Function: function () {
$('#CommunicationChannelFilter').val('').trigger('redraw.InputField');
$('#ArticleSenderTypeFilter').val('').trigger('redraw.InputField');
}
}
]);
return false;
});
$('#ResetArticleFilter').on('click', function () {
var Data = {
Action: 'AgentTicketZoom',
Subaction: 'ArticleFilterSet',
TicketID: TicketID,
SaveDefaults: 1
};
Core.AJAX.FunctionCall(Core.Config.Get('CGIHandle'), Data, function () {
location.reload();
});
});
}
else {
$('#SetArticleFilter').on('click', function () {
$('#EventTypeFilterDialog').find('form').css('width', '500px');
Core.UI.Dialog.ShowContentDialog($('#EventTypeFilterDialog'), Core.Language.Translate("Event Type Filter"), '20px', 'Center', true, [
{
Label: Core.Language.Translate("Apply"),
Function: function () {
var Data = Core.AJAX.SerializeForm($('#EventTypeFilterDialogForm'));
Core.AJAX.FunctionCall(Core.Config.Get('CGIHandle'), Data, function () {
location.reload();
}, 'text');
}
},
{
Label: Core.Language.Translate("Reset"),
Function: function () {
$('#EventTypeFilter').val('').trigger('redraw.InputField');
}
}
]);
return false;
});
$('#ResetArticleFilter').on('click', function () {
var Data = {
Action: 'AgentTicketZoom',
Subaction: 'EvenTypeFilterSet',
TicketID: TicketID,
SaveDefaults: 1
};
Core.AJAX.FunctionCall(Core.Config.Get('CGIHandle'), Data, function () {
location.reload();
});
});
}
}
/**
* @private
* @name InitProcessWidget
* @memberof Core.Agent.TicketZoom
* @function
* @description
* This function initializes events for process widget.
*/
function InitProcessWidget() {
var WidgetWidth, FieldsPerRow, FieldMargin, FieldWidth;
if ($('.DynamicFieldAutoResize').length > 0) {
WidgetWidth = parseInt($('#DynamicFieldsWidget').innerWidth() - 15, 10);
FieldMargin = parseInt($('.DynamicFieldAutoResize').css('margin-right'), 10) + 2;
FieldsPerRow = 4;
// define amount of fields per row depending on display resolution
if (WidgetWidth < 400) {
FieldsPerRow = 1;
}
else if (WidgetWidth < 600) {
FieldsPerRow = 2;
}
else if (WidgetWidth < 1000) {
FieldsPerRow = 3;
}
// determine the needed field width and resize the fields
if (FieldsPerRow === 1) {
FieldWidth = '100%';
}
else {
FieldWidth = parseInt(WidgetWidth / FieldsPerRow - FieldMargin - 1, 10) || 0;
}
$('.DynamicFieldAutoResize').width(FieldWidth);
}
$('.ShowFieldInfoOverlay').on('click', function() {
var OverlayTitle = $(this).closest('label').attr('title'),
OverlayHTML = $(this).closest('.FieldContainer').find('.Value').html();
OverlayHTML = '<div class="FieldOverlay">' + OverlayHTML + '</div>';
Core.UI.Dialog.ShowDialog({
Modal: true,
Title: OverlayTitle,
HTML: OverlayHTML,
PositionTop: '100px',
PositionLeft: 'Center',
CloseOnEscape: true,
Buttons: [
{
Type: 'Close',
Label: Core.Language.Translate("Close this dialog"),
Function: function() {
Core.UI.Dialog.CloseDialog($('.Dialog:visible'));
Core.Form.EnableForm($('form[name="compose"]'));
return false;
}
}
]
});
});
}
function ArticleDetailsEvents() {
// Toggle article details.
$('.WidgetAction.Expand').off('click').on('click', function() {
var $WidgetObj = $(this).closest('.WidgetSimple'),
$WidgetMenu = $WidgetObj.find('.WidgetMenu'),
$WidgetMessage = $WidgetObj.find('.WidgetMessage');
if ($WidgetObj.hasClass('MenuExpanded')) {
$WidgetMenu.slideUp('fast');
$WidgetObj.removeClass('MenuExpanded');
if ($WidgetMessage.length === 1) {
$WidgetMenu.removeClass('SpacingBottom');
}
}
else {
$WidgetMenu.slideDown('fast');
$WidgetObj.addClass('MenuExpanded');
if ($WidgetMessage.length === 1) {
$WidgetMenu.addClass('SpacingBottom');
}
}
return false;
});
}
/**
* @name InitWidgets
* @memberof Core.Agent.TicketZoom
* @function
* @param {Object} AsyncWidgetActions - list of widgets to initialize
* @description
* This function initializes configured asynchronous widgets.
*/
function InitWidgets(AsyncWidgetActions) {
$.each(AsyncWidgetActions, function (ElementID, URLPart) {
Core.AJAX.ContentUpdate($('#' + ElementID), Core.Config.Get('Baselink') + URLPart, function() {
// wait for content update
$('#' + ElementID).find("a.AsPopup").on('click', function () {
var Matches,
PopupType = 'TicketAction';
Matches = $(this).attr('class').match(/PopupType_(\w+)/);
if (Matches) {
PopupType = Matches[1];
}
Core.UI.Popup.OpenPopup($(this).attr('href'), PopupType);
return false;
});
$('#' + ElementID).find('.WidgetSimple').hide().fadeIn();
Core.UI.InitWidgetActionToggle();
});
});
}
/**
* @name Init
* @memberof Core.Agent.TicketZoom
* @function
* @description
* This function initializes the special module functions.
*/
TargetNS.Init = function () {
var ZoomExpand = false,
URLHash,
$ArticleElement,
ResizeTimeoutScroller,
ArticleIndex, Index, MenuItems = Core.Config.Get('MenuItems') || [],
ArticleTableHeight = parseInt(Core.Config.Get('ArticleTableHeight'), 10),
TicketID = Core.Config.Get('TicketID'),
Count, ArticleIDs = Core.Config.Get('ArticleIDs'),
ArticleFilterDialog = parseInt(Core.Config.Get('ArticleFilterDialog'), 10),
AsyncWidgetActions = Core.Config.Get('AsyncWidgetActions') || {},
TimelineView = Core.Config.Get('TimelineView'),
ProcessWidget = Core.Config.Get('ProcessWidget');
// create open popup event for dropdown elements
if (MenuItems.length > 0) {
for (ArticleIndex in MenuItems) {
for (Index in MenuItems[ArticleIndex]) {
if (MenuItems[ArticleIndex][Index].ItemType === 'Dropdown' && MenuItems[ArticleIndex][Index].Type !== 'OnLoad') {
if (MenuItems[ArticleIndex][Index].DropdownType === 'Forward') {
TargetNS.ArticleActionMenuDropdown(MenuItems[ArticleIndex][Index].FormID, "ForwardTemplateID");
}
else if (MenuItems[ArticleIndex][Index].DropdownType === 'Reply') {
TargetNS.ArticleActionMenuDropdown(MenuItems[ArticleIndex][Index].FormID, "ResponseID");
}
}
}
}
}
// Check, if ZoomExpand is active or not.
// Only active on tickets with less than 400 articles (see bug#8424).
// Since passed value is a regular 0/1 string, make sure it's a boolean first. To do this, convert it to
// integer by performing addition on it (+) and then use double not (!!) for casting it to boolean.
// !! + "1" === false;
// !! + "0" === true;
ZoomExpand = !! + Core.Config.Get('ZoomExpand');
Core.UI.Resizable.Init($('#ArticleTableBody'), ArticleTableHeight, function (Event, UI, Height) {
// remember new height for next reload
window.clearTimeout(ResizeTimeoutScroller);
ResizeTimeoutScroller = window.setTimeout(function () {
Core.Agent.PreferencesUpdate('UserTicketZoomArticleTableHeight', Height);
}, 1000);
});
$('.DataTable tbody td a.Attachment').on('click', function (Event) {
var Position;
if ($(this).attr('rel') && $('#' + $(this).attr('rel')).length) {
Position = $(this).offset();
Core.UI.Dialog.ShowContentDialog($('#' + $(this).attr('rel'))[0].innerHTML, Core.Language.Translate('Attachments'), Position.top - $(window).scrollTop(), parseInt(Position.left, 10) + 25);
}
Event.preventDefault();
Event.stopPropagation();
return false;
});
// Table sorting
Core.UI.Table.Sort.Init($('#ArticleTable'));
// load another article, if in "show one article" mode and article id is provided by location hash
if (!ZoomExpand) {
URLHash = location.hash.replace(/#/, '');
// if URL hash is empty, set it initially to the active article for working browser history
if (URLHash === '') {
InitialArticleID = $('#ArticleTable tr.Active input.ArticleID').val();
//location.hash = '#' + $('#ArticleTable tr.Active input.ArticleID').val();
}
else {
// if article ID is found in article list (= article id is valid)
$ArticleElement = $('#ArticleTable').find('input.ArticleID[value=' + URLHash + ']');
if ($ArticleElement.length) {
// Add active state to new row
$ArticleElement.closest('table').find('tr').removeClass('Active').end().end().closest('tr').addClass('Active');
// Load content of new article
LoadArticle($ArticleElement.closest('td').find('input.ArticleInfo').val(), URLHash);
}
}
}
$('a.Timeline').on('click', function() {
$(this).attr('href', $(this).attr('href') + ';ArticleID=' + URLHash);
});
// Start asynchronous loading of widgets
InitWidgets(AsyncWidgetActions);
// loading new articles
$('#ArticleTable tbody tr').on('click', function () {
Core.App.Publish('Event.Agent.TicketZoom.ArticleClick');
// Mode: show one article - load new article via ajax
if (!ZoomExpand) {
// Add active state to new row
$(this).closest('table').find('tr').removeClass('Active').end().end().addClass('Active');
// Mark old row as readed
$(this).closest('tr').removeClass('UnreadArticles').find('span.UnreadArticles').remove();
// Load content of new article
LoadArticle($(this).find('input.ArticleInfo').val(), $(this).find('input.ArticleID').val());
// mark an article as seen
TargetNS.MarkAsSeen(TicketID, $(this).find('input.ArticleID').val());
}
// Mode: show all articles - jump to the selected article
else {
location.href = '#Article' + $(this).find('input.ArticleID').val();
}
return false;
});
// init control function to check the location hash, if the user used the history back or forward buttons
if (!ZoomExpand) {
TargetNS.CheckURLHash();
}
$('a.AsPopup').on('click', function () {
var Matches,
PopupType = 'TicketAction';
Matches = $(this).attr('class').match(/PopupType_(\w+)/);
if (Matches) {
PopupType = Matches[1];
}
Core.UI.Popup.OpenPopup($(this).attr('href'), PopupType);
return false;
});
// Scroll to active article
if (!ZoomExpand && $('#ArticleTable tbody tr.Active').length) {
$('div.Scroller').get(0).scrollTop = parseInt($('#ArticleTable tbody tr.Active').position().top, 10) - 30;
}
// init browser link message close button
if ($('.MessageBrowser').length) {
$('.MessageBrowser a.Close').on('click', function () {
$('.MessageBrowser').fadeOut("slow");
Core.Agent.PreferencesUpdate('UserAgentDoNotShowBrowserLinkMessage', 1);
return false;
});
}
// add switchable toggle
$('label.Switchable').off('click.Switch').on('click.Switch', function() {
$(this).next('p.Value').find('.Switch').toggleClass('Hidden');
});
// Mark all articles as seen, in case the expanded zoom mode is active.
if (parseInt(Core.Config.Get('TicketItemMarkAsSeen'), 10) === 1) {
TargetNS.MarkTicketAsSeen(TicketID);
}
// Otherwise, mark just visible articles as seen.
// Do this only in case the expanded zoom mode is inactive, in order to avoid potential race condition with
// the previous action. Please see bug#13657 for more information.
else {
for (Count in ArticleIDs) {
TargetNS.MarkAsSeen(TicketID, ArticleIDs[Count]);
}
}
// event on change queue
$('#DestQueueID').on('change', function () {
if ($('#DestQueueID option:selected').val()) {
$(this).closest('form').submit();
}
});
// Add event bindings to all article widgets.
ArticleDetailsEvents();
// Initialize article view settings dialog.
ArticleViewEvents();
// initialize article filter events
if (typeof ArticleFilterDialog !== 'undefined') {
ArticleFilterEvents(ArticleFilterDialog, TicketID);
}
// initialize timeline view
if (typeof TimelineView !== 'undefined' && parseInt(TimelineView.Enabled, 10) === 1) {
Core.Agent.TicketZoom.TimelineView.InitTimelineView(TimelineView);
}
// initialize events for process widget
if (typeof ProcessWidget !== 'undefined' && parseInt(ProcessWidget, 10) === 1) {
InitProcessWidget();
}
Core.App.Subscribe('Event.AJAX.ContentUpdate.Callback', function() {
$('a.SplitSelection').unbind('click.SplitSelection').bind('click.SplitSelection', function() {
Core.Agent.TicketSplit.OpenSplitSelection($(this).attr('href'));
return false;
});
});
$('a.SplitSelection').unbind('click.SplitSelection').bind('click.SplitSelection', function() {
Core.Agent.TicketSplit.OpenSplitSelection($(this).attr('href'));
return false;
});
};
Core.Init.RegisterNamespace(TargetNS, 'APP_MODULE');
return TargetNS;
}(Core.Agent.TicketZoom || {}));