SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/resource/rs-ka-search.js

304 lines
16 KiB
JavaScript

"use strict";
/**
* Created by viktor.shevchenko on 7/21/15.
*/
angular.module('resourceModule')
.directive('rsKaSearch', ['ticketService', 'ticketModel', '$state', 'metadataModel', '$q', 'knowledgeArticleModel', 'relationModel', 'categoriesService', '$modal', 'permissionModel', 'roles', '$filter', 'configurationModel', 'events', 'searchModel',
function (ticketService, ticketModel, $state, metadataModel, $q, knowledgeArticleModel, relationModel, categoriesService, $modal, permissionModel, roles, $filter, configurationModel, events, searchModel) {
return {
require: '^rs',
restrict: 'E',
replace: true,
templateUrl: 'views/resource/rs-ka-search.html',
link: function (scope, element, attrs, rsController) {
angular.extend(scope, rsController);
scope.comaroundEnabled = configurationModel.comaroundEnabled;
//After manual refresh of ticket rsController context is not getting updated.
if (scope.context.type !== EntityVO.TYPE_KNOWLEDGE && ticketModel.cache[scope.context.id]) {
scope.context = ticketModel.cache[scope.context.id];
}
else if (knowledgeArticleModel.articles[scope.context.id]) {
scope.context = knowledgeArticleModel.articles[scope.context.id];
}
var state = {
processing: false,
searching: false,
searchNotFound: false,
watcherOn: false,
optionIsCollapsed: true,
canCreateKnowledge: permissionModel.hasPermission(roles.ITSM_KNOWLEDGE_USER_ROLE) && !scope.context.isDraft && scope.context.accessMappings.relationsEditAllowed
}, searchItems = [];
scope.articlePlaceholder = {
type: EntityVO.TYPE_KNOWLEDGE,
allCategories: [],
customer: {},
summary: '',
allCompanies: []
};
scope.titleRegExp = new RegExp(/.{1,5}/g);
if (scope.context.type === EntityVO.TYPE_SMARTRECORDER) {
scope.articlePlaceholder.customer.company = { name: scope.context.company };
}
else if (scope.context.type === EntityVO.TYPE_PROBLEM || scope.context.type === EntityVO.TYPE_KNOWNERROR) {
scope.articlePlaceholder.customer.company = scope.context.company;
}
else if (scope.context.customer && scope.context.customer.company) {
scope.articlePlaceholder.customer.company = scope.context.customer.company;
}
else {
scope.articlePlaceholder.customer.company = scope.context.customer || scope.context.company;
}
scope.contextRelations = relationModel.cache[scope.context.id];
scope.companyState = {
selected: true,
showFilter: configurationModel.showFilterForRecommendedKnowledge
};
if (scope.context.type === EntityVO.TYPE_KNOWLEDGE) {
scope.articlePlaceholder.allCompanies = scope.context.allCompanies;
//SW00512025 - passing All even if its not a selected company for this KA
if (!_.find(scope.articlePlaceholder.allCompanies, { name: 'All' })) {
scope.articlePlaceholder.allCompanies.push({ name: 'All' });
}
}
else {
scope.articlePlaceholder.allCompanies.push({ name: 'All' });
scope.articlePlaceholder.allCompanies.push(scope.articlePlaceholder.customer.company);
}
scope.toggleOptions = function () {
state.optionIsCollapsed = !state.optionIsCollapsed;
};
scope.createNewArticle = function () {
if (scope.comaroundEnabled) {
searchModel.getHKMUrls().then(function (urls) {
if (urls.createUrl) {
urls.createUrl = decodeURI(urls.createUrl);
window.open(urls.createUrl, '_blank');
}
});
}
else {
ticketModel.articleParent = scope.context;
var modalInstance = $modal.open({
templateUrl: 'views/create/create-ka.html',
controller: 'CreateKnowledgeArticleModalController',
windowClass: 'modal_full-content',
backdrop: false,
keyboard: false
});
modalInstance.result.then(function (article) {
scope.$emit(events.TICKET_PROFILE_RESEND_EVENT, { eventName: events.TICKET_SHOW_LOADER });
var newResource = new RelationItemVO().build({
id: article.id,
displayId: article.articleId,
title: article.title,
desc: article.title,
type: article.type,
additionalInformation: {
modifiedDate: article.modifiedDate
},
tag: EntityVO.TYPE_RESOURCE,
relationshipType: EntityVO.TYPE_RELATEDTO,
realObject: {
status: article.status,
version: article.version,
modifiedDate: article.modifiedDate
}
});
scope.saveToTicket(newResource).then(function () {
$state.go(newResource.type, {
id: newResource.id
});
}).finally(function () {
scope.$emit(events.TICKET_PROFILE_RESEND_EVENT, { eventName: events.TICKET_HIDE_LOADER });
});
scope.toggleSearchKa();
});
}
};
scope.setSortOption = function (option) {
scope.selectedSortOption = option;
scope.searchArticle();
};
scope.changeStatusOption = function (status) {
scope.statusOptions = status;
};
scope.changeSourceOption = function (source) {
scope.sourceOptions = source;
};
scope.searchArticle = function () {
if (state.searching) {
return;
}
state.searching = true;
scope.searchResults = [];
state.searchNotFound = false;
knowledgeArticleModel.clearVisitedArticlesForTicket(scope.context.id);
var searchData = {
search_text: scope.articlePlaceholder.summary,
suggest_search: true,
chunk_index: 0,
chunk_size: 15
}, searchOptions = {}, categoryList = scope.articlePlaceholder.allCategories;
if (scope.statusOptions) {
searchOptions.statuses = [{ value: scope.statusOptions.name }];
}
if (scope.sourceOptions) {
searchOptions.source = scope.sourceOptions.name;
}
if (scope.companyState.showFilter && scope.companyState.selected) {
var companyList = fetchContextCompany();
if (companyList) {
searchOptions.searchCompanies = companyList;
}
}
searchOptions.category = [];
_.each(categoryList, function (category) {
if (category.listOfTiers[0] && category.listOfTiers[0].selectedValue) {
var categoryData = {};
categoryData.name = category.name;
categoryData.tiers = {};
_.each(category.listOfTiers, function (tier) {
categoryData.tiers[tier.name] = tier.selectedValue ? tier.selectedValue : '';
});
searchOptions.category.push(categoryData);
}
});
findArticles(searchData, searchOptions);
scope.searchData = searchData;
scope.searchOptions = searchOptions;
!state.watcherOn && initWatch();
};
scope.getTicketLabel = function () {
return $filter('i18n')('ticket.type.' + scope.context.type);
};
function fetchContextCompany() {
var companies = [{ name: 'All' }];
if (scope.context.type === EntityVO.TYPE_KNOWLEDGE && scope.context.company && scope.context.company.name === 'All') {
return companies;
}
if (scope.context.type === EntityVO.TYPE_KNOWLEDGE || scope.context.type === EntityVO.TYPE_PROBLEM || scope.context.type === EntityVO.TYPE_KNOWNERROR) {
companies.push(scope.context.company);
}
else {
companies.push(scope.context.customer ? scope.context.customer.company : { name: scope.context.company });
}
return companies;
}
function findArticles(searchData, searchOptions) {
var searchPromise;
if (configurationModel.comaroundEnabled) {
var params = { search_text: searchData.search_text };
if (searchOptions.category && searchOptions.category.length) {
params.category = searchOptions.category;
}
searchPromise = knowledgeArticleModel.getHKMRecommendedKA(searchData, params);
}
else {
searchPromise = knowledgeArticleModel.findArticleByText(searchData, searchOptions, scope.selectedSortOption);
}
searchPromise.then(function (articles) {
searchItems = _.filter(articles, function (article) {
return scope.context.id !== article.id;
});
populateArticles(scope.contextRelations);
}).finally(function () {
state.searching = false;
});
}
function populateArticles(relatedItems) {
if (!searchItems || !searchItems.length) {
state.searchNotFound = true;
return;
}
var relatedArticles = _.filter(relatedItems, function (relatedItem) {
return _.find(searchItems, { id: relatedItem.id });
}), notRelatedArticles = _.reject(searchItems, function (searchItem) {
return _.find(relatedArticles, { id: searchItem.id });
});
scope.searchResults = relatedArticles.concat(notRelatedArticles);
if (scope.context.type !== EntityVO.TYPE_KNOWLEDGE) {
checkForVisitedArticles(scope.searchResults);
}
}
function initWatch() {
scope.$watchCollection('contextRelations', function (relatedItems) {
if (!state.watcherOn) {
state.watcherOn = true;
return; //Code below shouldn't run when initializing the watch
}
if (relationModel.unlinked.length && rsController.isKaSearchEnabled()) { //Case : Article is unlinked and advanced search articles screen
relationModel.unlinked.length = 0;
findArticles(scope.searchData, scope.searchOptions);
return;
}
populateArticles(relatedItems);
}, true);
}
scope.clearSearch = function () {
scope.articlePlaceholder.summary = '';
scope.searchResults = [];
searchItems.length = 0;
state.searchNotFound = false;
};
//Knowledge status is not getting populated when using filter in html in case of browser refresh because metadataModel.cache doesn't fetch value at that time.
scope.localizedStatus = function (status) {
if (scope.comaroundEnabled) {
return $filter('i18n')('hkm.status.' + status);
}
else {
return $filter('localizeLabel')(status, 'status', 'knowledge');
}
};
function checkForVisitedArticles(searchResults) {
var visitedArticlesList = knowledgeArticleModel.getVisitedArticlesForTicket(scope.context.id);
searchResults.some(function (article) {
article.visited = false;
return article instanceof GlobalSearchItemVO; //RelationItemVO are taken from cache so marking only them false.
});
if (!_.isEmpty(visitedArticlesList)) {
_.forEach(searchResults, function (article) {
article.visited = _.includes(visitedArticlesList, article.id);
});
}
}
function init() {
scope.clearSearch();
scope.state = state;
scope.itemsLimit = 4;
scope.sortOptions = [
{ name: 'mostRelevant', sortFieldName: '', sortFieldOrder: '' },
{ name: 'mostFavorite', sortFieldName: 'favorite', sortFieldOrder: 'des' },
{ name: 'mostRecent', sortFieldName: 'modifiedDate', sortFieldOrder: 'des' }
];
scope.selectedSortOption = scope.sortOptions[0];
state.processing = true;
var articleTemplatePromise = scope.comaroundEnabled ? $q.when([]) : knowledgeArticleModel.getKnowledgeArticleTemplates();
$q.all([metadataModel.getMetadataByType(EntityVO.TYPE_KNOWLEDGE), articleTemplatePromise])
.then(function (result) {
var metaData = result[0];
var categorizations = [
{
name: 'operational',
tiers: {}
},
{
name: 'product',
tiers: {}
}
];
scope.availableStatuses = metaData.statuses ? metaData.statuses.slice() : [];
// remove work in progress status since it is not supported by backend MTF search
_.remove(scope.availableStatuses, { name: 'Work In Progress' });
scope.articlePlaceholder.allCategories = _.cloneDeep(categoriesService.populateCategories(categorizations, metaData));
scope.availableSources = result[1];
})
.finally(function () {
state.processing = false;
});
}
init();
}
};
}
]);