"use strict"; /** * Created by igor.samulenko on 6/3/2014. */ (function () { 'use strict'; angular.module('myitsmApp') .factory('customFieldAreaLinkFunction', function () { return function (scope) { /** * Return array of visible fields * * @return {Array} */ scope.getVisibleFields = function () { if (scope.editMode) { return _.reject(scope.fields, 'groupMember'); } else { var fields = _.filter(scope.fields, function (field) { return field.isVisible() && !field.isGroupMember() && !field.isWidgetMember() && (field.ootb || field.required || angular.isDefined(field.value)); }); return fields; } }; /** * Returns true if there are visible fields * * @return {boolean} */ scope.hasVisibleFields = function () { var fields = scope.getVisibleFields(); return fields && fields.length > 0; }; /** * Get dependant field value, used for query menu fields * * @returns {String} */ scope.getDependantCustomFieldValue = function (fieldName) { var fieldValue = angular.noop(); _.find(scope.fields, function (field) { if (field.name === fieldName) { fieldValue = field.value; } else if (field.linkedFieldExist() && field.valueField === fieldName) { fieldValue = field.getLinkedValue(); } return !_.isUndefined(fieldValue); }); return (_.isUndefined(fieldValue) && !scope.editMode) ? scope.ticket.customFields[fieldName] : fieldValue; }; scope.getFieldsListToShow = function (limit) { var visibleFields = scope.getVisibleFields(); if (visibleFields.length > limit) { _.filter(visibleFields, function (field) { if (field.isRequired) { limit = field.displayOrder + 1; } }); } if (!_.isUndefined(limit) && limit >= 0) { visibleFields = visibleFields.slice(0, limit); } return visibleFields; }; scope.isEditable = function (field) { var data = field.isEditable(scope.ticket.accessMappings); return data === undefined ? false : data; }; scope.showField = function (field) { //check to not show the field if task phase management is not enabled return field.name === 'z1D_Phase' && !scope.ticket.showPhaseSelector ? false : true; }; }; }) .directive('customFieldArea', ['events', 'screenConfigurationModel', 'ticketModel', 'personModel', '$q', 'customFieldAreaLinkFunction', 'objectValueMapperService', function (events, screenConfigurationModel, ticketModel, personModel, $q, customFieldAreaLinkFunction, objectValueMapperService) { return { restrict: 'E', replace: true, scope: { panelId: '@', ticket: '=', metadata: '=', stacked: '=?', editMode: '=?', isNew: '=?', isDatesPanel: '=?', updateIsHandledByParent: '=', isTitleBar: '=' }, templateUrl: 'views/field-customization/custom-field-area.html', link: function (scope, element, attrs) { var hasAssigneeOrSupportGroupWidget = false; scope.state = { isDataLoading: false }; scope.$watch('ticket', function () { if (attrs.panelId && scope.ticket) { scope.state.isDataLoading = true; scope.ticket.ticketType = scope.ticket.ticketType ? scope.ticket.ticketType : scope.ticket.type; var screenView = scope.isNew ? 'create.' + scope.ticket.ticketType : scope.ticket.ticketType, screenName = screenConfigurationModel.getScreenNameByTicketType(screenView); screenConfigurationModel.loadScreenConfigurationAndCustomFieldLabels(screenName, scope.ticket.ticketType).then(function () { var panel = screenConfigurationModel.getPanelById(attrs.panelId), fields = angular.copy(panel && panel.fields) || []; if (attrs.panelId === 'assetScreen.Type Specific') { fields = _.filter(fields, function (field) { return _.includes(_.map(field.extension, 'classId'), scope.ticket.classId); }); if (fields.length) { scope.$emit(events.TS_CUSTOM_FIELDS_AVAILABLE, { typeSpecific: true }); } } console.log(scope.panelId + ' init!'); screenConfigurationModel.initFieldValues(fields, scope.ticket, scope.metadata).finally(function () { scope.$emit(events.FIELD_AREA_ATTACHED, attrs.panelId.split('.')[0]); console.log(scope.panelId + ' Loaded!'); }); scope.isAdditionalInfoPanel = panel && panel.shortId === 'additionalInfo'; scope.panel = panel; scope.fields = fields; objectValueMapperService.addFields(scope.fields); hasAssigneeOrSupportGroupWidget = scope.fields.some(function (field) { return field.isAssigneeWidget() || field.isSupportGroupWidget(); }); //hide field labels if the fields are in the title bar panel scope.hideLabelInTitleBar = scope.panel && scope.panel.name === 'titleBarPanel' ? true : false; scope.stacked = scope.stacked === undefined ? true : scope.stacked; scope.visibleFields = scope.getFieldsListToShow(); //get list of fields that have action(s) mapped to it scope.fieldActionMapping = objectValueMapperService.getFieldActionMapping(scope.ticket.ticketType); if (!scope.fieldActionMapping) { if (EntityVO.ENTITIES_WITH_NEW_CUSTOMIZATION.indexOf(scope.ticket.ticketType) !== -1) { screenConfigurationModel.loadActionsNew(scope.ticket.ticketType).then(function () { scope.actionLists = screenConfigurationModel.actionList; scope.fieldActionMapping = {}; for (var i in scope.actionLists) { if (scope.actionLists[i].mappedFields && scope.actionLists[i].mappedFields.length > 0) { var fieldArr = scope.actionLists[i].mappedFields, fieldObjArr = _.uniqBy(fieldArr, function (field) { return field.fieldName; }); for (var j in fieldObjArr) { scope.fieldActionMapping[fieldObjArr[j].fieldName] = { action: scope.actionLists[i], iconName: fieldObjArr[j].iconName }; } } } //store the fields with actions map in objectValueMapperService objectValueMapperService.setFieldActionMapping(scope.fieldActionMapping, scope.ticket.ticketType); }); } } }).finally(function () { scope.state.isDataLoading = false; }); } else { console.log("'panel-id' attribute is missing."); } }); scope.isCollapsed = true; scope.fieldsCountToShow = 5; customFieldAreaLinkFunction(scope); scope.$watch('isCollapsed && stacked', function () { scope.visibleFields = scope.getFieldsListToShow(); }); /** * Collect changes * * @returns {Object} */ function collectChanges() { var changes = screenConfigurationModel.collectChanges(scope.fields, scope.ticket.customFields, scope.ticket); if (_.size(changes)) { return { customFields: changes }; } else { return {}; } } function handleRefreshFieldValues(event, data) { if (data && data.panelId && attrs.panelId && (attrs.panelId === data.panelId)) { var panel = screenConfigurationModel.getPanelById(attrs.panelId); if (panel) { screenConfigurationModel.initFieldValues(scope.fields, data.ticket || scope.ticket, scope.metadata); } } } function handleToggleEditMode() { scope.editMode = !scope.editMode; scope.isCollapsed = false; scope.visibleFields = scope.getFieldsListToShow(); } function handleSaveChanges() { var changes = collectChanges(), isDraft = scope.ticket.isDraft, singleMode = !scope.updateIsHandledByParent; scope.$emit(events.SAVE_CHANGES_REQUEST, changes, singleMode || isDraft); if (_.size(changes)) { var updatePromise = $q.when(1); if (scope.ticket.type) { if (!isDraft && singleMode) { updatePromise = ticketModel.update(scope.ticket.id, scope.ticket.type, changes); } } else { updatePromise = personModel.updatePersonInfo(scope.ticket.id, changes); } if (singleMode || isDraft) { updatePromise.then(applyChanges).finally(closeEditor); } } else { closeEditor(); } } function applyChanges() { var changes = collectChanges(); screenConfigurationModel.updateTicketData(scope.ticket, changes.customFields); scope.isCollapsed = true; } function handleSaveAllChangesComplete() { if (scope.updateIsHandledByParent && !scope.ticket.isDraft) { // applyChanges(); closeEditor(); } } function handleSaveAllChangesFault() { if (scope.updateIsHandledByParent && !scope.ticket.isDraft) { _.forEach(scope.fields, function (field) { field.value = scope.ticket.customFields[field.name]; }); scope.$broadcast(events.REFRESH_FIELD_VALUES); closeEditor(); } } /** * Close edit mode */ function closeEditor() { if (!scope.updateIsHandledByParent || scope.ticket.isDraft) { scope.$emit(events.SAVE_CHANGES_COMPLETE); } scope.editMode = false; } function afterSaveChangesHandler() { closeEditor(); } function handleDiscardChanges() { _.forEach(scope.fields, function (field) { field.clearValue(); }); screenConfigurationModel.initFieldValues(scope.fields, scope.ticket, scope.metadata); scope.$broadcast(events.REFRESH_FIELD_VALUES); scope.editMode = false; scope.visibleFields = scope.getFieldsListToShow(); } function handleFieldValueChange() { scope.$emit(events.FIELD_FORM_IS_DIRTY); } function handleAssigneeUpdate(e, ticket, valueWasSaved, assigneeRole, fromAssignToMe) { if (hasAssigneeOrSupportGroupWidget) { if (isFieldValid(scope.fields, assigneeRole, fromAssignToMe)) { // Todo: currently we are skipping only custom fields when updated from blade however need to see if we can init only assignment related fields from ticket screenConfigurationModel.initFieldValues(scope.fields, ticket, scope.metadata, true); _.each(scope.fields, function (field) { var members = []; _.each(field.members, function (member) { members.push(member.name); }); scope.$emit(events.WIDGET_VALUE_CHANGE, { fieldName: field.name, memberName: members }); }); } if (ticket.type === EntityVO.TYPE_INCIDENT || ticket.type === EntityVO.TYPE_TASK || ticket.type === EntityVO.TYPE_CHANGE || ticket.type === EntityVO.TYPE_WORKORDER) { var fieldsToUpdate = [], assigneeField = ticket.type === EntityVO.TYPE_INCIDENT ? objectValueMapperService.getFieldByName('assignee') : objectValueMapperService.getFieldByName('assigneeName'); if (assigneeField && isFieldValid([assigneeField], assigneeRole, fromAssignToMe)) { fieldsToUpdate.push(assigneeField); } if (ticket.type === EntityVO.TYPE_WORKORDER || ticket.type === EntityVO.TYPE_CHANGE) { var managerField = objectValueMapperService.getFieldByName('managerName'); if (managerField && isFieldValid([managerField], assigneeRole, fromAssignToMe)) { fieldsToUpdate.push(managerField); } } if (fieldsToUpdate.length > 0) { screenConfigurationModel.initFieldValues(fieldsToUpdate, ticket, scope.metadata); } // scope.$emit(events.WIDGET_VALUE_CHANGE, {fieldName: assigneeField.name}); } if (valueWasSaved) { // Broadcasting down to assignee widget, to override original data // stored when widget was initialized scope.$broadcast(events.AFTER_SAVED_CHANGES); } } } function isFieldValid(fields, assigneeRole, fromAssignToMe) { var isValid = true; if (assigneeRole) { if (assigneeRole.indexOf('coordinator') !== -1) { assigneeRole = 'coordinator'; } else if (assigneeRole.indexOf('manager') !== -1) { assigneeRole = 'manager'; } else { assigneeRole = 'assignee'; } _.each(fields, function (field) { //need this check if its assignee or support group widget else if there are multiple fields added to same section then it always return false if (field.isAssigneeWidget() || field.isSupportGroupWidget()) { if (!fromAssignToMe) { if (assigneeRole === 'assignee' && (field.name === 'supportGroups' || field.name.toLowerCase().indexOf('assigned') !== -1)) { isValid = true; } else if ((scope.ticket.type === EntityVO.TYPE_PROBLEM) && (assigneeRole === 'coordinator') && field.name.indexOf('assignee') !== -1) { isValid = true; } else if ((scope.ticket.type === EntityVO.TYPE_WORKORDER) && (assigneeRole === 'assignee' || assigneeRole === 'manager') && (field.name.toLowerCase().indexOf('assignee') !== -1 || field.name.toLowerCase().indexOf('manager') !== -1 || field.name === 'supportGroups')) { isValid = true; } else if ((assigneeRole === 'coordinator' || assigneeRole === 'manager') && (field.name.toLowerCase().indexOf('coordinator') !== -1 || field.name.toLowerCase().indexOf('manager') !== -1)) { isValid = true; } else if (field.name.toLowerCase().indexOf(assigneeRole) === -1) { isValid = false; } } else { if (assigneeRole === 'assignee' && (field.name === 'supportGroups' || field.name.toLowerCase().indexOf('assigned') !== -1)) { isValid = true; } else if (assigneeRole === 'coordinator' && field.name.indexOf('assignee') !== -1) { isValid = true; } else if (field.name.toLowerCase().indexOf(assigneeRole) === -1) { isValid = false; } } } }); } return isValid; } scope.$on(events.REFRESH_FIELD_VALUES, handleRefreshFieldValues); scope.$on(events.TOGGLE_EDIT_MODE, handleToggleEditMode); scope.$on(events.AFTER_SAVED_CHANGES, afterSaveChangesHandler); scope.$on(events.SAVE_CHANGES, handleSaveChanges); scope.$on(events.SAVE_ALL_CHANGES_COMPLETE, handleSaveAllChangesComplete); scope.$on(events.SAVE_ALL_CHANGES_FAULT, handleSaveAllChangesFault); scope.$on(events.DISCARD_CHANGES, handleDiscardChanges); scope.$on(events.FIELD_VALUE_CHANGE, handleFieldValueChange); scope.$on(events.TICKET_ASSIGNEES_UPDATED, handleAssigneeUpdate); } }; } ]); })();