240 lines
13 KiB
JavaScript
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();
|
|
}
|
|
};
|
|
}
|
|
]);
|