"use strict"; (function () { 'use strict'; angular.module('myitsmApp') .directive('dynamicFieldArea', ['ticketModel', 'events', 'screenConfigurationModel', '$q', 'customFieldAreaLinkFunction', function (ticketModel, events, screenConfigurationModel, $q, customFieldAreaLinkFunction) { return { restrict: 'E', replace: true, scope: { ticket: '=', panelId: '=' }, templateUrl: 'views/field-customization/custom-field-area.html', link: function (scope) { var fields = angular.copy(scope.ticket.dynamicFields), fieldsHash = {}; _.forEach(fields, function (field) { _.extend(field, { dynamicField: true }); }); createFieldsHash(); initFieldValues(fields); scope.fields = fields; scope.editMode = false; scope.isCollapsed = true; scope.isDynamicArea = true; scope.fieldsCountToShow = 10; customFieldAreaLinkFunction(scope); // Dynamic fields don't have $scope.stacked, // so limit logic will never be applied to them. So visibleFields should be calculated only during init scope.visibleFields = scope.getFieldsListToShow(); scope.isEditable = function (field) { return field.isEditable(scope.ticket.accessMappings); }; function handleToggleEditMode() { scope.editMode = !scope.editMode; scope.isCollapsed = false; } function disableEditMode() { scope.$emit(events.SAVE_CHANGES_COMPLETE); scope.editMode = false; } function handleDiscardChanges() { initFieldValues(fields); scope.$broadcast(events.RESET_DYNAMIC_FIELDS); scope.editMode = false; } function handleSaveChanges() { scope.$emit(events.SAVE_CHANGES_REQUEST, null, true); var updatePromise, changes = collectChanges(scope.fields, fieldsHash), requestData = { dynamicFields: changes }; if (changes.length) { if (scope.ticket.type) { if (scope.ticket.isDraft) { updatePromise = $q.when(1); } else { updatePromise = ticketModel.update(scope.ticket.id, scope.ticket.type, requestData); } } updatePromise && updatePromise .then(function () { scope.ticket.dynamicFields = prepareDynamicFields(scope.ticket); updateTicketData(scope.ticket, changes); }) .finally(disableEditMode); } else { disableEditMode(); } } function handleFieldValueChange() { scope.$emit(events.FIELD_FORM_IS_DIRTY); } function initFieldValues(fields) { fields.forEach(function (field) { if (isValid(field.value) && field.value.toString().length) { field.setValue(field.value); } }); } function isValid(value) { return angular.isDefined(value) && value !== null; } function createFieldsHash() { _.forEach(fields, function (field) { fieldsHash[field.name] = field.value; }); } function collectChanges(changedFields, originalFieldsHash) { var changes = []; _.forEach(changedFields, function (changedField) { if (originalFieldsHash[changedField.name] !== changedField.getValue()) { changes.push({ name: changedField.name, value: changedField.getValue(), dataType: changedField.dataType, label: changedField.label }); } }); return changes; } function prepareDynamicFields(ticket) { var fields = []; _.forEach(ticket.dynamicFields, function (field) { fields.push({ name: field.name, value: field.value, dataType: field.dataType, label: field.label }); }); return fields; } function updateTicketData(ticket, changes) { if (changes.length) { if (!ticket.dynamicFields) { ticket.dynamicFields = []; } _.forEach(ticket.dynamicFields, function (field) { _.forEach(changes, function (change) { if (field.name === change.name) { field.value = change.value; } }); }); scope.$broadcast(events.UPDATE_DYNAMIC_DATA); createFieldsHash(); } } scope.$on(events.TOGGLE_DYNAMIC_FIELD_EDIT_MODE, handleToggleEditMode); scope.$on(events.SAVE_CHANGES, handleSaveChanges); scope.$on(events.DISCARD_CHANGES, handleDiscardChanges); scope.$on(events.FIELD_VALUE_CHANGE, handleFieldValueChange); } }; } ]); })();