SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/ticket/link-controller.js

498 lines
28 KiB
JavaScript

"use strict";
(function () {
'use strict';
angular.module('ticketModule').controller('LinkController', ['$scope', '$modalInstance', 'linkParams', 'configurationModel', 'searchService', 'ticketModel', 'relationModel', '$q', 'metadataModel', 'searchModel', 'assetService', 'authService', 'roles', 'systemAlertService', 'i18nService', 'events', '$filter',
function ($scope, $modalInstance, linkParams, configurationModel, searchService, ticketModel, relationModel, $q, metadataModel, searchModel, assetService, authService, roles, systemAlertService, i18nService, events, $filter) {
var type = linkParams.selectedItems[0].ticketType ? linkParams.selectedItems[0].ticketType : linkParams.selectedItems[0].type, isSingle = linkParams.selectedItems.length === 1, linkConfig = configurationModel.get('link'), selected = {
linkOption: {}
}, state = {
searching: false,
processing: false,
isDirty: false
}, deselectAllEntities = function () {
_.forEach(selected.entities, function (entity) {
entity.isSelected = false;
});
selected.entities = [];
}, globalMetadata, cssClass;
$scope.state = state;
$scope.selected = selected;
$scope.linkOptions = angular.copy(_.sortBy(getLinkOptions(type), 'type'));
$scope.availableEntities = null;
$scope.selected.advancedFilters = [];
$scope.searchConfig = angular.copy(configurationModel.get('outage.searchFilter'));
$scope.ticketType = type;
var filterDictionary = _.keyBy($scope.searchConfig, 'label');
//Sorting array of relation types
_.each($scope.linkOptions, function (item) {
item.relations = item.relations ? item.relations.sort() : [];
});
$q.all([metadataModel.getMetadataByType(EntityVO.TYPE_GLOBAL), metadataModel.getMetadataByType(EntityVO.TYPE_OUTAGE)]).then(function (metadata) {
globalMetadata = metadata[0];
var outageMetadata = metadata[1];
if (filterDictionary.unavailabilityStatus.options.length === 0) {
_.forEach(outageMetadata.statuses, function (status) {
var active = false;
//Defect #SW00490745 fix
if ((linkParams.selectedItems[0].timing === 'Latent' && status.name === 'Restored') || (linkParams.selectedItems[0].timing !== 'Latent' && status.name === 'Scheduled')) {
active = true;
}
filterDictionary.unavailabilityStatus.options.push({
name: status.label,
type: 'dynamic',
criteria: {
name: 'unavailabilityStatus',
value: [status.name]
},
active: active
});
if (active === true) {
$scope.selected.advancedFilters.push({
name: status.label,
type: 'dynamic',
criteria: {
name: 'unavailabilityStatus',
value: [status.name]
},
active: active
});
}
});
}
if (filterDictionary.unavailabilityType.options.length === 0) {
_.forEach(outageMetadata.types, function (type) {
filterDictionary.unavailabilityType.options.push({
name: type.label,
type: 'dynamic',
criteria: {
name: 'unavailabilityType',
value: [type.name]
}
});
});
}
if (filterDictionary.ciName.options.length !== 0) {
_.forEach(filterDictionary.ciName.options, function (type) {
if (type.active === true) {
$scope.selected.advancedFilters.push({
name: type.label,
type: 'constant',
criteria: {
name: 'relatedCI',
value: [type.name]
},
active: type.active
});
}
});
}
});
if (type === EntityVO.TYPE_CHANGE) {
//Custom functionality for advanced search of Outages, when All related CIs and
$scope.$watch(function () {
var relatedCIFilter = _.find($scope.selected.advancedFilters, { criteria: { name: 'relatedCI' } }), ciNamesFilter = _.find($scope.selected.advancedFilters, { criteria: { name: 'name' } });
return { relatedCI: relatedCIFilter, keywords: ciNamesFilter };
}, function (newVal, oldVal) {
var ciNameFilter, oldKeywords = oldVal.keywords, newKeywords = newVal.keywords, relatedCiOld = oldVal.relatedCI, relatedCiNew = newVal.relatedCI;
if (newKeywords && !oldKeywords) {
ciNameFilter = _.find($scope.searchConfig, { name: 'name' }) || {};
var allRelatedCiFilter = _.find(ciNameFilter.options, { name: 'relatedCI' }) || {};
allRelatedCiFilter.active = false;
var filterIndex = $scope.selected.advancedFilters.indexOf(relatedCiNew);
$scope.selected.advancedFilters.splice(filterIndex, 1);
}
else if (relatedCiNew && !relatedCiOld) {
ciNameFilter = _.find($scope.searchConfig, { name: 'name' }) || {};
_.each(ciNameFilter.options, function (filter) {
if (filter.criteria && filter.criteria.name === 'name') {
filter.active = false;
}
});
$scope.selected.advancedFilters = _.reject($scope.selected.advancedFilters, { criteria: { name: 'name' } });
}
}, true);
$scope.searchCIsByKeyword = function (searchText) {
return assetService.getListOfAssets(searchText).then(function (result) {
var ciList = [];
try {
ciList = result[0].items[0].objects;
}
catch (e) {
console.log(e);
}
return ciList;
});
};
}
$scope.selectLinkOption = function (linkOption) {
state.isDirty = true;
selected.linkOption = linkOption;
selected.relation = selected.linkOption.relations.length === 1 ? linkOption.relations[0] : '';
selected.searchText = '';
selected.entities = [];
$scope.availableEntities = null;
//Use-case when suggested entities should be shown, before user start searching
if ([EntityVO.TYPE_OUTAGE].indexOf(linkOption.type) >= 0 && type === EntityVO.TYPE_CHANGE) {
state.searching = true;
searchModel.getFilteredSuggestedOutagesList(ticket)
.then(function (suggestedOutages) {
if (suggestedOutages && suggestedOutages.length > 0) {
$scope.availableEntities = suggestedOutages;
state.showSuggestedItemsTooltip = true;
}
//$scope.selected.advancedFilters.push(filterDictionary.ciName.options[0]);
})
.finally(function () {
state.searching = false;
});
}
};
$scope.iconClass = function (option, type) {
if (option.serviceType === "Security Incident") {
cssClass = 'icon-security-incident';
}
else {
cssClass = 'icon-' + type;
}
return cssClass;
};
$scope.searchEntities = function () {
var params = {}, jsonParams = {};
// if there is no searchText, the request fails on the backend
// with an error 'The Search Text field cannot be null.'
if (!selected.searchText) {
return false;
}
if (state.showSuggestedItemsTooltip) {
state.showSuggestedItemsTooltip = false;
}
state.searching = true;
selected.entities = [];
if (selected.linkOption.type === EntityVO.TYPE_OUTAGE) {
if (selected.searchText) {
params.searchText = selected.searchText;
}
_.each($scope.selected.advancedFilters, function (filterItem) {
if (filterItem.criteria.name === 'scheduledStartDates') {
var startDate, endDate;
if (filterItem.criteria.value) {
if (filterItem.criteria.value.startDate) {
startDate = filterItem.criteria.value.startDate;
}
else if (filterItem.criteria.value.length && filterItem.criteria.value[0] && filterItem.criteria.value[0].start) {
startDate = filterItem.criteria.value[0].start;
}
if (filterItem.criteria.value.endDate) {
endDate = filterItem.criteria.value.endDate;
}
else if (filterItem.criteria.value.length && filterItem.criteria.value[0] && filterItem.criteria.value[0].end) {
endDate = filterItem.criteria.value[0].end;
}
}
else {
startDate = $scope.$eval(filterItem.defaultValues.start, { moment: moment });
endDate = $scope.$eval(filterItem.defaultValues.end, { moment: moment });
}
params.scheduledDate = [{
start: startDate,
end: endDate
}];
}
else if (filterItem.criteria.name === 'unavailabilityStatus') {
!params.unavailabilityStatus ? params.unavailabilityStatus = [filterItem.criteria.value[0]] : params.unavailabilityStatus.push(filterItem.criteria.value[0]);
}
else if (filterItem.criteria.name === 'unavailabilityType') {
!params.unavailabilityType ? params.unavailabilityType = [filterItem.criteria.value[0]] : params.unavailabilityType.push(filterItem.criteria.value[0]);
}
else if (filterItem.criteria.name === 'relatedCI') {
params.relatedCI = true;
}
else if (filterItem.criteria.name === 'name') {
!params.ciNames ? params.ciNames = [filterItem.criteria.value[0]] : params.ciNames.push(filterItem.criteria.value[0]);
}
});
return searchModel.getFilteredOutagesList(params, ticket)
.then(function (searchResults) {
$scope.availableEntities = searchResults;
})
.finally(function () {
state.searching = false;
});
}
else {
params = {
search_text: selected.searchText,
types: selected.linkOption.type,
chunk_index: 0,
chunk_size: 50
};
if (selected.linkOption.type === EntityVO.TYPE_ASSET) {
params.chunk_size = globalMetadata.configurationParameters && globalMetadata.configurationParameters.assetSearchQueryLimit
? globalMetadata.configurationParameters.assetSearchQueryLimit : 4;
}
jsonParams = {
allowSpecialCharacters: true
};
if (type === EntityVO.TYPE_KNOWLEDGE && linkParams.isDraft) { //To show retired articles while searching for related items.
params.suggest_search = true;
}
}
function postSearch(data) {
var searchResults = data.items.length > 0 ? data.items[0].results : [];
if (isSingle && type !== EntityVO.TYPE_ASSET && type !== EntityVO.TYPE_KNOWLEDGE) {
if (selected.linkOption.type === EntityVO.TYPE_ASSET) {
//remove asset that is impacted service
if (ticket.impactedService && ticket.impactedService.reconciliationId) {
searchResults = _.reject(searchResults, { id: ticket.impactedService.reconciliationId });
}
}
else {
//remove current item from search results
searchResults = _.reject(searchResults, { id: linkParams.selectedItems[0].id });
//remove already related items from search results
//Defect fix: SW00523402
// _.forEach(ticket.relations, function (relatedItem) {
// searchResults = _.reject(searchResults, { id: relatedItem.id });
// });
}
}
$scope.availableEntities = searchResults;
}
var promarr = [searchService.getGlobalSearchResults(params, jsonParams)];
if (!metadataModel.cache[selected.linkOption.type]) {
promarr.push(metadataModel.getMetadataByType(selected.linkOption.type));
}
return $q.all(promarr).then(function (data) {
postSearch(data[0]);
}).finally(function () {
state.searching = false;
});
};
$scope.selectEntity = function (entity) {
if (entity.isSelected) {
if (selected.relation === RelationItemVO.TYPE_DUPLICATEOF && selected.entities.length) {
deselectAllEntities();
}
if (entity.type === EntityVO.TYPE_OUTAGE) {
var relatedAsset = _.find(ticket.relations, { id: entity.affectedAsset.reconciliationId });
if (!relatedAsset) {
entity.affectedAsset.isRelatedToCR = true;
}
}
selected.entities.push(entity);
}
else {
if (entity.type === EntityVO.TYPE_OUTAGE && entity.affectedAsset.isRelatedToCR) {
entity.affectedAsset.isRelatedToCR = false;
}
_.remove(selected.entities, { id: entity.id });
}
};
$scope.selectRelation = function (relation) {
if (relation === RelationItemVO.TYPE_DUPLICATEOF && selected.entities.length && isSingle) {
//only 1 can be marked duplicate so deselect all and keep only one selected
_.forEach(selected.entities, function (entity) {
entity.isSelected = false;
});
_.last(selected.entities).isSelected = true;
_.remove(selected.entities, { isSelected: false });
}
if (relation === RelationItemVO.TYPE_ORIGINALOF) {
_.forEach(selected.entities, function (entity) {
if (!entity.additionalInformation.accessMappings.duplicateActionAllowed) {
entity.isSelected = false;
}
});
}
selected.relation = relation;
};
$scope.isEntityDisabled = function (entity) {
return (selected.relation === RelationItemVO.TYPE_ORIGINALOF && !entity.additionalInformation.accessMappings.duplicateActionAllowed);
};
$scope.link = function () {
var actionItems = _.map(linkParams.selectedItems, function (item) {
var actionObj = {};
if (type === EntityVO.TYPE_ASSET) {
actionObj = {
uuid: item.reconciliationId,
type: item.ticketType
};
}
else {
actionObj = {
uuid: item.id,
type: item.type
};
}
return actionObj;
}), alreadyRelatedItems = { length: 0 }, relateItems = _.map(selected.entities, function (entity) {
var matchRelatedItems, relatedObj = {
id: entity.id,
relationshipType: selected.relation,
tag: RelationItemVO.TAG_LINKEDITEM,
type: selected.linkOption.type,
desc: entity.title
};
if (!entity.title && entity.type === EntityVO.TYPE_OUTAGE) {
relatedObj.desc = entity.desc;
}
if (entity.displayId) {
relatedObj.displayId = entity.displayId;
}
if (linkParams.selectedItems.length === 1 && linkParams.selectedItems[0].displayId) {
relatedObj.parentDisplayId = linkParams.selectedItems[0].displayId;
}
matchRelatedItems = _.find(relationModel.cache && relationModel.cache[actionItems[0] && actionItems[0].uuid], function (item) {
if (item.id === entity.id && item.relationshipType === selected.relation) {
return item;
}
});
if (matchRelatedItems) {
alreadyRelatedItems[entity.id] = matchRelatedItems;
alreadyRelatedItems.length++;
}
else {
return relatedObj;
}
}), linkFn = linkParams.isDraft ? $q.when : relationModel.bulkAddRelation;
relateItems = _.without(relateItems, undefined);
if (alreadyRelatedItems.length > 0) {
systemAlertService.warning({
text: $filter('i18n')('ticket.notification.alreadyExist.message', alreadyRelatedItems.length),
hide: 10000
});
}
if (relateItems.length) {
state.processing = true;
linkFn(actionItems, relateItems).then(function () {
var linkedItems = _.map(selected.entities, function (entity, idx) {
var relation = relateItems[idx];
if (relation) {
if (entity.type === EntityVO.TYPE_ASSET) {
relation.realObject = {
assignee: entity.additionalInformation.assignee,
priority: entity.additionalInformation.priority,
status: entity.additionalInformation.status,
assetType: entity.additionalInformation.assetType,
name: entity.additionalInformation.name,
manufacturer: entity.additionalInformation.manufacturer,
model: entity.additionalInformation.product.model,
reconciliationId: entity.additionalInformation.reconciliationId,
classId: entity.additionalInformation.classId,
title: entity.title
};
relation.displayId = entity.displayId || '';
}
else {
relation.realObject = entity;
relation.displayId = entity.displayId || '';
}
return new RelationItemVO().build(relation);
}
});
linkedItems = _.without(linkedItems, undefined);
$modalInstance.close(linkedItems);
$scope.$parent.$broadcast(events.RELATIONS_UPDATE_COMPLETE);
if (configurationModel.showARMessageOnGetEntry && actionItems.length && selected.entities
&& selected.entities.length && selected.entities[0].type === EntityVO.TYPE_ASSET) {
ticketModel.getARMessageInformation(actionItems[0].uuid, actionItems[0].type);
}
state.processing = false;
}).catch(function (response) {
systemAlertService.error({
text: response.message ? response.message : response.data.results.error,
clear: false
});
$modalInstance.dismiss();
});
}
};
if (isSingle && type !== EntityVO.TYPE_ASSET && type !== EntityVO.TYPE_KNOWLEDGE) {
var id = linkParams.selectedItems[0].id, ticket = {};
if (linkParams.isDraft) {
ticket = ticketModel.cache[id];
ticket.relations = relationModel.cache[id];
}
else {
state.processing = true;
$q.all([ticketModel.getTicket(id, type), relationModel.getRelations(id, type)]).then(function (result) {
ticket = angular.copy(result[0]);
ticket.relations = result[1];
if (type === EntityVO.TYPE_INCIDENT) {
//INFO: SW00531355
var tempRelation = _.find(ticket.relations, { relationshipType: RelationItemVO.TYPE_ORIGINALOF });
if (tempRelation && tempRelation.relationshipType) { //if item is already a original of other incident
var incidentToIncidentLinkOption = _.find($scope.linkOptions, { type: type });
incidentToIncidentLinkOption.relations = _.without(incidentToIncidentLinkOption.relations, RelationItemVO.TYPE_DUPLICATEOF);
}
}
}).finally(function () {
state.processing = false;
});
}
}
if ($scope.linkOptions.length === 1) {
$scope.selectLinkOption($scope.linkOptions[0]);
}
function getLinkOptions(type) {
var options = linkConfig[type];
if (type === EntityVO.TYPE_CHANGE && !linkParams.linkFromTicketConsole) {
options = _.reject(options, { type: EntityVO.TYPE_ASSET });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_ASSET)) {
options = _.reject(options, { type: EntityVO.TYPE_ASSET });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_WORKORDER) || !authService.isAuthorized(roles.ITSM_AGENT_ROLE)) {
options = _.reject(options, { type: EntityVO.TYPE_WORKORDER });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_CHANGE) || !authService.isAuthorized(roles.ITSM_CHANGE_USER_ROLE)) {
options = _.reject(options, { type: EntityVO.TYPE_CHANGE });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_RELEASE) || !authService.isAuthorized(roles.ITSM_RELEASE_USER_ROLE)) {
options = _.reject(options, { type: EntityVO.TYPE_RELEASE });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_INCIDENT) || !authService.isAuthorized(roles.ITSM_AGENT_ROLE)) {
options = _.reject(options, { type: EntityVO.TYPE_INCIDENT });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_PROBLEM) || !authService.isAuthorized(roles.ITSM_PROBLEM_USER_ROLE)) {
options = _.reject(options, { type: EntityVO.TYPE_PROBLEM });
}
if (!configurationModel.isServerApplicationEnabled(EntityVO.TYPE_KNOWNERROR) || !authService.isAuthorized(roles.ITSM_PROBLEM_USER_ROLE)) {
options = _.reject(options, { type: EntityVO.TYPE_KNOWNERROR });
}
return options;
}
$scope.close = function () {
if (state.isDirty) {
var modalInstance = systemAlertService.modal({
title: i18nService.getLocalizedString('common.notification.dirty.title'),
text: i18nService.getLocalizedString('common.notification.dirty.message'),
buttons: [
{
text: i18nService.getLocalizedString('common.labels.yes'),
data: true
},
{
text: i18nService.getLocalizedString('common.labels.no'),
data: false
}
]
});
modalInstance.result.then(function (data) {
if (data) {
$modalInstance.dismiss();
}
});
}
else {
$modalInstance.dismiss();
}
};
function handleModalBackdropClick() {
$scope.close();
}
$scope.$on(events.MODAL_BACKDROP_CLICK, handleModalBackdropClick);
}
]);
})();