"use strict"; /** * Created by viktor.shevchenko on 7/9/15. */ /** * Created by viktor.shevchenko on 7/9/15. */ /* * Recommended Tickets directive loads related Tickets to a ticket and Similar Tickets + displays them in a list with the related on top. * Very possible that tickets are just incidents, todo: verify and rename to incidents * */ angular.module('resourceModule') .directive('rsRecommendedTickets', ['searchService', 'relationModel', '$q', 'events', 'configurationModel', function (searchService, relationModel, $q, events, configurationModel) { return { require: '^rs', restrict: 'E', scope: {}, templateUrl: 'views/resource/rs-recommended-tickets.html', link: function (scope, element, attrs, rsController) { angular.extend(scope, rsController); var context = scope.context, state = { itemLimit: 4, isDataLoading: false, watchersOn: false, ticketFilterStatuses: ['all', 'open', 'resolved', 'cancelled'] }, similarItems, cssClass; state.ticketFilterSelectedStatus = state.ticketFilterStatuses[0]; scope.recommendedTickets = []; scope.statusFilter = function (resource) { if (state.ticketFilterSelectedStatus === 'all') { return true; } if (state.ticketFilterSelectedStatus === 'open') { return _.includes(['Assigned', 'In Progress', 'Pending'], resource.getStatus()); } if (resource.getStatus().toLowerCase() === state.ticketFilterSelectedStatus) { return true; } }; scope.iconClass = function (resource) { if (configurationModel.showSecurityTickets && resource.additionalInformation.serviceType === "Security Incident") { cssClass = 'icon-security-incident'; } else { cssClass = 'icon-' + resource.type; } return cssClass; }; function init() { var searchSimilarItemsParams = { query: { chunk_size: 15, need_totalcount: false }, post: { types: ['incident'], searchCompanies: context.customer ? [context.customer.company] : [{ name: context.company }], sites: context.customer ? [context.customer.site] : [], search_text: context.summary + (context.desc ? ' ' + context.desc : ''), } }; state.isDataLoading = true; $q.all([relationModel.getRelations(context.id, context.type), searchService.getGlobalSearchResults(searchSimilarItemsParams.query, searchSimilarItemsParams.post)]).then(function (responce) { scope.contextRelations = angular.copy(relationModel.cache[context.id]); if (responce[1].items[0] && responce[1].items[0].results) { similarItems = _.reject(responce[1].items[0].results, { id: context.id }); } if (!state.watchersOn) { initWatchers(); } else { populateRecommendedTickets(scope.contextRelations); } }).finally(function () { state.isDataLoading = false; }); } function populateRecommendedTickets(relatedItems) { var relatedTickets = _.chain(relatedItems) .filter({ tag: RelationItemVO.TAG_RESOURCE }) .reject(function (item) { return _.includes([EntityVO.TYPE_KNOWLEDGE, EntityVO.TYPE_OUTAGE], item.type); }).value(), /*_.filter(relatedItems, { tag: RelationItemVO.TAG_RESOURCE, type: EntityVO.TYPE_INCIDENT }) -- possibly same*/ //we use all relatedItems below in case similar is related with different relation tag like duplicateOf scenario similarNotRelatedTickets = _.reject(similarItems, function (similarItem) { return _.find(relatedItems, { id: similarItem.id }); }); scope.recommendedTickets = relatedTickets.concat(similarNotRelatedTickets); scope.$emit(events.RESOURCES_FOUND, { data: scope.recommendedTickets, type: 'tickets' }); } function initWatchers() { state.watchersOn = true; scope.$watchCollection('contextRelations', function (relatedItems) { populateRecommendedTickets(relatedItems); }, true); scope.$watchCollection('context', function (newValue, oldValue) { if (newValue.summary !== oldValue.summary || newValue.desc !== oldValue.desc) { init(); } }); } scope.context = context; scope.state = state; init(); scope.$on(events.REFRESH_RESOURCE_FEED, function () { init(); }); } }; }]);