453 lines
27 KiB
JavaScript
453 lines
27 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Created by abhatkha on 9/08/2017.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
angular.module('adminModule')
|
|
.controller('LaunchActionController', ['$filter', '$modal', '$rootScope', '$scope', '$log', '$q', 'events', 'metadataModel',
|
|
'screenConfigurationModel', 'screenConfigurationService', 'systemAlertService', 'layoutConfigurationModel',
|
|
'objectValueMapperService', '$window', 'expressionEventManager', 'expressionEvaluatorService', '$timeout',
|
|
function ($filter, $modal, $rootScope, $scope, $log, $q, events, metadataModel, screenConfigurationModel, screenConfigurationService, systemAlertService, layoutConfigurationModel, objectValueMapperService, $window, expressionEventManager, expressionEvaluatorService, $timeout) {
|
|
var promptModal, metadata, contextId, type, isExecutingProviderAction;
|
|
$scope.providerActionToExecute = objectValueMapperService.providerActionToExecute;
|
|
$scope.context = $scope.context ? $scope.context : $scope.ticket;
|
|
if ($scope.bulkContextType) {
|
|
type = $scope.bulkContextType;
|
|
}
|
|
else {
|
|
type = $scope.context.ticketType || $scope.context.type;
|
|
}
|
|
metadataModel.getMetadataByType(type).then(function (data) {
|
|
metadata = data;
|
|
});
|
|
var fieldPropertyMapping = function (actionLists) {
|
|
$scope.actionLists = actionLists;
|
|
$scope.fieldActionMapping = {};
|
|
for (var i in actionLists) {
|
|
if (actionLists[i].mappedFields && actionLists[i].mappedFields.length > 0) {
|
|
var fieldArr = actionLists[i].mappedFields, fieldObjArr = _.uniqBy(fieldArr, function (field) {
|
|
return field.fieldName;
|
|
});
|
|
for (var j in fieldObjArr) {
|
|
$scope.fieldActionMapping[fieldObjArr[j].fieldName] = {
|
|
action: actionLists[i],
|
|
iconName: fieldObjArr[j].iconName
|
|
};
|
|
}
|
|
}
|
|
}
|
|
//store the fields with actions map in objectValueMapperService
|
|
objectValueMapperService.setFieldActionMapping($scope.fieldActionMapping, $scope.context.type);
|
|
};
|
|
var extractProviderActionExpressions = function (actionLists) {
|
|
var isActionOnTicketLoad;
|
|
if (actionLists) {
|
|
_.forEach(actionLists, function (action) {
|
|
if (action.expressions && action.expressions.length) {
|
|
_.forEach(action.expressions, function (expression) {
|
|
objectValueMapperService.addToProviderActionExpressionMapper(expression.condition, action);
|
|
if (expression.executeOn === 'On Ticket Load') {
|
|
isActionOnTicketLoad = true;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
if (isActionOnTicketLoad) {
|
|
expressionEventManager.handleTicketLoadForActions();
|
|
}
|
|
}
|
|
};
|
|
if (EntityVO.ENTITIES_WITH_NEW_CUSTOMIZATION.indexOf(type) !== -1) {
|
|
screenConfigurationModel.providerHardReload = true;
|
|
$scope.associateActionPromise = screenConfigurationModel.loadActionsNew($scope.context.type).then(function () {
|
|
$scope.AssociateActionLists = screenConfigurationModel.actionList;
|
|
fieldPropertyMapping($scope.AssociateActionLists);
|
|
if (screenConfigurationModel.isTicketEnabledForProviderActionExpression(type)) {
|
|
extractProviderActionExpressions($scope.AssociateActionLists);
|
|
}
|
|
});
|
|
}
|
|
$scope.showEditor = function (callback, params, ticketObj, contentId) {
|
|
promptModal = $modal.open({
|
|
templateUrl: 'views/admin/screen-configuration/provider-user-prompt.html',
|
|
windowClass: 'action-blade provider-user-prompt',
|
|
backdrop: 'custom',
|
|
resolve: {
|
|
ticket: ['ticketModel', function (ticketModel) {
|
|
return ticketModel.getTicket(contentId, ticketObj.resource);
|
|
}]
|
|
},
|
|
controller: ['$scope', 'ticket', function ($scope, ticket) {
|
|
var fieldObj = {}, result = {}, promptField;
|
|
var initMappingFieldDefaultValue = function (field, defaultValue) {
|
|
if (field.isCheckboxField()) {
|
|
var cBoxOption = (field.options[0] || {});
|
|
if (_.includes(cBoxOption, defaultValue) || ['true', 'checked'].indexOf(defaultValue) !== -1 || defaultValue === 0) {
|
|
field.setValue(0);
|
|
}
|
|
}
|
|
else if (field.hasDateDataType() || field.hasDateTimeDataType()) {
|
|
var stringParseDate = moment(defaultValue);
|
|
if (stringParseDate.isValid()) {
|
|
field.setValue(stringParseDate.valueOf());
|
|
}
|
|
else {
|
|
// Can be the case when we try to parse string representation of timestamp
|
|
// it is worth to try to parse defaultValue to a number and parse
|
|
var numberParsedDate = moment(+defaultValue);
|
|
if (numberParsedDate.isValid()) {
|
|
field.setValue(numberParsedDate.valueOf());
|
|
}
|
|
}
|
|
}
|
|
else if (field.hasTimeDataType()) {
|
|
var amPmReg = new RegExp(/am|pm/, 'ig');
|
|
var parseFormat = 'HH:mm';
|
|
if (amPmReg.test(defaultValue)) {
|
|
parseFormat = 'hh:mma';
|
|
}
|
|
var setTimeValue = moment(defaultValue, parseFormat);
|
|
if (setTimeValue.isValid()) {
|
|
field.value = setTimeValue.valueOf();
|
|
}
|
|
}
|
|
else if (field.isDropdownField() || field.isRadioField()) {
|
|
var defaultValueOption = _.find(field.options, function (option) {
|
|
return _.includes(option, defaultValue);
|
|
});
|
|
if (defaultValueOption) {
|
|
field.setValue(defaultValueOption.name);
|
|
}
|
|
}
|
|
else {
|
|
field.setValue(defaultValue);
|
|
}
|
|
};
|
|
$scope.fieldArray = params.prompt;
|
|
// These are required for custom field directives, to render properly
|
|
$scope.editMode = true;
|
|
$scope.ticket = ticket;
|
|
$scope.fieldArray.forEach(function (field) {
|
|
if (field.defaultValue) {
|
|
initMappingFieldDefaultValue(field.mappedField, field.defaultValue);
|
|
}
|
|
});
|
|
$scope.getMappedFieldRenderType = function (field) {
|
|
var type = 'text';
|
|
if (field.isCheckboxField()) {
|
|
type = 'checkbox';
|
|
}
|
|
else if (field.hasDateDataType()) {
|
|
type = 'date';
|
|
}
|
|
else if (field.hasDateTimeDataType()) {
|
|
type = 'datetime';
|
|
}
|
|
else if (field.hasTimeDataType()) {
|
|
type = 'time';
|
|
}
|
|
else if (field.isNumberField()) {
|
|
type = 'number';
|
|
}
|
|
else if (field.isDropdownField() || field.isRadioField()) {
|
|
type = field.options.length > 0 ? 'enum' : 'text';
|
|
/*if (type === 'number') {
|
|
field.max = Infinity;
|
|
field.min = 0;
|
|
}*/
|
|
}
|
|
return type;
|
|
};
|
|
$scope.executeAction = function () {
|
|
var isEmptyPromptField = false, emptyFieldLabel = '';
|
|
for (var i in $scope.fieldArray) {
|
|
promptField = $scope.fieldArray[i];
|
|
fieldObj[promptField.mappedFieldId] = getMappedFieldValue(promptField.mappedField);
|
|
if (fieldObj[promptField.mappedFieldId] === null || fieldObj[promptField.mappedFieldId] === '') {
|
|
emptyFieldLabel += promptField.mappedFieldName + ' ';
|
|
isEmptyPromptField = true;
|
|
}
|
|
}
|
|
if (isEmptyPromptField) {
|
|
var message = emptyFieldLabel + $filter('i18n')('common.labels.nonEmpty');
|
|
systemAlertService.error({ text: message, clear: true, hide: 10000 });
|
|
}
|
|
else {
|
|
result = {};
|
|
_.extend(result, params, fieldObj);
|
|
callback(result, ticketObj, contentId);
|
|
promptModal.dismiss();
|
|
}
|
|
};
|
|
$scope.cancelExecution = function () {
|
|
isExecutingProviderAction = false;
|
|
promptModal.dismiss();
|
|
executeQueuedProviderAction(ticketObj);
|
|
};
|
|
function handleModalBackdropClick() {
|
|
$scope.cancelExecution();
|
|
}
|
|
var getMappedFieldValue = function (field) {
|
|
var value = field.getValue();
|
|
if (field.isDropdownField()) {
|
|
if (field.options.length && !field.ootb && value !== null) {
|
|
value = _.get(_.find(field.options, { name: value }), 'name');
|
|
}
|
|
}
|
|
else if (field.isCheckboxField() && value === null) {
|
|
value = -1;
|
|
}
|
|
return value;
|
|
};
|
|
$scope.$on(events.MODAL_BACKDROP_CLICK, handleModalBackdropClick);
|
|
}],
|
|
size: 'sm'
|
|
});
|
|
};
|
|
$scope.displaypromptModal = function (executeCallback, params, templateId, ticketObj, contentId) {
|
|
screenConfigurationModel.getTemplateById(templateId).then(function (templateObj) {
|
|
_.each(params.prompt, function (prompt) {
|
|
var mid = prompt.mappedFieldId, found = _.find(templateObj.mappings, { mappedFieldId: mid });
|
|
if (!_.isUndefined(found)) {
|
|
prompt.defaultValue = found.defaultValue || '';
|
|
prompt.mappedFieldName = found.mappedField.label || found.mappedFieldName;
|
|
prompt.dataType = found.mappedField.dataType;
|
|
prompt.mappedField = new FieldVO().build(found.mappedField);
|
|
prompt.mappedField.hideLabel = true;
|
|
prompt.mappedField.isReadOnly = false;
|
|
prompt.mappedField.isRequired = false;
|
|
prompt.mappedField.isHidden = false;
|
|
prompt.sequence = found.sequence;
|
|
}
|
|
});
|
|
params.prompt = _.sortBy(params.prompt, 'sequence'); //fix to show fields as per sequence in template object
|
|
$scope.showEditor(executeCallback, params, ticketObj, contentId);
|
|
});
|
|
};
|
|
$scope.launchAction = function (actionItem, actionType, $event, calledFromActionExpression) {
|
|
$log.topic('actionExecution', actionItem, actionType);
|
|
if (actionType === 'client') {
|
|
//URL action
|
|
//metadataModel.getMetadataByType(scope.context.type).then(function (metadata) {
|
|
//regex for finding square brackets [params] in the url
|
|
var re = new RegExp('\\[\\w+\\]'), url = actionItem.url, target = actionItem.target === 'new' ? '_blank' : '_self';
|
|
var findLabelObject = function (labelObject) {
|
|
return labelObject.name === key;
|
|
};
|
|
while (url.search(re) !== -1) {
|
|
var match = url.match(re), key = match[0].replace(/[\[\]']+/g, ''); //remove the square brackets
|
|
//check whether field is available in custom fields first else it should be in metadata
|
|
if ($scope.context.customFields && angular.isDefined($scope.context.customFields[key])) {
|
|
var selectionFieldObject = _.find(screenConfigurationModel.fieldLabels, findLabelObject);
|
|
if (selectionFieldObject && selectionFieldObject.options && (selectionFieldObject.options.length > $scope.context.customFields[key])) {
|
|
url = url.replace(re, selectionFieldObject.options[$scope.context.customFields[key]].label);
|
|
}
|
|
else {
|
|
url = url.replace(re, $scope.context.customFields[key]);
|
|
}
|
|
}
|
|
else {
|
|
var valueFromRecord = screenConfigurationService.getContextPropertyByMetadataMapping($scope.context, metadata, key) || '', localizedValue = $filter('localizeLabel')(valueFromRecord, key, $scope.context.type);
|
|
url = url.replace(re, localizedValue || valueFromRecord);
|
|
}
|
|
}
|
|
$log.topic('actionExecution', 'Launch URL action', url, target);
|
|
$window.open(encodeURI(url), target);
|
|
//});
|
|
}
|
|
else if (actionType === 'launch') {
|
|
$scope.launchActionCallback({ actionItem: actionItem, event: $event });
|
|
}
|
|
else {
|
|
//Provider action
|
|
contextId = type === EntityVO.TYPE_ASSET ? $scope.context.reconciliationId : $scope.context.id;
|
|
if (EntityVO.ENTITIES_WITH_NEW_CUSTOMIZATION.indexOf($scope.context.type) !== -1) {
|
|
$log.topic('providerExecution', 'New Provider action', actionItem, contextId);
|
|
if (calledFromActionExpression) {
|
|
$scope.getInputParams(actionItem, $scope.context, $scope.executeActionFromExpressionCallback, contextId);
|
|
}
|
|
else {
|
|
$scope.getInputParams(actionItem, $scope.context, $scope.executeActionCallback, contextId);
|
|
}
|
|
}
|
|
else {
|
|
$log.topic('actionExecution', 'Old Provider action', actionItem.id, contextId);
|
|
screenConfigurationModel.executeProviderAction(actionItem.id, contextId).then(function () {
|
|
var message = $filter('i18n')('screenConfiguration.providerActionExecuted', actionItem.actionName);
|
|
systemAlertService.success({ text: message, clear: true, hide: 10000 });
|
|
}).catch(function (error) {
|
|
systemAlertService.error({
|
|
text: (error.data && error.data.error) ? error.data.error : error.defaultMessage,
|
|
clear: false
|
|
});
|
|
});
|
|
}
|
|
}
|
|
};
|
|
$scope.getInputParams = function (actionObj, ticketObj, callback, contextId) {
|
|
var paramObj = { prompt: [] }, showUserPrompt = false, value, fieldDef, fieldName, obj, i;
|
|
for (i in actionObj.mappings) {
|
|
obj = actionObj.mappings[i];
|
|
if (obj.type.indexOf('input') === 0) {
|
|
if (obj.mappedFieldValue && (obj.type.indexOf('ticket') !== -1)) {
|
|
fieldName = obj.mappedFieldValue;
|
|
fieldDef = objectValueMapperService.getFieldDefinitionByName(fieldName, obj.mappedFieldId);
|
|
value = objectValueMapperService.getExactValueByFieldName(fieldName);
|
|
$log.topic('providerExecution', obj.type, 'fieldName:', fieldName, 'value :', value);
|
|
if (fieldDef && (fieldDef.isDropdownField() || fieldDef.isRadioField())) {
|
|
var selectedOption = _.find(fieldDef.options, { name: value });
|
|
if (selectedOption) {
|
|
value = selectedOption.index;
|
|
}
|
|
else {
|
|
value = undefined;
|
|
}
|
|
}
|
|
if (_.isString(value) && fieldDef && (fieldDef.isCheckboxField() || (value === "" && fieldDef.isNumberField()))) {
|
|
value = undefined;
|
|
}
|
|
if (fieldDef && (fieldDef.isDateTimeField() || fieldDef.isDateField()) && !value) {
|
|
// In order to prevent error from the backend, client should send null instead of empty string for dates
|
|
value = null;
|
|
}
|
|
paramObj[obj.mappedFieldId] = value;
|
|
$log.topic('providerExecution', obj.type, paramObj);
|
|
}
|
|
else if (obj.type.indexOf('prompt') !== -1) {
|
|
showUserPrompt = true;
|
|
paramObj.prompt.push(obj);
|
|
$log.topic('providerExecution', obj.type, paramObj);
|
|
}
|
|
else if (obj.type.indexOf('default') !== -1) {
|
|
if (obj.mappedFieldValue) {
|
|
paramObj[obj.mappedFieldId] = obj.mappedFieldValue;
|
|
}
|
|
else {
|
|
paramObj[obj.mappedFieldId] = '';
|
|
}
|
|
$log.topic('providerExecution', obj.type, paramObj);
|
|
}
|
|
}
|
|
}
|
|
if (showUserPrompt) {
|
|
$scope.displaypromptModal(callback, paramObj, actionObj.templateId, actionObj, contextId);
|
|
}
|
|
else {
|
|
callback(paramObj, actionObj, contextId);
|
|
$log.topic('providerExecution', actionObj, paramObj);
|
|
}
|
|
return paramObj;
|
|
};
|
|
var setOutputParams = function (actionObj, data) {
|
|
$log.topic('providerExecution', 'setOutputParams', data);
|
|
if (!_.isEmpty(data)) {
|
|
$log.topic('providerExecution', 'OPEN_EDIT_MODE');
|
|
$rootScope.$broadcast(events.OPEN_EDIT_MODE);
|
|
//Delaying setting field values, so that field values are set after edit mode is open
|
|
//Else the field value and originalData value will be the same and cannot reset to old value.
|
|
$timeout(function () {
|
|
objectValueMapperService.setFieldFromProvider(data, actionObj.mappings).then(function () {
|
|
$log.topic('providerExecution', 'Loaded output values');
|
|
});
|
|
});
|
|
}
|
|
};
|
|
$scope.executeActionCallback = function (params, actionItem, contextId) {
|
|
delete params.prompt;
|
|
if (actionItem.isSynchronous) {
|
|
$scope.$emit(events.PROVIDER_SHOW_LOADING);
|
|
}
|
|
screenConfigurationModel.executeProviderActionV3(actionItem.id, contextId, params).then(function (data) {
|
|
setOutputParams(actionItem, data);
|
|
var message = $filter('i18n')('screenConfiguration.providerActionExecuted', actionItem.label);
|
|
$scope.$emit(events.PROVIDER_HIDE_LOADING);
|
|
$log.topic('providerExecution', 'Show success message');
|
|
systemAlertService.success({ text: message, clear: true, hide: 10000 });
|
|
}).catch(function (error) {
|
|
$scope.$emit(events.PROVIDER_HIDE_LOADING);
|
|
systemAlertService.error({
|
|
text: (error.data && error.data.error) ? error.data.error : error.defaultMessage,
|
|
clear: false
|
|
});
|
|
});
|
|
};
|
|
$scope.executeActionFromExpressionCallback = function (params, actionItem, contextId) {
|
|
delete params.prompt;
|
|
if (actionItem.isSynchronous) {
|
|
$scope.$emit(events.PROVIDER_SHOW_LOADING);
|
|
}
|
|
screenConfigurationModel.executeProviderActionV3(actionItem.id, contextId, params).then(function (data) {
|
|
isExecutingProviderAction = false;
|
|
setOutputParams(actionItem, data);
|
|
var message = $filter('i18n')('screenConfiguration.providerActionExecutedFromExpression', actionItem.label);
|
|
$scope.$emit(events.PROVIDER_HIDE_LOADING);
|
|
$log.topic('providerExecution', 'Show success message');
|
|
systemAlertService.success({ text: message, clear: true, hide: 10000 });
|
|
executeQueuedProviderAction(actionItem);
|
|
}).catch(function (error) {
|
|
$scope.$emit(events.PROVIDER_HIDE_LOADING);
|
|
isExecutingProviderAction = false;
|
|
executeQueuedProviderAction(actionItem);
|
|
systemAlertService.error({
|
|
text: (error.data && error.data.error) ? error.data.error : error.defaultMessage,
|
|
clear: false
|
|
});
|
|
});
|
|
};
|
|
function executeQueuedProviderAction(actionItem) {
|
|
objectValueMapperService.clearProviderActionFieldName(actionItem.actionFieldName, actionItem.actionId);
|
|
clearProviderAction(actionItem);
|
|
if ($scope.providerActionsList.length) {
|
|
$timeout(function () {
|
|
$scope.launchActionFromExpression($scope.providerActionsList);
|
|
});
|
|
}
|
|
}
|
|
$scope.checkForOutputMapping = function (actionObj) {
|
|
var returnVal = false;
|
|
if (actionObj && actionObj.mappings && actionObj.mappings.length) {
|
|
if (!_.isUndefined(_.find(actionObj.mappings, { type: 'output' }))) {
|
|
returnVal = true;
|
|
}
|
|
}
|
|
return returnVal;
|
|
};
|
|
$scope.hide = function () {
|
|
promptModal.hide();
|
|
};
|
|
//whenever ticket is getting loaded or user clicks on cancel button of edit ticket this event is registered causing memory leak as well as firing multiple times.
|
|
if (!objectValueMapperService.isProviderActionEventRegistered()) {
|
|
objectValueMapperService.registerProviderActionCallExpressionEvent($rootScope.$on(events.PROVIDER_ACTION, function (event, data) {
|
|
if (data.length) {
|
|
$scope.providerActionsList = objectValueMapperService.getProviderActionsList();
|
|
if (_.size($scope.providerActionsList) && !isExecutingProviderAction) {
|
|
$scope.launchActionFromExpression($scope.providerActionsList);
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
// $scope.$on('$destroy', function () {
|
|
// unbindRootScopeListener();
|
|
// });
|
|
$scope.launchActionFromExpression = function (actionList) {
|
|
if (!_.isArray(actionList) || (actionList && actionList.length <= 0)) {
|
|
return;
|
|
}
|
|
// the expression may no longer be valid based on the previous actions output mappings,
|
|
// so re-evaluate expression before executing the next action
|
|
var value = expressionEvaluatorService.evaluate(actionList[0].expression);
|
|
if (value) {
|
|
isExecutingProviderAction = true;
|
|
$scope.launchAction(actionList[0].action, actionList[0].action.actionType, null, true);
|
|
}
|
|
else if (actionList[0] && actionList[0].action) {
|
|
objectValueMapperService.clearProviderActionFieldName(actionList[0].action.actionFieldName, actionList[0].action.actionId);
|
|
}
|
|
};
|
|
function clearProviderAction(actionItem) {
|
|
objectValueMapperService.clearProviderActionFromList(actionItem);
|
|
}
|
|
}]);
|
|
})();
|