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

240 lines
13 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',
function (ticketService, ticketModel, $state, metadataModel, $q, knowledgeArticleModel, relationModel, categoriesService, $modal, permissionModel, roles, $filter) {
return {
require: '^rs',
restrict: 'E',
replace: true,
templateUrl: 'views/resource/rs-ka-search.html',
link: function (scope, element, attrs, rsController) {
angular.extend(scope, rsController);
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];
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 () {
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) {
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,
});
});
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;
}
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();
};
function findArticles(searchData, searchOptions) {
knowledgeArticleModel.findArticleByText(searchData, searchOptions, scope.selectedSortOption).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) {
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;
$q.all([metadataModel.getMetadataByType(EntityVO.TYPE_KNOWLEDGE), knowledgeArticleModel.getKnowledgeArticleTemplates()])
.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();
}
};
}
]);