570 lines
34 KiB
JavaScript
570 lines
34 KiB
JavaScript
"use strict";
|
|
(function () {
|
|
'use strict';
|
|
/**
|
|
* @ngdoc directive
|
|
* @name myitsmApp:chatWindow
|
|
* @restrict AE
|
|
* @desription Chat windows are used for user chatting. It's a draggable window which contains chat message history and
|
|
* chat controls bar. From chat window one can invite other user for a quick discussion of some issue. Also there is an option
|
|
* to relate conversation with specific app instance and save chat log to instance timeline, at the end of conversation
|
|
*/
|
|
angular.module('myitsmApp')
|
|
.directive('chatWindow', ['$filter', '$state', 'personModel', 'chatModel', 'searchModel', 'systemAlertService', '$window', 'userModel', '$timeout',
|
|
function ($filter, $state, personModel, chatModel, searchModel, systemAlertService, $window, userModel, $timeout) {
|
|
return {
|
|
restrict: 'AE',
|
|
templateUrl: 'components/chat/chat-window.html',
|
|
replace: true,
|
|
scope: {
|
|
chatRoom: "=",
|
|
isPopupWindow: "@"
|
|
},
|
|
link: function (scope, $element) {
|
|
var popupMode = !!scope.isPopupWindow;
|
|
scope.parentWindow = window.opener; //Will be null if not popup window
|
|
function parseStorageString(key, cacheString) {
|
|
var storedValue = cacheString || localStorage.getItem(key);
|
|
try {
|
|
storedValue = JSON.parse(storedValue) || [];
|
|
}
|
|
catch (e) {
|
|
storedValue = [];
|
|
}
|
|
return storedValue;
|
|
}
|
|
function onStorageEvent(storageEvent) {
|
|
if (storageEvent.key != 'app.popup.setFocusRequest' || storageEvent.newValue != scope.chatRoom.id)
|
|
return;
|
|
localStorage.setItem('app.popup.setFocusRequest', "");
|
|
console.log("Already opened");
|
|
}
|
|
if (popupMode) {
|
|
var popupsList = parseStorageString('app.popup.rooms');
|
|
popupsList.push(scope.chatRoom.id);
|
|
localStorage['app.popup.rooms'] = JSON.stringify(popupsList);
|
|
$window.document.body.style.minWidth = 0;
|
|
$window.document.body.style.overflow = "hidden";
|
|
$window.addEventListener('storage', onStorageEvent, false);
|
|
$window.onbeforeunload = function () {
|
|
var activeChatPopups = parseStorageString('app.popup.rooms'), updatedPopupsList = _.without(activeChatPopups, scope.chatRoom.id) || [];
|
|
localStorage.setItem('app.popup.rooms', JSON.stringify(updatedPopupsList));
|
|
};
|
|
}
|
|
else
|
|
$element.draggable({ containment: "parent", scroll: false, handle: ".drag-handle" });
|
|
scope.state = {
|
|
searchUserFormActive: false,
|
|
searchTicketProfileActive: false,
|
|
searchInProgress: false
|
|
};
|
|
scope.userModel = userModel;
|
|
scope.pendingSearchPromises = [];
|
|
scope.chatActions = {};
|
|
scope.searchBar = { selectedItem: null };
|
|
scope.messageEditor = { messageBody: '' };
|
|
scope.chatRoom.roster = {};
|
|
scope.headerText = "";
|
|
var textAreaElement = $element.find(".chat__message-editor");
|
|
textAreaElement.focus();
|
|
/**
|
|
* @ngdoc method
|
|
* @name myitsmApp.chatWindow#getChatParticipantsData
|
|
* @methodOf myitsmApp.chatWindow
|
|
*
|
|
* @description
|
|
* Fills chat participants with their profiles information. There are two scenarios
|
|
* of profile data retrieve - by loginId or by jid values, depending on which of two values is available
|
|
*
|
|
*/
|
|
var getChatParticipantsData = function () {
|
|
var chatProfiles = { getProfileForJids: [] };
|
|
_.each(scope.chatRoom.participants, function (participant) {
|
|
var userJID = Strophe.getNodeFromJid(participant.jid);
|
|
if (userJID != chatModel.Client.conn.authcid) {
|
|
if (chatModel.cachedProfiles[userJID] && chatModel.cachedProfiles[userJID].firstName) {
|
|
scope.chatRoom.roster[userJID] = chatModel.cachedProfiles[userJID];
|
|
}
|
|
else {
|
|
chatProfiles.getProfileForJids.push(userJID);
|
|
}
|
|
}
|
|
});
|
|
if (chatProfiles.getProfileForJids.length) {
|
|
chatModel.getUserProfileByJID(chatProfiles.getProfileForJids).then(function () {
|
|
_.each(chatProfiles.getProfileForJids, function (jid) {
|
|
scope.chatRoom.roster[jid] = chatModel.cachedProfiles[jid];
|
|
});
|
|
});
|
|
}
|
|
};
|
|
/*Watching, when participants list changes*/
|
|
scope.$watch(function () {
|
|
return scope.chatRoom.participants;
|
|
}, function (newValue) {
|
|
if (newValue) {
|
|
getChatParticipantsData();
|
|
}
|
|
});
|
|
/*Watching, when user adds text in search input*/
|
|
scope.$watch('searchBar.searchParam', function (newVal, oldVal) {
|
|
if (newVal && (newVal != oldVal)) {
|
|
scope.searchBar.handleUserQuery();
|
|
}
|
|
if (oldVal && !newVal) {
|
|
scope.pendingSearchPromises = [];
|
|
scope.state.searchInProgress = false;
|
|
scope.searchBar.resultsList = null;
|
|
}
|
|
});
|
|
/*Generates participants string, to show on chat window header*/
|
|
scope.generateChatHeaderCaption = function () {
|
|
if (scope.chatRoom.generateRosterSummary) {
|
|
return scope.chatRoom.generateRosterSummary();
|
|
}
|
|
var profilesList = _.toArray(scope.chatRoom.roster), namesArray = _.map(scope.chatRoom.roster, function (profile) {
|
|
if (profilesList.length < 3) {
|
|
return profile.fullName || profile.displayName;
|
|
}
|
|
return profile.firstName;
|
|
});
|
|
return namesArray.length > 0 ? namesArray.join(", ") : $filter('i18n')('chat.header.generic');
|
|
};
|
|
/*List of available chat window actions*/
|
|
if (window.isRtl) {
|
|
scope.chatControls = [
|
|
{ label: 'Minimize Chat', iconClass: 'glyphicon glyphicon-minus', name: 'minimize', disabled: scope.isPopupWindow },
|
|
{ label: 'Popin Chat', iconClass: 'icon-pop_in', name: 'popinChatWindow', disabled: !scope.isPopupWindow || scope.parentWindow && scope.parentWindow.closed },
|
|
{ label: 'Popout Chat', iconClass: 'icon-pop_up', name: 'popoutChatWindow', disabled: scope.isPopupWindow },
|
|
{ label: 'Invite User', iconClass: 'icon-user_plus', name: 'showSearchForm', args: 'invite' },
|
|
{ label: 'Leave Chat', iconClass: 'icon-exit', name: 'leaveChat' }
|
|
];
|
|
}
|
|
else {
|
|
scope.chatControls = [
|
|
{ label: 'Leave Chat', iconClass: 'icon-exit', name: 'leaveChat' },
|
|
{ label: 'Invite User', iconClass: 'icon-user_plus', name: 'showSearchForm', args: 'invite' },
|
|
{ label: 'Popout Chat', iconClass: 'icon-pop_up', name: 'popoutChatWindow', disabled: scope.isPopupWindow },
|
|
{ label: 'Popin Chat', iconClass: 'icon-pop_in', name: 'popinChatWindow', disabled: !scope.isPopupWindow || scope.parentWindow && scope.parentWindow.closed },
|
|
{ label: 'Minimize Chat', iconClass: 'glyphicon glyphicon-minus', name: 'minimize', disabled: scope.isPopupWindow }
|
|
];
|
|
}
|
|
scope.redirectToAsignedItem = function () {
|
|
var relatedObject = scope.chatRoom.parent, url;
|
|
if (!relatedObject) {
|
|
return false;
|
|
}
|
|
if (relatedObject.ticketType == EntityVO.TYPE_ASSET) {
|
|
if (scope.isPopupWindow) {
|
|
url = $state.href(EntityVO.TYPE_ASSET, { assetId: relatedObject.reconciliationId, assetClassId: relatedObject.classId });
|
|
window.open(url, "_blank");
|
|
return;
|
|
}
|
|
$state.go(EntityVO.TYPE_ASSET, { assetId: relatedObject.reconciliationId, assetClassId: relatedObject.classId });
|
|
}
|
|
else {
|
|
if (scope.isPopupWindow) {
|
|
url = $state.href(relatedObject.type, { id: relatedObject.id });
|
|
window.open(url, "_blank");
|
|
return;
|
|
}
|
|
$state.go(relatedObject.type, { id: relatedObject.id });
|
|
}
|
|
};
|
|
/*Sets proper class for chat controls icon*/
|
|
scope.getConditionalClasses = function (control) {
|
|
if (!chatModel.connected && control.name !== 'minimize') {
|
|
return 'chat-disable-events';
|
|
}
|
|
if (control.name == 'showSearchForm') {
|
|
return scope.state.searchUserFormActive ? 'active' : angular.noop();
|
|
}
|
|
};
|
|
/*Chat controls click event transmitter. Uses controls item, to execute applicable click handler */
|
|
scope.handleChatControlsClick = function ($e, action) {
|
|
if (scope.chatRoom.inactiveRoom)
|
|
return false;
|
|
return scope.chatActions[action.name](action.args);
|
|
};
|
|
/*Removes chat window relation to app instance, if one was specified*/
|
|
scope.removeChatAssignment = function () {
|
|
scope.chatRoom.loadingAssignments = true;
|
|
chatModel.removeChatAssignment(scope.chatRoom.room).finally(function () {
|
|
scope.chatRoom.loadingAssignments = false;
|
|
});
|
|
};
|
|
scope.chatActions.popoutChatWindow = function () {
|
|
var activeChatPopupsList = localStorage.getItem('app.popup.rooms') || "[]", popupURL = '#/chatPopupWindow';
|
|
if (activeChatPopupsList.indexOf(scope.chatRoom.id) >= 0) {
|
|
localStorage.setItem('app.popup.setFocusRequest', scope.chatRoom.id);
|
|
scope.chatActions.minimize();
|
|
return;
|
|
}
|
|
$window.popupDetails = { roomId: scope.chatRoom.id };
|
|
var minWidth = 400, minHeight = 500, width = Math.round((screen.width / 3) / 10) * 10, height = Math.round(screen.height * 70 / 100), popupHeight = _.max([minHeight, height]), popupWidth = _.max([minWidth, width]), popupName = "chatPopup_" + (Strophe.getNodeFromJid(scope.chatRoom.id) || "").split("-").join("_"), popupParams = "location=no, scrollbars=no, resizable=yes, width=" + popupWidth + ", height=" + popupHeight, popup = $window.open(popupURL, popupName, popupParams);
|
|
popup.focus();
|
|
scope.chatActions.minimize();
|
|
};
|
|
scope.chatActions.popinChatWindow = function () {
|
|
var parentScope, activeChatRoom;
|
|
if (scope.parentWindow.closed)
|
|
return;
|
|
try {
|
|
parentScope = scope.parentWindow.angular.element('body').scope();
|
|
activeChatRoom = _.find(parentScope.chatModel.activeChatRooms, { id: scope.chatRoom.id });
|
|
}
|
|
catch (e) { }
|
|
if (parentScope && activeChatRoom) {
|
|
parentScope.$apply(function () {
|
|
activeChatRoom.isOpened = true;
|
|
});
|
|
window.close();
|
|
}
|
|
};
|
|
/*Minimizes chat window */
|
|
scope.chatActions.minimize = function () {
|
|
scope.chatRoom.isOpened = false;
|
|
};
|
|
/**
|
|
* @ngdoc method
|
|
* @name myitsmApp.chatWindow#leaveChat
|
|
* @methodOf myitsmApp.chatWindow
|
|
*
|
|
* @description
|
|
* Action can be triggered from chat controls, by clicking leave chat button. It prompts
|
|
* confirmation modal with available actions based on user privileges within the chat
|
|
* If chat creator leaves chat it will lead to destroy of the chat windows for all participants
|
|
* Also owner can save chat log to a timeline of related app instance, if one was selected
|
|
*
|
|
*/
|
|
scope.chatActions.leaveChat = function () {
|
|
if (scope.chatRoom.isLoading)
|
|
return;
|
|
var nick = Strophe.escapeNode(scope.chatRoom.room.nick), affiliation = scope.chatRoom.participants[nick].affiliation, modalSettings;
|
|
var modalText = $filter('i18n')('chat.participantLeave.modal.confirmAction.leave'), modalConfirm = { leave: true };
|
|
if (affiliation == 'owner') {
|
|
if (scope.chatRoom.parent) {
|
|
modalText = $filter('i18n')('chat.ownerLeave.modal.confirmAction.saveLog');
|
|
modalConfirm = { save: true };
|
|
}
|
|
else {
|
|
modalText = $filter('i18n')('chat.ownerLeave.modal.confirmAction.leave');
|
|
modalConfirm = { close: true };
|
|
}
|
|
}
|
|
modalSettings = {
|
|
title: $filter('i18n')('chat.ownerLeave.modal.title'),
|
|
text: modalText,
|
|
buttons: [
|
|
{
|
|
text: $filter('i18n')('common.labels.leave'),
|
|
data: modalConfirm
|
|
},
|
|
{
|
|
text: $filter('i18n')('common.button.cancel')
|
|
}
|
|
],
|
|
isPopoutWindow: true
|
|
};
|
|
var modalInstance = systemAlertService.modal(modalSettings);
|
|
modalInstance.result.then(function (data) {
|
|
if (!_.isEmpty(data)) {
|
|
var userAction = data ? (data.save ? 'saveLog' : 'destroyRoom') : 'leave';
|
|
if (scope.isPopupWindow) {
|
|
var parentScope, activeChatRoom;
|
|
try {
|
|
parentScope = scope.parentWindow.angular.element('body').scope();
|
|
activeChatRoom = _.find(parentScope.chatModel.activeChatRooms, { id: scope.chatRoom.id });
|
|
if (parentScope && activeChatRoom) {
|
|
parentScope.$apply(function () {
|
|
activeChatRoom.isOpened = false;
|
|
(userAction == 'saveLog') && parentScope.chatModel.saveChatLogToTicketWorknote(activeChatRoom, activeChatRoom.parent);
|
|
(userAction != 'leave') && parentScope.chatModel.leaveRoomAndDestroyChatWindow(activeChatRoom);
|
|
(userAction == 'leave') && parentScope.chatModel.leaveConversation(activeChatRoom);
|
|
});
|
|
}
|
|
}
|
|
catch (e) { }
|
|
window.close();
|
|
}
|
|
else {
|
|
scope.chatRoom.isOpened = false;
|
|
(userAction == 'saveLog') && chatModel.saveChatLogToTicketWorknote(scope.chatRoom, scope.chatRoom.parent);
|
|
(userAction != 'leave') && chatModel.leaveRoomAndDestroyChatWindow(scope.chatRoom);
|
|
(userAction == 'leave') && chatModel.leaveConversation(scope.chatRoom);
|
|
}
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* @ngdoc method
|
|
* @name myitsmApp.chatWindow#showSearchForm
|
|
* @methodOf myitsmApp.chatWindow
|
|
*
|
|
* @description
|
|
* Shows search bar to the user, when one clicks invite person button or relate chat link. Controls search context,
|
|
* based clicked item.
|
|
*
|
|
*/
|
|
scope.chatActions.showSearchForm = function (type) {
|
|
if (scope.chatRoom.isLoading)
|
|
return;
|
|
if (type == 'connect') {
|
|
scope.searchBar.clearSelection();
|
|
scope.state.searchTicketProfileActive = true;
|
|
scope.state.searchUserFormActive = false;
|
|
}
|
|
else if (type == 'invite') {
|
|
if (!scope.state.searchUserFormActive) {
|
|
scope.searchBar.searchParam = null;
|
|
scope.searchBar.clearSelection();
|
|
scope.state.searchUserFormActive = true;
|
|
scope.state.searchTicketProfileActive = false;
|
|
scope.filteredList = [];
|
|
}
|
|
else {
|
|
scope.searchBar.clearSelection();
|
|
scope.state.searchUserFormActive = false;
|
|
}
|
|
}
|
|
$timeout(function () {
|
|
try {
|
|
$element.find("[ng-model*='searchParam']")[0].focus();
|
|
}
|
|
catch (ex) { }
|
|
}, 500);
|
|
};
|
|
scope.searchBar.suggestionMouseOver = function (index) {
|
|
var hoveredItem = scope.filteredList[index];
|
|
if (scope.state.searchUserFormActive && hoveredItem.active != EntityVO.CHAT_STATUS_ONLINE) {
|
|
return false;
|
|
}
|
|
scope.searchBar.alignWithTop = null;
|
|
scope.searchBar.selectedSuggestionIndex = index;
|
|
};
|
|
/*Keydown event handler for search input. Clears and hides search input when Esc is pressed*/
|
|
scope.searchBar.checkPressedKey = function ($event) {
|
|
var keyCode = $event.keyCode || $event.which;
|
|
if (keyCode == 27) {
|
|
scope.searchBar.clearSelection();
|
|
scope.state.searchUserFormActive = false;
|
|
scope.state.searchTicketProfileActive = false;
|
|
}
|
|
if (keyCode == 13) {
|
|
$event.preventDefault();
|
|
var selectedItem = scope.filteredList[scope.searchBar.selectedSuggestionIndex];
|
|
if (!selectedItem || (scope.state.searchUserFormActive && selectedItem.available != EntityVO.CHAT_STATUS_ONLINE)) {
|
|
return false;
|
|
}
|
|
else {
|
|
scope.searchBar.selectSuggestion(selectedItem);
|
|
}
|
|
}
|
|
if (keyCode == 38 || keyCode == 40) {
|
|
if (scope.state.searchUserFormActive || scope.state.searchTicketProfileActive && scope.filteredList && scope.searchBar.resultsList.length > 0) {
|
|
$event.preventDefault();
|
|
if (keyCode == 38) {
|
|
if (scope.searchBar.selectedSuggestionIndex == 0)
|
|
return false;
|
|
else {
|
|
scope.searchBar.alignWithTop = true;
|
|
scope.searchBar.selectedSuggestionIndex--;
|
|
}
|
|
return false;
|
|
}
|
|
else {
|
|
if (scope.searchBar.selectedSuggestionIndex == scope.filteredList.length - 1)
|
|
return false;
|
|
else {
|
|
var nextIndex = scope.searchBar.selectedSuggestionIndex + 1, nextItem = scope.filteredList[nextIndex];
|
|
if (scope.state.searchUserFormActive && nextItem && nextItem.available != EntityVO.CHAT_STATUS_ONLINE)
|
|
return false;
|
|
else {
|
|
scope.searchBar.alignWithTop = false;
|
|
scope.searchBar.selectedSuggestionIndex++;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
};
|
|
/**
|
|
* Handles user search text input and executes server request to retrieve user profiles or instance list, if search text
|
|
* pass length check
|
|
* */
|
|
scope.searchBar.handleUserQuery = function () {
|
|
var query = scope.searchBar.searchParam;
|
|
if (scope.searchBar.selectedItem) {
|
|
return;
|
|
}
|
|
if (!query) {
|
|
scope.searchBar.selectedSuggestionIndex = 0;
|
|
scope.searchBar.resultsList = [];
|
|
scope.filteredList = [];
|
|
return;
|
|
}
|
|
if (query.length >= 3) {
|
|
scope.searchBar.selectedSuggestionIndex = 0;
|
|
scope.state.searchInProgress = true;
|
|
scope.getSearchResultsDebounce(query);
|
|
}
|
|
else {
|
|
scope.searchBar.resultsList = [];
|
|
scope.filteredList = [];
|
|
}
|
|
};
|
|
/*Controls placeholder value, based on context of search, selected by user*/
|
|
scope.searchBar.getSearchBarPlaceholder = function () {
|
|
if (scope.state.searchUserFormActive) {
|
|
return $filter('i18n')('chat.searchBar.userSearch.placeholder');
|
|
}
|
|
else if (scope.state.searchTicketProfileActive) {
|
|
return $filter('i18n')('chat.searchBar.ticketProfile.placeholder');
|
|
}
|
|
};
|
|
/*
|
|
* Handles item selection from suggestions list, returned from the server.
|
|
* Fills search input with selected value. Next step should be confirmation or cancel
|
|
* of selection
|
|
* */
|
|
scope.searchBar.selectSuggestion = function (item) {
|
|
if (item.hasOwnProperty('firstName') || item.hasOwnProperty('loginId')) {
|
|
var available = item.available ? item.available.toLowerCase() : EntityVO.CHAT_STATUS_OFFLINE;
|
|
if (available != EntityVO.CHAT_STATUS_ONLINE) {
|
|
return;
|
|
}
|
|
}
|
|
scope.searchBar.selectedItem = item;
|
|
scope.searchBar.confirmSelection();
|
|
$timeout(function () {
|
|
try {
|
|
$element.find(".chat__search-bar_confirm-action")[0].focus();
|
|
}
|
|
catch (ex) { }
|
|
}, 500);
|
|
};
|
|
/*Cancels suggested item selction*/
|
|
scope.searchBar.clearSelection = function () {
|
|
scope.searchBar.selectedItem = null;
|
|
scope.searchBar.searchParam = '';
|
|
scope.searchBar.resultsList = [];
|
|
};
|
|
/**
|
|
* Confirms selection and based on context
|
|
* relate chat to app instance or invites user to chat
|
|
*/
|
|
scope.searchBar.confirmSelection = function () {
|
|
if (scope.state.searchUserFormActive) {
|
|
scope.chatRoom.roster[scope.searchBar.selectedItem.jid] = scope.searchBar.selectedItem;
|
|
chatModel.inviteUserToChat(scope.searchBar.selectedItem, scope.chatRoom);
|
|
scope.state.searchUserFormActive = false;
|
|
}
|
|
else {
|
|
chatModel.assignChatRoom(scope.chatRoom.room, scope.searchBar.selectedItem);
|
|
scope.chatRoom.parent = scope.searchBar.selectedItem;
|
|
scope.state.searchTicketProfileActive = false;
|
|
}
|
|
scope.searchBar.clearSelection();
|
|
};
|
|
/*Used in ngRepeat as sorting function in suggestions list of invitees*/
|
|
scope.sortResults = function (item) {
|
|
if (scope.state.searchUserFormActive) {
|
|
!!item.available ? item.available = item.available.toLowerCase() : item.available = EntityVO.CHAT_STATUS_OFFLINE;
|
|
var statusIndex = chatModel.Client.options.users_status_list.indexOf(item.available);
|
|
return statusIndex + (item.fullName || item.firstName + " " + item.lastName);
|
|
}
|
|
};
|
|
/*Debounce function, which runs request to a server to get profiles or instances matching
|
|
* user search criteria.
|
|
* It will execute server request only when user stops typing or makes a pause in typing equal to 400 ms
|
|
* Data returned from server will be used to build suggestions list.
|
|
* */
|
|
scope.getSearchResultsDebounce = _.debounce(function (query) {
|
|
var promise;
|
|
if (scope.state.searchUserFormActive) {
|
|
promise = personModel.getListOfPersonByName(query)
|
|
.then(function (profiles) {
|
|
chatModel.updateCachedProfiles(profiles);
|
|
scope.filteredList = [];
|
|
if (scope.searchBar.searchParam && !scope.searchBar.selectedItem && scope.state.searchUserFormActive) {
|
|
var participants = scope.chatRoom.getParticipantJIDsArray();
|
|
scope.searchBar.resultsList = _.filter(profiles, function (profile) {
|
|
var currentUserMatch = (chatModel.currentUser.loginId == profile.loginId);
|
|
if (profile.jid) {
|
|
var chatParticipant = (participants.indexOf(profile.jid) >= 0);
|
|
}
|
|
return !chatParticipant && !currentUserMatch;
|
|
});
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
var filters = { types: [EntityVO.TYPE_INCIDENT, EntityVO.TYPE_WORKORDER, EntityVO.TYPE_SERVICEREQUEST, EntityVO.TYPE_TASK, EntityVO.TYPE_ASSET, EntityVO.TYPE_CHANGE, EntityVO.TYPE_KNOWNERROR, EntityVO.TYPE_PROBLEM, EntityVO.TYPE_RELEASE] };
|
|
promise = searchModel.getGlobalSearchResults(query, filters)
|
|
.then(function () {
|
|
if (scope.pendingSearchPromises.length == 0) {
|
|
return;
|
|
}
|
|
if (scope.searchBar.searchParam && !scope.searchBar.selectedItem && scope.state.searchTicketProfileActive) {
|
|
if (searchModel.globalSearchResults.totalCount > 0) {
|
|
scope.searchBar.resultsList = [];
|
|
var matchedItems = searchModel.globalSearchResults.items;
|
|
_.each(matchedItems, function (item) {
|
|
scope.searchBar.resultsList = scope.searchBar.resultsList.concat(item.results);
|
|
});
|
|
}
|
|
else {
|
|
scope.searchBar.resultsList = [];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
scope.pendingSearchPromises.push(promise);
|
|
promise.finally(function () {
|
|
var promiseIndex = scope.pendingSearchPromises.indexOf(promise);
|
|
if (promiseIndex >= 0) {
|
|
scope.pendingSearchPromises.splice(promiseIndex, 1);
|
|
}
|
|
if (scope.pendingSearchPromises.length == 0) {
|
|
scope.state.searchInProgress = false;
|
|
}
|
|
});
|
|
}, 400);
|
|
scope.tools = function () {
|
|
chatModel.processChatMessage(EntityVO.CHATOPS_TOOLS, scope.chatRoom);
|
|
};
|
|
/*
|
|
* keypress event handler, which looks for enter button click and sends
|
|
* new chat message, if shift button is not active
|
|
* */
|
|
scope.messageEditor.handleTyping = function ($event) {
|
|
var keyCode = $event.which || $event.keyCode;
|
|
if (keyCode == 13 && !$event.shiftKey && scope.messageEditor.messageBody) {
|
|
var messageText = scope.messageEditor.messageBody;
|
|
if (scope.chatRoom.parent != null && scope.chatRoom.parent.type == 'incident') {
|
|
var chatR = scope.chatRoom;
|
|
if (messageText == EntityVO.CHATOPS_DETAILS || messageText == EntityVO.CHATOPS_KNOWLEDGE
|
|
|| messageText == EntityVO.CHATOPS_SIMILARINCIDENTS || messageText == EntityVO.CHATOPS_SWARM || messageText == EntityVO.CHATOPS_TOOLS) { // chatModel.sendChatMessage(scope.messageEditor.messageBody, scope.chatRoom.room);
|
|
chatModel.processChatMessage(messageText, chatR);
|
|
}
|
|
else {
|
|
chatModel.sendChatMessage(scope.messageEditor.messageBody, scope.chatRoom.room);
|
|
}
|
|
}
|
|
else {
|
|
chatModel.sendChatMessage(scope.messageEditor.messageBody, scope.chatRoom.room);
|
|
}
|
|
scope.messageEditor.messageBody = '';
|
|
$event.preventDefault();
|
|
}
|
|
};
|
|
scope.isChatEnabled = function () {
|
|
return chatModel.connected;
|
|
};
|
|
}
|
|
};
|
|
}]);
|
|
}());
|