1376 lines
70 KiB
JavaScript
1376 lines
70 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Created by igor.samulenko on 4/29/2014.
|
|
*/
|
|
(function () {
|
|
'use strict';
|
|
angular.module('adminModule')
|
|
.factory('screenConfigurationModel', ['$q', 'screenConfigurationService', 'configurationModel', 'i18nService', 'pwaModel',
|
|
function ($q, screenConfigurationService, configurationModel, i18nService, pwaModel) {
|
|
var screenConfigurationModel = {
|
|
appConfig: null,
|
|
screenList: null,
|
|
screensCacheByName: {},
|
|
fieldList: null,
|
|
fieldLabels: null,
|
|
selectedFieldList: null,
|
|
actionList: null,
|
|
actionOrder: 'custom',
|
|
actionUrlParams: null,
|
|
availableFieldsCache: {},
|
|
runtimeActionsCache: {},
|
|
dynamicSelectionFieldLabelsCache: {},
|
|
providerPromise: {},
|
|
providerHardReload: true,
|
|
allFieldsLoaded: {
|
|
basicTab: false,
|
|
datesTab: false
|
|
}
|
|
}, customLabelPromise = null, configByNamePromise = {}, fieldLabelDictionary = {}, screenTypeMap = {
|
|
incident: ScreenConfigurationVO.prototype.INCIDENT_VIEW_SCREEN,
|
|
workorder: ScreenConfigurationVO.prototype.WORK_ORDER_VIEW_SCREEN,
|
|
task: ScreenConfigurationVO.prototype.TASK_VIEW_SCREEN,
|
|
person: ScreenConfigurationVO.prototype.PERSON_DETAILS_SCREEN,
|
|
change: ScreenConfigurationVO.prototype.CHANGE_VIEW_SCREEN,
|
|
problem: ScreenConfigurationVO.prototype.PROBLEM_DETAILS_SCREEN,
|
|
knownerror: ScreenConfigurationVO.prototype.KNOWN_ERROR_DETAILS_SCREEN,
|
|
asset: ScreenConfigurationVO.prototype.ASSET_SCREEN,
|
|
create: {
|
|
incident: ScreenConfigurationVO.prototype.CREATE_INCIDENT_SCREEN,
|
|
change: ScreenConfigurationVO.prototype.CREATE_CHANGE_SCREEN,
|
|
workorder: ScreenConfigurationVO.prototype.CREATE_WORK_ORDER_SCREEN,
|
|
task: ScreenConfigurationVO.prototype.CREATE_TASK_SCREEN
|
|
}
|
|
}, dataSourceMap = {
|
|
incident: EntityVO.TYPE_INCIDENT,
|
|
workorder: EntityVO.TYPE_WORKORDER,
|
|
task: EntityVO.TYPE_TASK,
|
|
person: 'Person',
|
|
change: EntityVO.TYPE_CHANGE,
|
|
problem: EntityVO.TYPE_PROBLEM,
|
|
knownerror: EntityVO.TYPE_KNOWNERROR,
|
|
asset: 'Asset'
|
|
};
|
|
// editor actions
|
|
var ACTION_CREATE = 'create', ACTION_UPDATE = 'update', ACTION_REMOVE = 'remove';
|
|
/**
|
|
* Public functions
|
|
*/
|
|
/**
|
|
* Loads screen configuration
|
|
*/
|
|
var screenConfigurationPromise = $q.defer();
|
|
screenConfigurationModel.loadConfiguration = function () {
|
|
screenConfigurationModel.appConfig = {};
|
|
screenConfigurationModel.screenList = [];
|
|
// Using fromConfig flag, required by backend since this call is used
|
|
// only on screen configuration
|
|
return screenConfigurationService.loadConfiguration({ fromConfig: true })
|
|
.then(handleConfigurationLoadSuccess);
|
|
};
|
|
/**
|
|
* Get screen configuration for specific screen by name
|
|
* @param {string} screenName - name of the screen to load
|
|
* @param {boolean} force - if true, will enforce request for screen configuration to be sent
|
|
* @param {object} options - additional request params
|
|
* @return {Promise}
|
|
*/
|
|
screenConfigurationModel.loadScreenConfigurationByName = function (screenName, force, options) {
|
|
var cachedScreen = force ? angular.noop() : getScreenByName(screenName), screenPromise;
|
|
if (cachedScreen) {
|
|
screenPromise = $q.when(cachedScreen);
|
|
}
|
|
else {
|
|
if (!configByNamePromise[screenName]) {
|
|
configByNamePromise[screenName] = screenConfigurationService.loadScreenConfigurationByName(screenName, options)
|
|
.then(function (screenConfig) {
|
|
screenConfigurationModel.screensCacheByName[screenName] = screenConfig.screens[0];
|
|
screenConfigurationModel.screenList = _.reject(screenConfigurationModel.screensCacheByName, function (screen) {
|
|
return screen.datasource !== 'Person' && !configurationModel.isServerApplicationEnabled(screen.datasource.toLowerCase());
|
|
});
|
|
configByNamePromise[screenName] = null;
|
|
return angular.copy(screenConfigurationModel.screensCacheByName[screenName]);
|
|
});
|
|
}
|
|
screenPromise = configByNamePromise[screenName];
|
|
}
|
|
return screenPromise;
|
|
};
|
|
screenConfigurationModel.loadScreenConfigurationAndCustomFieldLabels = function (screenName, ticketType, force) {
|
|
var deferred = $q.defer();
|
|
screenConfigurationModel.loadScreenConfigurationByName(screenName, force)
|
|
.then(function () {
|
|
return screenConfigurationModel.loadFieldsLabels(ticketType);
|
|
})
|
|
.finally(function () {
|
|
deferred.resolve();
|
|
});
|
|
return deferred.promise;
|
|
};
|
|
/**
|
|
* Refreshes metadata for specific datasource
|
|
*
|
|
* @param {String} datasource
|
|
* @param {String} screenName - optional parameter, used for screens that support v2 calls only
|
|
* @returns {*}
|
|
*/
|
|
screenConfigurationModel.refreshMetadataForDatasource = function (datasource, screenName) {
|
|
var params = {
|
|
datasource: datasource
|
|
};
|
|
if (screenName) {
|
|
params.screen = screenName;
|
|
}
|
|
var refreshMeta = function () {
|
|
if (fieldLabelDictionary[datasource]) {
|
|
delete fieldLabelDictionary[datasource];
|
|
}
|
|
};
|
|
if (screenConfigurationModel.isV2CompatibleScreen(screenName)) {
|
|
return screenConfigurationService.refreshMetadataV2(params).then(refreshMeta);
|
|
}
|
|
else {
|
|
return screenConfigurationService.refreshMetadata(params).then(refreshMeta);
|
|
}
|
|
};
|
|
/**
|
|
* Loads field data required for custom area editor
|
|
* @param panel
|
|
* @returns {*}
|
|
*/
|
|
screenConfigurationModel.loadFields = function (panel) {
|
|
var availableFieldListPromise = screenConfigurationModel.loadAvailableFieldList(panel), selectedFieldListPromise = screenConfigurationModel.loadSelectedFieldList(panel);
|
|
return $q.all([availableFieldListPromise, selectedFieldListPromise]);
|
|
};
|
|
/**
|
|
* Loads list of fields available for selection
|
|
* @param {PanelVO} panel
|
|
*/
|
|
screenConfigurationModel.loadAvailableFieldList = function (panel) {
|
|
var query = { datasource: panel.dataSource }, promise;
|
|
if (panel.dataSource === 'Asset') {
|
|
query.assetType = panel.shortId;
|
|
if (panel.shortId === 'typeSpecific') {
|
|
query.classId = panel.classId;
|
|
}
|
|
}
|
|
if (screenConfigurationModel.isV2CompatibleScreen(panel.parentScreenName)) {
|
|
query.screen = panel.parentScreenName;
|
|
promise = screenConfigurationService.loadAvailableFieldListV2(query);
|
|
}
|
|
else {
|
|
promise = screenConfigurationService.loadAvailableFieldList(query);
|
|
}
|
|
return promise.then(handleAvailableFieldListLoadSuccess);
|
|
};
|
|
/**
|
|
* Loads available fields list for four new screens introduced in v2.0.
|
|
* @returns {Array<FieldVO>} - list of
|
|
*/
|
|
screenConfigurationModel.loadAvailableFieldListForAllNewScreens = function (force) {
|
|
var screensData = [];
|
|
if (configurationModel.isServerApplicationEnabled(EntityVO.TYPE_INCIDENT)) {
|
|
screensData.push({ datasource: EntityVO.TYPE_INCIDENT, screen: ScreenConfigurationVO.prototype.INCIDENT_VIEW_SCREEN }, { datasource: EntityVO.TYPE_INCIDENT, screen: ScreenConfigurationVO.prototype.CREATE_INCIDENT_SCREEN });
|
|
}
|
|
if (configurationModel.isServerApplicationEnabled(EntityVO.TYPE_CHANGE)) {
|
|
screensData.push({ datasource: EntityVO.TYPE_CHANGE, screen: ScreenConfigurationVO.prototype.CHANGE_VIEW_SCREEN }, { datasource: EntityVO.TYPE_CHANGE, screen: ScreenConfigurationVO.prototype.CREATE_CHANGE_SCREEN });
|
|
}
|
|
if (configurationModel.isServerApplicationEnabled(EntityVO.TYPE_WORKORDER)) {
|
|
screensData.push({ datasource: EntityVO.TYPE_WORKORDER, screen: ScreenConfigurationVO.prototype.WORK_ORDER_VIEW_SCREEN }, { datasource: EntityVO.TYPE_WORKORDER, screen: ScreenConfigurationVO.prototype.CREATE_WORK_ORDER_SCREEN });
|
|
}
|
|
if (configurationModel.isServerApplicationEnabled(EntityVO.TYPE_TASK)) {
|
|
screensData.push({ datasource: EntityVO.TYPE_TASK, screen: ScreenConfigurationVO.prototype.TASK_VIEW_SCREEN }, { datasource: EntityVO.TYPE_TASK, screen: ScreenConfigurationVO.prototype.CREATE_TASK_SCREEN });
|
|
}
|
|
var promises = {};
|
|
if (force) {
|
|
screensData.forEach(function (screenData) {
|
|
promises[screenData.screen] = screenConfigurationService.loadAvailableFieldListV2(screenData)
|
|
.then(function (availableFields) {
|
|
screenConfigurationModel.availableFieldsCache[screenData.screen] = availableFields;
|
|
});
|
|
});
|
|
}
|
|
else {
|
|
promises = [$q.when(screenConfigurationModel.availableFieldsCache)];
|
|
}
|
|
return $q.all(promises).then(function () {
|
|
return angular.copy(screenConfigurationModel.availableFieldsCache);
|
|
});
|
|
};
|
|
/**
|
|
* Loads Actions and Url params w.r.t to resource
|
|
* @param resourceType
|
|
*/
|
|
screenConfigurationModel.loadActions = function (resourceType) {
|
|
return screenConfigurationService.loadActions({ resourceType: resourceType }).then(handleActionsLoadSuccess);
|
|
};
|
|
screenConfigurationModel.loadActionUrlParams = function (resourceType) {
|
|
return screenConfigurationService.loadActionUrlParams({ resourceType: resourceType }).then(handleActionUrlParamsLoadSuccess);
|
|
};
|
|
/**
|
|
* Loads Actions V2 and Url params w.r.t to resource
|
|
* @param resourceType
|
|
*/
|
|
screenConfigurationModel.loadActionsNew = function (resourceType) {
|
|
if (!screenConfigurationModel.providerPromise[resourceType] || screenConfigurationModel.providerHardReload) {
|
|
screenConfigurationModel.providerPromise[resourceType] = screenConfigurationService.loadActionsNew({ resourceType: resourceType }).then(handleActionsLoadSuccess);
|
|
screenConfigurationModel.providerHardReload = false;
|
|
return screenConfigurationModel.providerPromise[resourceType];
|
|
}
|
|
else {
|
|
return screenConfigurationModel.providerPromise[resourceType];
|
|
}
|
|
};
|
|
/**
|
|
* Loads list of selected fields
|
|
* @param {PanelVO} panel
|
|
*/
|
|
screenConfigurationModel.loadSelectedFieldList = function (panel) {
|
|
var query = {
|
|
datasource: panel.dataSource
|
|
};
|
|
if (panel.dataSource === 'Asset') {
|
|
query.assetType = panel.shortId;
|
|
if (panel.shortId === 'typeSpecific') {
|
|
query.classId = panel.classId;
|
|
}
|
|
}
|
|
return screenConfigurationService.loadSelectedFieldList(query).then(handleSelectedFieldListLoadSuccess);
|
|
};
|
|
/**
|
|
* Loads fields labels
|
|
* @param {String} ticketType
|
|
*/
|
|
screenConfigurationModel.loadFieldsLabels = function (ticketType) {
|
|
var editTicketScreenName = screenTypeMap[ticketType], createTicketScreenName = screenTypeMap.create[ticketType];
|
|
var screen = _.find(screenConfigurationModel.screensCacheByName, function (scr) {
|
|
return [editTicketScreenName, createTicketScreenName].indexOf((scr || {}).name) !== -1;
|
|
});
|
|
var promise = $q.when(1);
|
|
if (screen) {
|
|
var dataSource = screen.datasource, cachedLabels = fieldLabelDictionary[dataSource];
|
|
if (cachedLabels) {
|
|
handleFieldLabelsLoadSuccess(cachedLabels, dataSource);
|
|
}
|
|
else {
|
|
if (customLabelPromise === null) {
|
|
customLabelPromise = screenConfigurationService
|
|
.loadFieldsLabels({ datasource: dataSource })
|
|
.then(function (labels) {
|
|
handleFieldLabelsLoadSuccess(labels, dataSource);
|
|
customLabelPromise = null;
|
|
return screenConfigurationModel.fieldLabels;
|
|
});
|
|
}
|
|
promise = customLabelPromise;
|
|
}
|
|
}
|
|
else {
|
|
console.log('Warning: screen configuration for ' + ticketType + ' not found.');
|
|
}
|
|
return promise;
|
|
};
|
|
screenConfigurationModel.loadMockDependantFieldMappings = function () {
|
|
return screenConfigurationService.loadMockDependantFieldMappings();
|
|
};
|
|
/**
|
|
* Loads fields labels
|
|
* @param {String} ticketType
|
|
* @param {String} menuName
|
|
* @param {Object} params
|
|
* @param {Object} dependencies
|
|
*/
|
|
screenConfigurationModel.loadDynamicSelectionFieldLabels = function (ticketType, menuName, searchText, dependencies, classId, fieldName, isNew, useChunk) {
|
|
var screen = getScreenForTicketType(isNew ? ('create.' + ticketType) : ticketType), params = {
|
|
datasource: screen ? screen.datasource : ticketType,
|
|
menuName: menuName,
|
|
searchText: searchText
|
|
};
|
|
function escapeRegExp(string) {
|
|
return string.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
|
}
|
|
if (classId) {
|
|
params.classId = classId;
|
|
}
|
|
if (screen) {
|
|
var dynamicFieldCache = screenConfigurationModel.dynamicSelectionFieldLabelsCache[fieldName];
|
|
useChunk = dynamicFieldCache && dynamicFieldCache.searchData && dynamicFieldCache.searchData.exceedsChunkSize ? true : useChunk;
|
|
// If chunk size exceeds, new call should be made for any non-matching text
|
|
if (!useChunk && angular.isDefined(dynamicFieldCache)
|
|
&& ((!dynamicFieldCache.searchData.exceedsChunkSize && _.startsWith(searchText, dynamicFieldCache.searchText))
|
|
|| (dynamicFieldCache.searchData.exceedsChunkSize && searchText === dynamicFieldCache.searchText))) {
|
|
if (dynamicFieldCache.datasource === params.datasource && _.isEqual(dependencies, dynamicFieldCache.dependencies)) {
|
|
var searchData = _.cloneDeep(dynamicFieldCache.searchData), escaped = escapeRegExp(searchText), formatted = escaped.replace(/%/g, '.*');
|
|
formatted = '.*' + formatted + '.*';
|
|
formatted = new RegExp('^' + formatted + '$', 'im');
|
|
var searchItemList = void 0;
|
|
if (searchData && Array.isArray(searchData)) {
|
|
searchItemList = searchData;
|
|
}
|
|
else if (searchData && searchData.items && Array.isArray(searchData.items)) {
|
|
searchItemList = searchData.items;
|
|
}
|
|
_.remove(searchItemList, function (field) {
|
|
//To support search using wildcard '%' also.
|
|
if (!field.displayLabel.match(formatted) && !field.value.match(formatted)) {
|
|
return true;
|
|
}
|
|
});
|
|
return $q.when(searchData);
|
|
}
|
|
}
|
|
return screenConfigurationService.loadDynamicSelectionFieldLabels(params, dependencies).then(function (data) {
|
|
screenConfigurationModel.dynamicSelectionFieldLabelsCache[fieldName] = {
|
|
searchText: searchText,
|
|
searchData: data,
|
|
datasource: params.datasource,
|
|
dependencies: dependencies
|
|
};
|
|
return { items: data.items, exceedsChunkSize: data.exceedsChunkSize };
|
|
});
|
|
}
|
|
else {
|
|
console.log('Warning: screen configuration for ' + ticketType + ' not found.');
|
|
return $q.reject();
|
|
}
|
|
};
|
|
/**
|
|
* Helper method, which marks fields as updated. Used for v2 customization save call
|
|
* @param {FieldVO} field
|
|
* @param {PanelVO} panel
|
|
*/
|
|
screenConfigurationModel.markFieldUpdated = function (field, panel) {
|
|
var isNewField = !field.id || panel.addedFields.some(function (aField) {
|
|
return field.id === aField.id;
|
|
});
|
|
if (!isNewField) {
|
|
field.wasUpdated = true;
|
|
}
|
|
};
|
|
/**
|
|
* Checks whether particular screen supports v2 res calls
|
|
*
|
|
* @param {string} screenName - name of the screen
|
|
* @returns {boolean}
|
|
*/
|
|
screenConfigurationModel.isV2CompatibleScreen = function (screenName) {
|
|
return ScreenConfigurationVO.prototype.isV2Compatible(screenName);
|
|
};
|
|
/**
|
|
* Saves custom field configuration for panel
|
|
* @param {PanelVO} panel
|
|
*/
|
|
screenConfigurationModel.savePanelConfiguration = function (panel) {
|
|
var updatedFields = [], addedFields = [], removedFields = [], useV2Flow = screenConfigurationModel.isV2CompatibleScreen(panel.parentScreenName);
|
|
if (useV2Flow) {
|
|
var fields = getPanelUpdatedFieldsForV2Call(panel);
|
|
fields.forEach(function (field) {
|
|
addUpdatedField(field, panel);
|
|
});
|
|
}
|
|
else {
|
|
// update field ordering
|
|
panel.fields.forEach(function (field, index) {
|
|
var members = [];
|
|
field.displayOrder = index;
|
|
field.groupMember = false;
|
|
if (field.dependency) {
|
|
for (var j = 0; j < field.dependency.length; j++) {
|
|
delete field.dependency[j].availability;
|
|
delete field.dependency[j].fieldUnavailableOn;
|
|
}
|
|
}
|
|
// Handle group fields, but skip this if field is a widget
|
|
if (!field.isWidget()) {
|
|
field.members.forEach(function (gfield, gindex) {
|
|
var temp = { "name": gfield.name };
|
|
gfield.displayOrder = gindex;
|
|
gfield.groupMember = true;
|
|
if (gfield.dependency) {
|
|
for (var j = 0; j < gfield.dependency.length; j++) {
|
|
delete gfield.dependency[j].availability;
|
|
delete gfield.dependency[j].fieldUnavailableOn;
|
|
}
|
|
}
|
|
if (gfield.id) {
|
|
addUpdatedField(gfield, panel);
|
|
if (gfield.current) {
|
|
temp = gfield.current;
|
|
}
|
|
}
|
|
members.push(temp);
|
|
});
|
|
field.members = members;
|
|
}
|
|
if (field.id) {
|
|
addUpdatedField(field, panel);
|
|
}
|
|
});
|
|
}
|
|
function addUpdatedField(field, panel) {
|
|
if (panel.shortId !== 'typeSpecific') {
|
|
delete field.extension;
|
|
}
|
|
if (useV2Flow) {
|
|
updatedFields.push(angular.extend({
|
|
state: ACTION_UPDATE,
|
|
screenId: panel.parentScreenId,
|
|
screenName: panel.parentScreenName,
|
|
panelId: panel.id,
|
|
panelName: panel.name,
|
|
datasource: panel.dataSource
|
|
}, new GalileoFieldV2VO().build(field)));
|
|
}
|
|
else {
|
|
updatedFields.push(angular.extend({
|
|
state: ACTION_UPDATE,
|
|
areaId: panel.id
|
|
}, new GalileoFieldVO().build(field)));
|
|
}
|
|
}
|
|
if (useV2Flow) {
|
|
addedFields = getPanelAddedFieldsForV2Call(panel);
|
|
removedFields = getPanelRemovedFieldsForV2Call(panel);
|
|
}
|
|
else {
|
|
addedFields = panel.addedFields.map(function (field) {
|
|
var newField;
|
|
if (panel.shortId !== 'typeSpecific') {
|
|
delete field.extension;
|
|
}
|
|
newField = angular.extend({
|
|
state: ACTION_CREATE,
|
|
areaId: panel.id
|
|
}, new GalileoFieldVO().build(field));
|
|
return newField;
|
|
});
|
|
removedFields = panel.removedFields.map(function (field) {
|
|
var removedField;
|
|
if (panel.shortId !== 'typeSpecific') {
|
|
delete field.extension;
|
|
}
|
|
removedField = angular.extend({
|
|
state: ACTION_REMOVE,
|
|
areaId: panel.id
|
|
}, new GalileoFieldVO().build(field));
|
|
return removedField;
|
|
});
|
|
}
|
|
if (!useV2Flow) {
|
|
addedFields.forEach(function (field, index) {
|
|
var fieldIndex = _.findIndex(updatedFields, { name: field.name });
|
|
if (fieldIndex != -1) {
|
|
updatedFields = _.slice(updatedFields, 0, fieldIndex);
|
|
}
|
|
});
|
|
}
|
|
var saveFieldConfiguration = useV2Flow ? screenConfigurationService.saveFieldConfigurationV2 : screenConfigurationService.saveFieldConfiguration;
|
|
return saveFieldConfiguration([].concat(removedFields, addedFields, updatedFields), panel.shortId)
|
|
.catch(function (e) {
|
|
throw e;
|
|
})
|
|
.finally(function () {
|
|
screenConfigurationModel.clearActionsListCacheForType(panel.dataSource.toLowerCase());
|
|
});
|
|
};
|
|
function getPanelFieldsV2Call(panel, action) {
|
|
var fields = [];
|
|
if (action === ACTION_CREATE) {
|
|
fields = panel.addedFields;
|
|
}
|
|
else if (action === ACTION_REMOVE) {
|
|
fields = panel.removedFields;
|
|
}
|
|
return fields.reduce(function (acc, field) {
|
|
var fieldCopy = _.cloneDeep(field);
|
|
if (field.isGroupField()) {
|
|
// Should use original members list for remove action, because user can firs remove group members
|
|
// manually and then remove group, so members array will be empty, which is wrong
|
|
var groupMembers = (action === ACTION_REMOVE) ? field.initialMembers : field.members;
|
|
fieldCopy.members = groupMembers.map(function (member) {
|
|
return new GalileoFieldV2VO().build(member);
|
|
});
|
|
}
|
|
// Don't need to send group members separately.
|
|
// Group field members array will be used on the backend
|
|
if (!field.isGroupMember()) {
|
|
acc.push(angular.extend({
|
|
state: action,
|
|
screenId: panel.parentScreenId,
|
|
screenName: panel.parentScreenName,
|
|
panelId: panel.id,
|
|
panelName: panel.name,
|
|
datasource: panel.dataSource
|
|
}, new GalileoFieldV2VO().build(fieldCopy)));
|
|
}
|
|
return acc;
|
|
}, []);
|
|
}
|
|
function getPanelAddedFieldsForV2Call(panel) {
|
|
return getPanelFieldsV2Call(panel, ACTION_CREATE);
|
|
}
|
|
function getPanelRemovedFieldsForV2Call(panel) {
|
|
return getPanelFieldsV2Call(panel, ACTION_REMOVE);
|
|
}
|
|
function getPanelUpdatedFieldsForV2Call(panel) {
|
|
return panel.fields.reduce(function (acc, field, index) {
|
|
var fieldMembers = [];
|
|
if (field.displayOrder !== index) {
|
|
field.displayOrder = index;
|
|
screenConfigurationModel.markFieldUpdated(field, panel);
|
|
}
|
|
if (field.dependency) {
|
|
for (var j = 0; j < field.dependency.length; j++) {
|
|
delete field.dependency[j].availability;
|
|
delete field.dependency[j].fieldUnavailableOn;
|
|
}
|
|
}
|
|
// Handle group fields, but skip this if field is a widget
|
|
if (field.isGroupField()) {
|
|
fieldMembers = field.members.map(function (gfield, gindex) {
|
|
if (gfield.displayOrder !== gindex) {
|
|
gfield.displayOrder = gindex;
|
|
screenConfigurationModel.markFieldUpdated(gfield, panel);
|
|
}
|
|
if (gfield.dependency) {
|
|
for (var j = 0; j < gfield.dependency.length; j++) {
|
|
delete gfield.dependency[j].availability;
|
|
delete gfield.dependency[j].fieldUnavailableOn;
|
|
}
|
|
}
|
|
if (!gfield.id || gfield.wasUpdated) {
|
|
screenConfigurationModel.markFieldUpdated(field, panel);
|
|
}
|
|
return new GalileoFieldV2VO().build(gfield);
|
|
});
|
|
}
|
|
if (field.id && field.wasUpdated) {
|
|
var fieldCopy = _.cloneDeep(field);
|
|
fieldCopy.members = fieldMembers;
|
|
acc.push(fieldCopy);
|
|
}
|
|
return acc;
|
|
}, []);
|
|
}
|
|
/**
|
|
* Saves custom action configuration
|
|
* @param {PanelVO} panel
|
|
*/
|
|
screenConfigurationModel.saveActionConfiguration = function (actionList, actionOrder) {
|
|
var actionObj = {
|
|
actionOrder: actionOrder,
|
|
actionList: []
|
|
};
|
|
actionList.forEach(function (action) {
|
|
delete action.isOpen;
|
|
actionObj.actionList.push(action);
|
|
});
|
|
return screenConfigurationService.saveActionConfiguration(actionObj).then(handleActionsLoadSuccess);
|
|
};
|
|
/**
|
|
+ * Saves custom action configuration V2
|
|
+ * @param {PanelVO} panel
|
|
+
|
|
*/
|
|
screenConfigurationModel.saveFieldConfigurationV2 = function (actionList, actionOrder) {
|
|
var actionObj = {
|
|
actionOrder: actionOrder,
|
|
actionList: []
|
|
};
|
|
actionList.forEach(function (action) {
|
|
delete action.isOpen;
|
|
actionObj.actionList.push(action);
|
|
});
|
|
return screenConfigurationService.saveFieldConfigurationV2(actionObj).then(handleActionsLoadSuccess);
|
|
};
|
|
/**
|
|
* Finds a panel with specified name
|
|
* @param {String} panelId
|
|
*/
|
|
screenConfigurationModel.getPanelById = function (panelId) {
|
|
var screenName = panelId.split('.')[0];
|
|
var panelName = panelId.split('.')[1];
|
|
var screen = getScreenByName(screenName);
|
|
return screen ? screen.getPanelByName(panelName) : null;
|
|
};
|
|
/**
|
|
* Get list of editable fields for screen with specified name
|
|
* @param {String} screenName
|
|
* @return {Array} fields
|
|
*/
|
|
screenConfigurationModel.getEditableFieldsForScreen = function (screenName) {
|
|
var screen = getScreenByName(screenName);
|
|
return _.filter(screen ? screen.getFields() : [], { editable: true });
|
|
};
|
|
/**
|
|
* Get list of required fields for screen with specified name
|
|
* @param {String} screenName
|
|
* @return {Array} fields
|
|
*/
|
|
screenConfigurationModel.getRequiredFieldsForScreen = function (screenName) {
|
|
var screen = getScreenByName(screenName);
|
|
return _.filter(screen ? screen.getFields() : [], { required: true });
|
|
};
|
|
/**
|
|
* Get list of available fields for screen with specified name
|
|
* @param screenName
|
|
* @param {Array<FieldVO>} availableFields - optional param of available fields to build list from
|
|
* @return {Array} fields
|
|
*/
|
|
screenConfigurationModel.getAvailableFieldsForScreen = function (screenName, availableFields) {
|
|
var screen = getScreenByName(screenName);
|
|
var fields = screen ? screen.getFields() : [];
|
|
return (availableFields || screenConfigurationModel.fieldList).filter(function (field) {
|
|
return !_.filter(fields, { name: field.name, dataType: field.dataType }).length;
|
|
});
|
|
};
|
|
/**
|
|
* Get list of available fields for screen with specified name
|
|
* @param screenName
|
|
* @return {Array} fields
|
|
*/
|
|
screenConfigurationModel.getFieldByName = function (screenName, fieldName) {
|
|
var screen = getScreenByName(screenName);
|
|
var fields = screen ? screen.getFields() : [];
|
|
return _.find(fields, { name: fieldName });
|
|
};
|
|
/**
|
|
* Get list of available fields for screen with specified name and classId
|
|
* @param screenName, classId
|
|
* @return {Array} fields
|
|
*/
|
|
screenConfigurationModel.getAvailableFieldsForScreenByClassId = function (screenName, classId) {
|
|
var screen = getScreenByName(screenName);
|
|
var fields = screen ? screen.getFields() : [];
|
|
return screenConfigurationModel.fieldList.filter(function (field) {
|
|
var i, j;
|
|
var selectedfields = _.filter(fields, { name: field.name });
|
|
if (!selectedfields.length) {
|
|
return true;
|
|
}
|
|
else {
|
|
for (i = 0; i < selectedfields.length; i++) {
|
|
for (j = 0; j < selectedfields[i].extension.length; j++) {
|
|
if (selectedfields[i].extension[j].classId === classId.name) {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
};
|
|
/**
|
|
* Get assignment panel descriptor
|
|
*
|
|
* @param ticket
|
|
* @returns {ScreenConfigurationVO}
|
|
*/
|
|
screenConfigurationModel.getAssignmentPanel = function (ticket) {
|
|
var panel;
|
|
if (ticket.type) {
|
|
var screen = getScreenForTicketType(ticket.type);
|
|
if (screen) {
|
|
panel = screen.getPanelByName('Assignment');
|
|
}
|
|
}
|
|
return panel || {};
|
|
};
|
|
/**
|
|
* Get Avialable accelerators V2
|
|
*
|
|
* @param type
|
|
* @param {String} screenName - screen name for accelerators
|
|
* @returns OOTB fields + avilable custom fields map
|
|
*/
|
|
screenConfigurationModel.getAccelerators = function (type, screenName) {
|
|
var promise;
|
|
// if (screenConfigurationModel.isV2CompatibleScreen(screenName) && ([ScreenConfigurationVO.prototype.WORK_ORDER_VIEW_SCREEN, ScreenConfigurationVO.prototype.TASK_VIEW_SCREEN].indexOf(screenName) === -1)) {
|
|
if (screenConfigurationModel.isV2CompatibleScreen(screenName)) {
|
|
promise = screenConfigurationService.getNewAcceleratorsByType({
|
|
datasource: type,
|
|
screen: screenName
|
|
}).then(function (data) {
|
|
return data;
|
|
});
|
|
}
|
|
else {
|
|
promise = screenConfigurationService.getAcceleratorsByType({ datasource: type }).then(function (data) {
|
|
return data;
|
|
});
|
|
}
|
|
return promise;
|
|
};
|
|
/**
|
|
* Collect field value changes
|
|
*
|
|
* @param {Array} changedFields
|
|
* @param {Object} originalFields
|
|
*/
|
|
screenConfigurationModel.collectChanges = function (changedFields, originalFields, ticket) {
|
|
var changes = {};
|
|
_.forEach(changedFields, function (field) {
|
|
var isGroupMember = field.isGroupMember();
|
|
if (field.editable || isGroupMember) {
|
|
var newValue = field.getValue(), oldValue = originalFields ? originalFields[field.name] : '', valueChanged = (isValid(newValue) && (newValue !== oldValue)) || (newValue === null && isValid(oldValue) && oldValue !== '');
|
|
if (valueChanged || isGroupMember) {
|
|
if (field.type === 'category') {
|
|
var category = getCategoryValue(newValue);
|
|
//Asset and knowledge needs to be handled separately as currently a seperate call is made to specially save
|
|
//their categories (at least for assets)
|
|
if (category) {
|
|
if (_.find(ticket.resCategorizations, { name: category.name })) {
|
|
if (changes.resCategorizations instanceof Array) {
|
|
changes.resCategorizations.push(category);
|
|
}
|
|
else {
|
|
changes.resCategorizations = [category];
|
|
}
|
|
}
|
|
else if (_.find(ticket.categorizations, { name: category.name })) {
|
|
if (changes.categorizations instanceof Array) {
|
|
changes.categorizations.push(category);
|
|
}
|
|
else {
|
|
changes.categorizations = [category];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if (field.dataType === 'widget') {
|
|
_.forEach(field.members, function (member) {
|
|
changes[member.name] = field.value[member.name];
|
|
});
|
|
}
|
|
else {
|
|
changes[field.name] = newValue;
|
|
}
|
|
if (field.isMenuField() && newValue === '') { //special handling for menu fields, they cannot be '', null or menuItem
|
|
changes[field.name] = null;
|
|
}
|
|
if (field.linkedFieldExist()) {
|
|
changes[field.valueField] = field.getLinkedValue();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
return changes;
|
|
};
|
|
screenConfigurationModel.composePanelId = function (ticketType, panelName) {
|
|
return screenConfigurationModel.getScreenNameByTicketType(ticketType) + '.' + panelName;
|
|
};
|
|
/**
|
|
* Init custom field values from ticket data
|
|
*
|
|
* @param {Array} fields
|
|
* @param {TicketVO} ticket
|
|
*/
|
|
screenConfigurationModel.initFieldValues = function (fields, ticket, metadata, fromAssignment) {
|
|
var ootbMappingKey, setValuesdefer = $q.defer(), noOfFieldsSet = 0;
|
|
if (fields && fields.length > 0) {
|
|
var fieldValues;
|
|
_.each(fields, function (field) {
|
|
if ((ticket.type === 'incident' || ticket.type === 'change') && field.name === 'summary') {
|
|
field.charLimit = 100;
|
|
}
|
|
else if (ticket.type === 'task' && field.name === 'summary') {
|
|
field.charLimit = 255;
|
|
}
|
|
if (field.isWidget()) {
|
|
field.label = i18nService.getLocalizedString('field.widget.' + field.name + '.label');
|
|
}
|
|
if (field.type === FieldVO.prototype.PERSON_NAME) {
|
|
var fieldName = field.name === 'requestedFor' ? 'customer' : field.name;
|
|
fieldValues = ticket[fieldName];
|
|
if (field.name === "contact") {
|
|
if (_.isEmpty(ticket[fieldName])) {
|
|
fieldValues = undefined;
|
|
}
|
|
}
|
|
else if (field.isAssigneeWidget()) {
|
|
field.primaryKey = getOotbPrimaryKeyForWidget(field, metadata);
|
|
fieldValues = ticket[field.primaryKey];
|
|
}
|
|
field.setValue(fieldValues);
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.PRIORITY) {
|
|
field.setValue({
|
|
impact: ticket.impact,
|
|
urgency: ticket.urgency,
|
|
priority: ticket.priority
|
|
});
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.TICKET_CLASS) {
|
|
field.setValue({
|
|
timing: ticket.timing,
|
|
timingReason: ticket.timingReason
|
|
});
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.AFFECTED_ASSET) {
|
|
fieldValues = {
|
|
'ci': ticket[field.name],
|
|
'company': ticket.company,
|
|
'customer': ticket.customer,
|
|
'ticketType': ticket.type
|
|
};
|
|
if (_.isEmpty(ticket[field.name]) || _.isEmpty(ticket[field.name].name)) {
|
|
fieldValues.ci = null;
|
|
}
|
|
field.setValue(fieldValues);
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.TICKET_LOCATION) {
|
|
if (ticket.location) {
|
|
fieldValues = {
|
|
'siteId': ticket.location.siteId,
|
|
'region': ticket.location.region,
|
|
'siteGroup': ticket.location.siteGroup,
|
|
'name': ticket.location.name,
|
|
'companyName': ticket.location.companyName,
|
|
'address': ticket.location.address
|
|
};
|
|
}
|
|
else {
|
|
fieldValues = {
|
|
'siteId': null,
|
|
'region': null,
|
|
'siteGroup': null,
|
|
'name': null,
|
|
'companyName': null,
|
|
'address': null
|
|
};
|
|
}
|
|
field.setValue(fieldValues);
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.IMPACTED_AREAS) {
|
|
field.setValue({ impactedAreas: ticket.impactedAreas });
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.CATEGORY_FIELD) {
|
|
field.setValue(_.findLast(_.cloneDeep(ticket.allCategories), { name: field.getCategorizationPropertyName() }));
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.PERSON_SITE) {
|
|
var siteInfo = _.cloneDeep(ticket.customer.site);
|
|
siteInfo = siteInfo ? siteInfo : {};
|
|
var siteValue = {
|
|
site: {
|
|
name: siteInfo.name,
|
|
id: siteInfo.siteId,
|
|
attributeMap: {
|
|
siteAddress: siteInfo.address,
|
|
regionName: siteInfo.region,
|
|
siteGroupName: siteInfo.siteGroup
|
|
}
|
|
},
|
|
siteGroup: {
|
|
name: siteInfo.siteGroup,
|
|
attributeMap: {
|
|
regionName: siteInfo.region
|
|
}
|
|
},
|
|
region: {
|
|
name: siteInfo.region
|
|
},
|
|
company: ticket.customer.company
|
|
};
|
|
field.setValue(siteValue);
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.PERSON_LOCATION_MAP) {
|
|
ticket.customer.site && field.setValue(ticket.customer.site.address);
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.POI_LOCATION) {
|
|
field.setValue(_.cloneDeep(ticket.location));
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.CATEGORY_COMPANY) {
|
|
if (ticket.locationCompany && ticket.locationCompany.name) {
|
|
field.setValue(ticket.locationCompany.name);
|
|
}
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.type === FieldVO.prototype.TASK_PHASE) {
|
|
if (ticket.selectedPhase) {
|
|
field.setValue({
|
|
phaseGuid: ticket.selectedPhase.guid,
|
|
phaseName: ticket.selectedPhase.name
|
|
});
|
|
}
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.isSupportGroupWidget()) {
|
|
field.primaryKey = getOotbPrimaryKeyForWidget(field, metadata);
|
|
var supportGroup = angular.copy(ticket[field.primaryKey]);
|
|
if (supportGroup) {
|
|
supportGroup.supportGroups = supportGroup.name || supportGroup.supportGroups;
|
|
}
|
|
field.setValue(supportGroup);
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (field.isGroupField()) {
|
|
screenConfigurationModel.initFieldValues(field.members, ticket, metadata);
|
|
noOfFieldsSet++;
|
|
}
|
|
else {
|
|
if (field.isWidget() && field.members.length > 0) {
|
|
field.setValue(getOotbFieldValue(ticket, metadata, field));
|
|
noOfFieldsSet++;
|
|
}
|
|
else {
|
|
if (metadata) {
|
|
ootbMappingKey = metadata.ootbMapping[field.name];
|
|
}
|
|
if (!field.ootb) {
|
|
if (!fromAssignment) {
|
|
// from assignment blade no need to update
|
|
field.setValue(_.get(ticket.customFields, field.name));
|
|
}
|
|
noOfFieldsSet++;
|
|
}
|
|
else if (ootbMappingKey && ootbMappingKey.length > 0) { //if field is ootb
|
|
field.setValue(getFieldValue(field.name, ootbMappingKey, ticket));
|
|
if (field.name === 'assignee' || field.name === 'assigneeName' || field.name === 'managerName') {
|
|
var tempFieldName = ootbMappingKey[0].split('.');
|
|
field.assigneeLoginId = ticket[tempFieldName[0]] ? ticket[tempFieldName[0]].loginId : null;
|
|
}
|
|
noOfFieldsSet++;
|
|
}
|
|
else {
|
|
if (!fromAssignment) {
|
|
// from assignment blade no need to update
|
|
field.setValue(ticket[field.name]);
|
|
}
|
|
noOfFieldsSet++;
|
|
}
|
|
}
|
|
}
|
|
if (noOfFieldsSet === fields.length) {
|
|
setValuesdefer.resolve();
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
setValuesdefer.resolve();
|
|
}
|
|
return setValuesdefer.promise;
|
|
};
|
|
/**
|
|
* Update ticket data from custom field values
|
|
*
|
|
* @param {TicketVO} ticket
|
|
* @param {Object} changes
|
|
*/
|
|
screenConfigurationModel.updateTicketData = function (ticket, changes) {
|
|
if (_.size(changes)) {
|
|
if (!ticket.customFields) {
|
|
ticket.customFields = {};
|
|
}
|
|
_.forOwn(changes, function (value, fieldName) {
|
|
ticket.customFields[fieldName] = value;
|
|
});
|
|
}
|
|
};
|
|
/**
|
|
* Check if all required fields are filled
|
|
* @param ticket
|
|
*/
|
|
screenConfigurationModel.ticketDataIsValid = function (ticket) {
|
|
var screenName = screenConfigurationModel.getScreenNameByTicketType(ticket.type);
|
|
var requiredFields = screenConfigurationModel.getRequiredFieldsForScreen(screenName);
|
|
var result = true;
|
|
_.each(requiredFields, function (field) {
|
|
if (!field.isCheckboxField()) {
|
|
result = result && isValid(ticket.customFields[field.name]);
|
|
}
|
|
});
|
|
return result;
|
|
};
|
|
/**
|
|
* Check the number of reguired fields missing
|
|
* @param ticket
|
|
*/
|
|
screenConfigurationModel.ticketNumOfRequiredFieldMissing = function (ticket) {
|
|
var screenName = screenConfigurationModel.getScreenNameByTicketType(ticket.type);
|
|
var requiredFields = screenConfigurationModel.getRequiredFieldsForScreen(screenName);
|
|
var numOfRequiredFieldMissing = 0;
|
|
_.each(requiredFields, function (field) {
|
|
if (!isValid(ticket.customFields[field.name])) {
|
|
numOfRequiredFieldMissing += 1;
|
|
}
|
|
});
|
|
return numOfRequiredFieldMissing;
|
|
};
|
|
/**
|
|
* Load actions for record for runtime menu
|
|
* @param resourceType
|
|
* @param refreshData
|
|
*/
|
|
screenConfigurationModel.loadActionsForRuntime = function (resourceType, refreshData) {
|
|
return executeLoadActionsForRuntime(false, resourceType, refreshData);
|
|
};
|
|
/**
|
|
* Load actions for record for runtime menu
|
|
* @param resourceType
|
|
* @param refreshData
|
|
*/
|
|
screenConfigurationModel.loadActionsForRuntimeV2 = function (resourceType, refreshData) {
|
|
return executeLoadActionsForRuntime(true, resourceType, refreshData);
|
|
};
|
|
/**
|
|
* Gets runtime actions for new and old screen types
|
|
* @param {Boolean} useV2Call - should be true for v2 screens, otherwise false. Controls corresponding method on service
|
|
* @param {String} resourceType - ticket type to load actions for
|
|
* @param {Boolean} refreshData - should be true, when cached value should be ignored and should be retrieved from server
|
|
* @returns {Promise}
|
|
*/
|
|
function executeLoadActionsForRuntime(useV2Call, resourceType, refreshData) {
|
|
var getActionsMethod = useV2Call ? 'loadActionsNew' : 'loadActions', cachedActions = screenConfigurationModel.runtimeActionsCache[resourceType];
|
|
if (!refreshData && cachedActions) {
|
|
return $q.when(cachedActions);
|
|
}
|
|
var actionsPromise = screenConfigurationService[getActionsMethod]({ resourceType: resourceType })
|
|
.then(function (items) {
|
|
screenConfigurationModel.runtimeActionsCache[resourceType] = items;
|
|
});
|
|
screenConfigurationModel.runtimeActionsCache[resourceType] = actionsPromise;
|
|
return screenConfigurationModel.runtimeActionsCache[resourceType];
|
|
}
|
|
/**
|
|
* Clears actions list from local cache by type
|
|
*
|
|
* @param {String} type - ticket type to clear cache for
|
|
*/
|
|
screenConfigurationModel.clearActionsListCacheForType = function (type) {
|
|
if (screenConfigurationModel.runtimeActionsCache[type]) {
|
|
delete screenConfigurationModel.runtimeActionsCache[type];
|
|
}
|
|
};
|
|
/**
|
|
* Execute provider action
|
|
* @param actionId
|
|
* @param resourceId
|
|
*/
|
|
screenConfigurationModel.executeProviderAction = function (actionId, resourceId) {
|
|
return screenConfigurationService.executeProviderAction(actionId, resourceId);
|
|
};
|
|
screenConfigurationModel.executeProviderActionV3 = function (actionId, resourceId, params) {
|
|
return screenConfigurationService.executeProviderActionV3(actionId, resourceId, params);
|
|
};
|
|
screenConfigurationModel.getSmartReporterUrl = function () {
|
|
return screenConfigurationService.getSmartReporterUrl();
|
|
};
|
|
screenConfigurationModel.getExternalUrl = function (urlName) {
|
|
if (screenConfigurationModel.externalUrl) {
|
|
return $q.when(screenConfigurationModel.externalUrl[urlName]);
|
|
}
|
|
else {
|
|
return screenConfigurationService.getExternalUrl().then(function (url) {
|
|
if (!screenConfigurationModel.externalUrl) {
|
|
screenConfigurationModel.externalUrl = url;
|
|
}
|
|
return url[urlName];
|
|
});
|
|
}
|
|
};
|
|
/**
|
|
* Get List Of Action Templates Metadata based on resourceType
|
|
* @param withMetadata
|
|
* @param resourceType
|
|
*/
|
|
screenConfigurationModel.getTemplateList = function (withMetadata, resourceType) {
|
|
return screenConfigurationService.getTemplateList({ withMetadata: withMetadata, resourceType: resourceType });
|
|
};
|
|
/**
|
|
* Get List Of Action Templates Metadata based on templateId
|
|
* @param templateId
|
|
*/
|
|
screenConfigurationModel.getTemplateById = function (templateId) {
|
|
return screenConfigurationService.getTemplateById({ templateId: templateId });
|
|
};
|
|
/**
|
|
* Get Existing Action Container
|
|
* @param resourceType
|
|
* @param supportedPlatforms
|
|
*/
|
|
screenConfigurationModel.getExistingContainer = function (resourceType, supportedPlatforms) {
|
|
return screenConfigurationService.getExistingContainer({ resourceType: resourceType, supportedPlatforms: supportedPlatforms });
|
|
};
|
|
/**
|
|
* Create custom action Url
|
|
* @param actionOrder
|
|
*/
|
|
screenConfigurationModel.createUrlAction = function (actionList, actionOrder, resourceType) {
|
|
var actionObj = {
|
|
actionOrder: actionOrder,
|
|
actionList: actionList,
|
|
resourceType: resourceType
|
|
};
|
|
return screenConfigurationService.createUrlAction(actionObj).then(handleActionsLoadSuccess);
|
|
};
|
|
screenConfigurationModel.refreshServerCache = function () {
|
|
return screenConfigurationService.refreshServerCache();
|
|
};
|
|
function getOotbPrimaryKeyForWidget(field, metadata) {
|
|
var ootbMappingKey, widgetMember = field.members[0];
|
|
if (widgetMember) {
|
|
ootbMappingKey = _.last(metadata.ootbMapping[widgetMember.name]);
|
|
return _.head(ootbMappingKey.split('.'));
|
|
}
|
|
return '';
|
|
}
|
|
function getOotbFieldValue(ticket, metadata, field) {
|
|
if (field.members.length > 0) {
|
|
var ticketFieldValue = {};
|
|
field.members.forEach(function (member) {
|
|
var ootbMappingKey = metadata.ootbMapping[member.name];
|
|
ticketFieldValue[member.name] = (ootbMappingKey && ootbMappingKey.length > 0)
|
|
? getFieldValue(field.name, ootbMappingKey, ticket) : ticket[member.name];
|
|
});
|
|
return ticketFieldValue;
|
|
}
|
|
}
|
|
function getFieldValue(name, ootbMappingKey, ticket) {
|
|
var ticketCopy = _.cloneDeep(ticket);
|
|
if (name.indexOf('CategoryTier') !== -1 || name === 'resProductName' || (_.startsWith(_.last(ootbMappingKey), 'categorizations'))) {
|
|
if (!ticketCopy.categorizations.tiers) {
|
|
ticketCopy.categorizations.tiers = {};
|
|
ticketCopy.categorizations.forEach(function (categorization) {
|
|
_.extend(ticketCopy.categorizations.tiers, categorization.tiers);
|
|
});
|
|
}
|
|
if (ticketCopy.resCategorizations && !ticketCopy.resCategorizations.tiers) {
|
|
ticketCopy.resCategorizations.tiers = {};
|
|
ticketCopy.resCategorizations.forEach(function (resCategorization) {
|
|
_.extend(ticketCopy.resCategorizations.tiers, resCategorization.tiers);
|
|
});
|
|
}
|
|
}
|
|
return _.get(ticketCopy, _.last(ootbMappingKey));
|
|
}
|
|
/**
|
|
* Private functions
|
|
*/
|
|
function collectTiersValues(listOfTiers) {
|
|
var tiers = {};
|
|
_.forEach(listOfTiers, function (tier) {
|
|
tiers[tier.name] = tier.selectedValue;
|
|
});
|
|
return tiers;
|
|
}
|
|
/**
|
|
* Get category values in the format expected by server
|
|
*/
|
|
function getCategoryValue(category) {
|
|
if (category.dirty) {
|
|
var cat = {
|
|
name: category.name,
|
|
tiers: collectTiersValues(category.listOfTiers)
|
|
};
|
|
if (category.primary) {
|
|
cat.primary = true;
|
|
}
|
|
if (category.company) {
|
|
cat.company = category.company;
|
|
}
|
|
return cat;
|
|
}
|
|
return null;
|
|
}
|
|
/**
|
|
* Get screen configuration by specified name
|
|
* @param {String} screenName
|
|
* @returns {ScreenConfigurationVO}
|
|
*/
|
|
function getScreenByName(screenName) {
|
|
return angular.copy(screenConfigurationModel.screensCacheByName[screenName]);
|
|
}
|
|
/**
|
|
* Returns true if value is valid
|
|
* @param value
|
|
* @returns {boolean}
|
|
*/
|
|
function isValid(value) {
|
|
return angular.isDefined(value) && value !== null;
|
|
}
|
|
screenConfigurationModel.getScreenNameByTicketType = function (ticketType) {
|
|
return _.get(screenTypeMap, ticketType);
|
|
};
|
|
/**
|
|
* Get screen configuration for specified ticket type
|
|
* @param {String} ticketType
|
|
* @return {ScreenConfigurationVO} screen configuration
|
|
*/
|
|
function getScreenForTicketType(ticketType) {
|
|
var screenName = screenConfigurationModel.getScreenNameByTicketType(ticketType);
|
|
return getScreenByName(screenName);
|
|
}
|
|
/**
|
|
* Handler for success load of app config
|
|
* @param {ApplicationConfigurationVO} appConfig
|
|
*/
|
|
function handleConfigurationLoadSuccess(appConfig) {
|
|
screenConfigurationModel.appConfig = appConfig;
|
|
var savedAssetScreen;
|
|
if (pwaModel.isPwaEnabled()) {
|
|
_.remove(appConfig.screens, function (screen) {
|
|
if (screen.name === "assetScreen" && _.includes(configurationModel.get('pwaEnabledTickets.tickets'), screen.datasource.toLowerCase())) {
|
|
savedAssetScreen = screen;
|
|
}
|
|
return screen.datasource && _.includes(configurationModel.get('pwaEnabledTickets.tickets'), screen.datasource.toLowerCase());
|
|
});
|
|
}
|
|
var screenList = appConfig.screens;
|
|
_.forEach(appConfig.screens, function (screen) {
|
|
if (screen.datasource !== 'Person' && !configurationModel.isServerApplicationEnabled(screen.datasource.toLowerCase())) {
|
|
screenList = _.reject(screenList, { datasource: screen.datasource });
|
|
}
|
|
screenConfigurationModel.screensCacheByName[screen.name] = screen;
|
|
});
|
|
screenConfigurationModel.screenList = angular.copy(screenList);
|
|
if (savedAssetScreen) {
|
|
screenConfigurationModel.savedAssetScreen = savedAssetScreen;
|
|
screenConfigurationModel.screensCacheByName[savedAssetScreen.name] = savedAssetScreen;
|
|
}
|
|
if (!appConfig.screens.length) {
|
|
console.log('Warning: screen list of application configuration is empty.');
|
|
screenConfigurationPromise.reject();
|
|
}
|
|
}
|
|
/**
|
|
* Handler for success load of available field list
|
|
* @param {Array} fieldList
|
|
*/
|
|
function handleAvailableFieldListLoadSuccess(fieldList) {
|
|
var uniqueFieldsList = fieldList.reduce(function (res, field) {
|
|
var isFieldAlreadySelected = res.some(function (selectedField) {
|
|
return selectedField.name === field.name && selectedField.dataType === field.dataType;
|
|
});
|
|
if (!isFieldAlreadySelected) {
|
|
res.push(field);
|
|
}
|
|
return res;
|
|
}, []);
|
|
screenConfigurationModel.fieldList = _.sortBy(uniqueFieldsList, 'name');
|
|
screenConfigurationModel.fieldDictionary = _.keyBy(uniqueFieldsList, 'name');
|
|
}
|
|
/**
|
|
* Handler for success load of available field list
|
|
* @param {Array} fieldList
|
|
*/
|
|
function handleActionsLoadSuccess(data) {
|
|
_.forEach(data.actionList, function (actionItem) {
|
|
actionItem.label = actionItem.labels[i18nService.language] || actionItem.labels.default;
|
|
});
|
|
if (data.actionOrder === 'alphabetical') {
|
|
screenConfigurationModel.actionList = _.sortBy(data.actionList, 'label');
|
|
}
|
|
else {
|
|
screenConfigurationModel.actionList = _.sortBy(data.actionList, 'sequenceNo');
|
|
}
|
|
screenConfigurationModel.actionOrder = data.actionOrder;
|
|
}
|
|
/**
|
|
* Handler for success load of available field list
|
|
* @param {Array} fieldList
|
|
*/
|
|
function handleActionUrlParamsLoadSuccess(data) {
|
|
screenConfigurationModel.actionUrlParams = data;
|
|
}
|
|
/**
|
|
* Handler for success load of selected field list
|
|
* @param {Array} fieldList
|
|
*/
|
|
function handleSelectedFieldListLoadSuccess(fieldList) {
|
|
screenConfigurationModel.selectedFieldDictionary = _.keyBy(fieldList, 'name');
|
|
}
|
|
/**
|
|
* Handler for success load of field list
|
|
* @param {Array} fieldLabels
|
|
* @param {String} dataSource
|
|
*/
|
|
function handleFieldLabelsLoadSuccess(fieldLabels, dataSource) {
|
|
if (!fieldLabelDictionary[dataSource]) {
|
|
fieldLabelDictionary[dataSource] = fieldLabels;
|
|
}
|
|
screenConfigurationModel.fieldLabels = fieldLabels.items;
|
|
}
|
|
screenConfigurationModel.getLocalizedFieldByNameForTicketType = function (fieldName, ticketType, assetClassId) {
|
|
var localizedField;
|
|
if (ticketType) {
|
|
var dataSource = dataSourceMap[ticketType];
|
|
localizedField = _.find(fieldLabelDictionary && fieldLabelDictionary[dataSource] && fieldLabelDictionary[dataSource].items, { name: fieldName });
|
|
}
|
|
if (!(localizedField && localizedField.label) && assetClassId) {
|
|
localizedField = _.find(screenConfigurationModel.fieldLabels, function (fieldLabel) {
|
|
return fieldLabel.name == fieldName && fieldLabel.classIds[0] == assetClassId;
|
|
});
|
|
}
|
|
if (!(localizedField && localizedField.label)) {
|
|
localizedField = _.find(screenConfigurationModel.fieldLabels, { name: fieldName });
|
|
}
|
|
return localizedField;
|
|
};
|
|
screenConfigurationModel.checkExpressionValid = function (node, fieldAcceleratorsList) {
|
|
var _errorMsg = '', _checkExpressionValid = function (node) {
|
|
var result;
|
|
if (!_errorMsg && node) {
|
|
if (node.left) {
|
|
return _checkExpressionValid(node.left);
|
|
}
|
|
if (node.right) {
|
|
return _checkExpressionValid(node.right);
|
|
}
|
|
if (node.type === 'Identifier') {
|
|
if (!_.startsWith(node.name, '$') || !_.find(fieldAcceleratorsList, { name: node.name })) {
|
|
_errorMsg = i18nService.getLocalizedStringwithParams('expression.builder.error.invalidIdentifier', node.name);
|
|
return _errorMsg;
|
|
}
|
|
}
|
|
else if (node.type === 'Compound') {
|
|
_errorMsg = i18nService.getLocalizedString('expression.builder.standard.error');
|
|
return _errorMsg;
|
|
}
|
|
else if (node.type === 'CallExpression') {
|
|
if (!_.includes(['NOOP', 'REPLACE', 'DATEADD', 'DATEDIFF', 'HASROLE', 'INGROUP', 'SELECTIONINDEX', 'SELECTIONLABEL', 'ISREQUIRED', 'ISREADONLY', 'ISHIDDEN', 'ONCHANGE'], node.callee.name)) {
|
|
_errorMsg = i18nService.getLocalizedStringwithParams('expression.builder.error.functionNotSupported', node.callee.name);
|
|
return _errorMsg;
|
|
}
|
|
_.each(node.arguments, function (item) {
|
|
return _checkExpressionValid(item);
|
|
});
|
|
}
|
|
else if (node.type === 'ConditionalExpression') {
|
|
result = _checkExpressionValid(node.test);
|
|
if (!result) {
|
|
result = _checkExpressionValid(node.consequent);
|
|
if (!result) {
|
|
return _checkExpressionValid(node.alternate);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
return _errorMsg;
|
|
}
|
|
};
|
|
return _checkExpressionValid(node);
|
|
};
|
|
/**
|
|
* Checks whether the screen supports expressions in actions
|
|
*
|
|
* @param {string} ticketType - type of the ticket
|
|
* @returns {boolean}
|
|
*/
|
|
screenConfigurationModel.isTicketEnabledForProviderActionExpression = function (ticketType) {
|
|
return ScreenConfigurationVO.prototype.isTicketEnabledForProviderActionExpression(ticketType);
|
|
};
|
|
return screenConfigurationModel;
|
|
}]);
|
|
})();
|