SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/create/create-ka-controller.js

434 lines
22 KiB
JavaScript

"use strict";
/**
* Created by viktor.shevchenko on 12/10/2014.
*/
(function () {
'use strict';
angular.module('createTicketModule')
.controller('CreateKnowledgeArticleController', ['$scope', 'localStorageService', '$modal', 'searchService', 'relationModel',
'$state', '$timeout', 'systemAlertService', 'attachmentService', 'metadataModel', 'categoriesService',
'knowledgeArticleModel', 'ticketModel', '$q', '$filter', 'configurationModel',
function ($scope, localStorageService, $modal, searchService, relationModel, $state, $timeout, systemAlertService, attachmentService, metadataModel, categoriesService, knowledgeArticleModel, ticketModel, $q, $filter, configurationModel) {
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_KNOWLEDGE)) {
$state.go('unauthorized');
return;
}
$scope.editMode = true; //flag that is used for category directive
var article = {}, metadata, knowledgeTitleChangeTimer, state = {}, localStorageDefaultTemplateKey = 'DEFAULT_KA_TEMPLATE', currentUserId = localStorageService.get('user.userId'), savedTemplate = localStorageService.get(localStorageDefaultTemplateKey), defaultTemplateId = (savedTemplate && (savedTemplate.user === currentUserId)) ? savedTemplate.templateId : null, localStorageLastVisibilitySetKey = 'LAST_SET_OF_VISIBILITY_GROUPS', draftArticle = {};
setInitialState();
loadAvailableTemplates().then(function () {
if (defaultTemplateId) {
$scope.selectedTemplate = _.find($scope.templates, { id: defaultTemplateId });
loadDraftData().then(function () {
state.isTemplateSelected = true;
state.isTemplateAccepted = true;
});
}
});
function setInitialState() {
state = angular.extend(state, {
dataIsLoading: false,
isTemplateSelected: false,
isTemplateAccepted: false,
rememberTemplate: false,
showMetadata: true,
loadingMergeWindow: false,
showingMergeTool: false,
similarArticles: [],
showSimilarArticles: false,
loadVisibility: false,
loadingSimilarArticles: false,
similarArticlePromise: null,
allowStateChange: false
});
$scope.attachments = [];
$scope.linkedItems = [];
$scope.titleMaxLength = 4000;
}
function loadAvailableTemplates() {
state.dataIsLoading = true;
return knowledgeArticleModel.getKnowledgeArticleTemplates().then(function (templates) {
$scope.templates = angular.copy(templates);
_.remove($scope.templates, { name: 'Decision Tree' });
return templates;
}).finally(function () {
state.dataIsLoading = false;
});
}
function loadDraftData() {
var metaDataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_KNOWLEDGE), kaDraftPromise = knowledgeArticleModel.getDraft($scope.selectedTemplate.id, $scope.articleContext), globalMetadataPromise = metadataModel.getMetadataByType(EntityVO.TYPE_GLOBAL);
state.dataIsLoading = true;
return $q.all([metaDataPromise, kaDraftPromise, globalMetadataPromise]).then(function (result) {
metadata = result[0];
angular.extend(article, result[1]);
$scope.knowledgeAnchorParser = result[2].configurationParameters.knowledgeAnchorParser;
$scope.article.categoriesControls = _.cloneDeep(categoriesService.populateCategories($scope.article.defaultCategorization, metadata));
$scope.article.categoriesSet = _.cloneDeep(categoriesService.populateMultipleCategories($scope.article.allCategories, metadata));
draftArticle = _.cloneDeep($scope.article);
_.forEach($scope.article.content, function (content) {
if (content.snippet) {
content.snippet = _.compact(content.snippet.split('\n')).join('<br>');
}
});
}).finally(function () {
state.dataIsLoading = false;
});
}
//template selection screen
$scope.selectTemplate = function (template) {
state.isTemplateSelected = true;
$scope.selectedTemplate = _.cloneDeep(template);
};
//template details screen
$scope.backToTemplateSelection = function () {
$scope.selectedTemplate = null;
state.isTemplateSelected = false;
state.rememberTemplate = false;
};
$scope.acceptTemplate = function () {
loadDraftData().then(function () {
setDefaultTemplate(state.rememberTemplate ? $scope.selectedTemplate.id : null);
state.isTemplateAccepted = true;
});
};
$scope.mergeAndAcceptTemplate = function () {
var newContent = '', previousArticle = _.cloneDeep(article);
runMergeForChangeTemplate()
.then(function (content) {
$scope.previousTemplate = null;
newContent = content;
state.dataIsLoading = true;
return knowledgeArticleModel.getDraft($scope.selectedTemplate.id);
})
.then(function (result) {
angular.extend(article, knowledgeArticleModel.mergeArticleMetaData(result, previousArticle, newContent));
setDefaultTemplate(state.rememberTemplate ? $scope.selectedTemplate.id : null);
state.isTemplateAccepted = true;
}).finally(function () {
state.dataIsLoading = false;
});
};
function setDefaultTemplate(templateId) {
state.rememberTemplate = false;
localStorageService.set(localStorageDefaultTemplateKey, {
templateId: templateId,
user: currentUserId
});
}
function runMergeForChangeTemplate() {
return openMergeTool({
input: $scope.article.content,
output: _.cloneDeep($scope.selectedTemplate.templateObject.sections),
outputTitle: ['create.knowledge.merge.change.output.title'],
inputTitle: ['create.knowledge.merge.change.input.title.first', 'create.knowledge.merge.change.input.title.second']
}).then(function (content) {
return content;
});
}
//knowledge article edit screen
$scope.changeTemplate = function () {
state.isTemplateSelected = false;
state.isTemplateAccepted = false;
$scope.previousTemplate = _.cloneDeep($scope.selectedTemplate);
setDefaultTemplate(null);
loadAvailableTemplates();
};
$scope.clearTitle = function () {
$scope.article.title = '';
$scope.onKnowledgeTitleChange();
};
$scope.onKnowledgeTitleChange = function (value) {
state.similarArticles = [];
state.loadingSimilarArticles = false;
if (knowledgeTitleChangeTimer) {
$timeout.cancel(knowledgeTitleChangeTimer);
}
if (value && value.length >= 3) {
knowledgeTitleChangeTimer = $timeout(function () {
state.loadingSimilarArticles = true;
if (state.similarArticlePromise) {
state.similarArticlePromise.finally(function () {
state.loadingSimilarArticles = true;
state.similarArticles = [];
});
}
state.similarArticlePromise = knowledgeArticleModel.findArticleByText({ search_text: value }).then(function (articles) {
state.similarArticles = articles;
_.remove(state.similarArticles, { templateName: 'Decision Tree' }); //Currently not supporting decision tree
}).finally(function () {
state.loadingSimilarArticles = false;
});
}, 1000);
}
};
$scope.mergeSimilarArticle = function (id) {
state.dataIsLoading = true;
knowledgeArticleModel.getKnowledgeArticleById(id).then(function (data) {
state.dataIsLoading = false;
state.showingMergeTool = true;
return openMergeTool({
uuid: $scope.article.articleGUID,
input: data.content,
output: _.cloneDeep(article.content),
outputTitle: ['create.knowledge.merge.output.title'],
inputTitle: ['create.knowledge.merge.input.title.first', 'create.knowledge.merge.input.title.second']
});
}).then(function (content) {
article.content = content;
}).finally(function () {
state.showingMergeTool = false;
});
};
$scope.updateSimilarArticle = function (id) {
state.dataIsLoading = true;
knowledgeArticleModel.getKnowledgeArticleById(id).then(function (data) {
state.dataIsLoading = false;
if (data.accessMappings.detailsEditAllowed) {
state.showingMergeTool = true;
return openMergeTool({
input: _.cloneDeep(article.content),
output: _.cloneDeep(data.content),
outputTitle: ['create.knowledge.merge.instead.output.title'],
inputTitle: ['create.knowledge.merge.instead.input.title.first', 'create.knowledge.merge.instead.input.title.second']
});
}
else {
systemAlertService.info({
text: $filter('i18n')('create.knowledge.similar.edit.instead.deny')
});
return $q.reject();
}
}).then(function (content) {
openArticleForEdit(id, content);
}).finally(function () {
state.showingMergeTool = false;
});
};
function openArticleForEdit(id, content) {
state.allowStateChange = true;
$state.go('knowledge', { id: id, content: content, editMode: true });
}
function openMergeTool(mergeParams) {
var parentScope = $scope;
return $modal.open({
templateUrl: 'views/knowledge-article/article-merge-tool.html',
controller: ['$scope', '$modalInstance', 'mergeParams',
function ($scope, $modalInstance, mergeParams) {
$scope.input = { content: mergeParams.input };
$scope.output = { content: mergeParams.output, uuid: mergeParams.uuid };
$scope.outputTitle = mergeParams.outputTitle || [];
$scope.inputTitle = mergeParams.inputTitle || [];
$scope.knowledgeAnchorParser = parentScope.knowledgeAnchorParser;
$scope.merge = function () {
$modalInstance.close($scope.output.content);
};
parentScope.$on('$destroy', $modalInstance.close);
}
],
windowClass: 'modal_article-merge-tool',
backdrop: false,
keyboard: false,
resolve: {
mergeParams: function () {
return mergeParams;
}
}
}).result;
}
$scope.handleFileChange = function (fileInput) {
var newAttachment = attachmentService.prepareFileToUpload({ fileInput: fileInput });
if (newAttachment && newAttachment.size <= 0) {
systemAlertService.warning({
text: $filter('i18n')('attachment.file_empty'),
icon: 'icon-exclamation_triangle',
clear: true,
hide: 5000
});
return;
}
if (newAttachment) {
$scope.attachments ? $scope.attachments.push(newAttachment) : $scope.attachments = [newAttachment];
}
};
$scope.dismissAttachment = function ($e, attachment) {
var index = $scope.attachments.indexOf(attachment);
if (index >= 0) {
$scope.attachments.splice(index, 1);
}
$e.stopImmediatePropagation();
};
$scope.addLinkedItem = function ($event) {
var modalInstance = $modal.open({
templateUrl: 'views/ticket/link-item-action-blade.html',
windowClass: 'action-blade',
controller: 'LinkController',
resolve: {
linkParams: function () {
return {
selectedItems: [{
id: null,
type: EntityVO.TYPE_KNOWLEDGE
}],
isDraft: true
};
}
}
});
modalInstance.result.then(function (linkedItems) {
Array.prototype.push.apply($scope.linkedItems, linkedItems);
}).finally(function () {
$event.currentTarget.focus();
});
};
$scope.removeLinkedItem = function (item) {
_.pull($scope.linkedItems, item);
};
$scope.createArticle = function () {
var createdArticle;
$scope.state.dataIsLoading = true;
$scope.article.allCategories = categoriesService.collectValues($scope.article.categoriesSet, $scope.article);
saveSetOfVisibilityGroups(article.articleVisibilityGroup);
article.title = article.title.replace(/\u00a0/g, ' ');
article.parentTicketType = ticketModel.articleParent ? ticketModel.articleParent.type : '';
setTimeout(function () {
knowledgeArticleModel.createArticle(currentUserId, article).then(function (result) {
createdArticle = result;
if (ticketModel.articleParent) {
delete ticketModel.articleParent;
}
}).then(function () {
var linkingPromise = $scope.linkedItems.length ? linkItems(createdArticle) : $q.when(1), attachmentPromise = $scope.attachments.length ? addAttachments(createdArticle) : $q.when(1);
knowledgeArticleModel.getArticleRevisionsById(createdArticle.id, true); //just to preload revisions, so user wont wait for them on article detail page.
return $q.all([linkingPromise, attachmentPromise]);
}).catch(function (error) {
systemAlertService.error({
text: (error.data.defaultMessage) || (error.data.errorCode ? $filter('i18n')('error.unknown') : error.data.error),
clear: false,
displayOnStateChange: true
});
}).finally(function () {
$scope.state.dataIsLoading = false;
if (createdArticle) {
$scope.onCreateArticleCompleted(createdArticle);
}
});
}, 200);
};
function saveSetOfVisibilityGroups(visibilities) {
localStorageService.set(localStorageLastVisibilitySetKey, visibilities);
}
function linkItems(createdArticle) {
return relationModel.addRelation({
uuid: createdArticle.id,
type: EntityVO.TYPE_KNOWLEDGE
}, _.map($scope.linkedItems, function (item) {
return _.omit(item, ['realObject', 'isPoi']);
}));
}
function addAttachments(createdArticle) {
return attachmentService.uploadAttachment(createdArticle.type, createdArticle.id, $scope.attachments);
}
$scope.onCreateArticleCompleted = function (createdArticle) {
state.allowStateChange = true;
$state.go('knowledge', { id: createdArticle.id });
};
$scope.cancel = function () {
if ($scope.previousTemplate) {
state.isTemplateSelected = true;
state.isTemplateAccepted = true;
$scope.selectedTemplate = _.cloneDeep($scope.previousTemplate);
$scope.previousTemplate = null;
}
else {
//trick to avoid triggering $stateChangeStart event
$state.go('dashboard', {}, { notify: false }).then(function () {
$scope.$emit('$stateChangeSuccess');
});
}
};
$scope.discard = function () {
showLeaveCreateKnowledgeArticleDialog().then(function (result) {
result && $scope.cancel();
});
};
function showLeaveCreateKnowledgeArticleDialog() {
var modal = systemAlertService.modal({
type: 'info',
title: $filter('i18n')('common.notification.dirty.title'),
text: $filter('i18n')('common.notification.dirty.loseChanges'),
buttons: [
{
text: $filter('i18n')('common.button.yes'),
data: true
},
{
text: $filter('i18n')('common.button.no'),
data: false
}
]
});
return modal.result;
}
function isArticleDirty() {
return isArticleTitleDirty() || isArticleContentDirty() || isArticleMetadataDirty();
}
function isArticleContentDirty() {
var rawContent = getRawArticleContent();
return !angular.equals(draftArticle.content, rawContent);
}
function isArticleTitleDirty() {
return article.title && article.title.trim();
}
function isArticleMetadataDirty() {
var articleMetadata = _.omit(article, ['categoriesControls', 'content', 'title']), draftArticleMetadata = _.omit(article, ['categoriesControls', 'content', 'title']);
return !angular.equals(articleMetadata, draftArticleMetadata);
}
function getRawArticleContent() {
var articleContentCopy = _.cloneDeep(article.content);
return _.map(articleContentCopy, function (section) {
section.snippet = $(section.snippet).text();
return section;
});
}
$scope.state = state;
$scope.article = article;
$scope.searchService = searchService;
$scope.$on('$stateChangeStart', function (event, toState, toParams) {
if (!state.allowStateChange && state.isTemplateSelected && state.isTemplateAccepted && isArticleDirty()) {
event.preventDefault();
showLeaveCreateKnowledgeArticleDialog().then(function (result) {
if (result) {
state.allowStateChange = true;
$state.go(toState.name, toParams);
}
});
}
});
}
])
.controller('CreateKnowledgeArticleModalController', ['$scope', '$controller', '$modalInstance', 'ticketModel',
function ($scope, $controller, $modalInstance, ticketModel) {
function initArticleContext() {
if (ticketModel.articleParent.type === EntityVO.TYPE_PROBLEM ||
ticketModel.articleParent.type === EntityVO.TYPE_KNOWNERROR ||
ticketModel.articleParent.type === EntityVO.TYPE_INCIDENT ||
ticketModel.articleParent.type === EntityVO.TYPE_WORKORDER) {
$scope.articleContext = {
id: ticketModel.articleParent.id,
type: ticketModel.articleParent.type
};
}
}
initArticleContext();
$.extend(this, $controller('CreateKnowledgeArticleController', { $scope: $scope }));
$scope.onCreateArticleCompleted = function (createdArticle) {
$modalInstance.close(createdArticle);
};
$scope.cancel = function () {
$modalInstance.dismiss();
};
$scope.$on('$stateChangeSuccess', $modalInstance.dismiss);
}
]);
})();