SmartIT_Extensions/BMC/smart-it-full-helix/scripts/app/common/editable-content-section-di...

235 lines
12 KiB
JavaScript

"use strict";
/**
* Created by igor.samulenko on 6/23/2014.
*/
(function () {
'use strict';
angular.module('myitsmApp')
.directive('editableContentSection', function () {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
editModeAllowed: '=',
hideEditButton: '=',
ticket: '=',
editButtonLabel: '='
},
templateUrl: 'views/common/editable-content-section.html',
controller: ['$element', '$transclude', '$scope', '$timeout', 'events', 'ticketModel', 'assetModel',
function ($element, $transclude, $scope, $timeout, events, ticketModel, assetModel) {
var childScope, transcludedContent;
var forms = [];
var combinedChanges = {};
var editableBlockCount = 0;
var combinedBlocksCount = 0;
var processedEventsCount = 0;
var savedEventsCount = 0;
$scope.editMode = false;
$scope.dataSaving = false;
$scope.editableContentInvalid = false;
$transclude(function (clone, scope) {
childScope = scope;
childScope.handleExternalEditClick = function () {
$scope.onEditButtonClick();
};
childScope.$on(events.SAVE_CHANGES_REQUEST, handleSaveChangesRequest);
childScope.$on(events.SAVE_CHANGES_COMPLETE, handleSaveChangesComplete);
childScope.$on(events.SAVE_CHANGES_FAULT, handleSaveChangesFault);
childScope.$on(events.SAVE_CHANGES_FAULT_CONTINUE, handleSaveChangesFaultContinue);
// perform manual transclusion
var editableContentHolder = $element.find('div.editable-content-section__content');
editableContentHolder.append(clone);
// find forms if any exist
var formArray = editableContentHolder.find('form');
if (formArray.length) {
_.forEach(formArray, function (element) {
forms.push(element.name);
});
}
// track amount of editable blocks
editableBlockCount = editableContentHolder.find('.editable-content-section-block').length;
transcludedContent = clone;
});
$scope.$on(events.DISABLE_EDIT, function (event, childEditMode) {
$scope.isChildInContent = childEditMode;
});
/**
* Handle edit click
*/
$scope.onEditButtonClick = function () {
var elementId = getElementId();
resetState();
childScope.$broadcast(events.TOGGLE_EDIT_MODE, elementId);
childScope.$broadcast(events.TOGGLE_DYNAMIC_FIELD_EDIT_MODE, elementId);
$scope.editMode = !$scope.editMode;
childScope.editMode = !childScope.editMode;
$timeout(updateRequiredFieldsLabelVisibility);
$timeout(focusFirstInput, 100);
// notify parents
$scope.$emit(events.TOGGLE_EDIT_MODE, elementId);
$scope.$emit(events.DISABLE_PARENT_EDITMODE, true);
$scope.$emit(events.DISABLE_CHILD_EDITMODE, true);
};
function focusFirstInput() {
$element.find('input[type="text"]').first().focus();
}
/**
* Handle save click
*/
$scope.onSaveClick = function () {
var editableContentHolder = $element.find('div.editable-content-section__content');
editableBlockCount = editableContentHolder.find('.editable-content-section-block').length;
childScope.$broadcast(events.SAVE_CHANGES);
$scope.$emit(events.DISABLE_PARENT_EDITMODE, false);
$scope.$emit(events.DISABLE_CHILD_EDITMODE, false);
};
/**
* Handle cancel click
*/
$scope.onCancelClick = function () {
childScope.$broadcast(events.DISCARD_CHANGES);
$scope.$emit(events.DISABLE_PARENT_EDITMODE, false);
$scope.$emit(events.DISABLE_CHILD_EDITMODE, false);
closeEditMode();
};
$scope.editableContentIsInvalid = function () {
var result = false;
if (forms && forms.length) {
try {
_.forEach(forms, function (formName) {
var form = _.get(childScope, formName) || childScope[formName];
result = result || form.$invalid;
});
}
catch (error) {
//ignore it
}
}
$scope.editableContentInvalid = result;
return result;
};
function handleSaveChangesRequest(event, eventData, singleMode, isCustomField) {
startSaving();
if (editableBlockCount > 0) {
if (eventData && _.size(eventData) && !singleMode) {
if (eventData.customFields) {
combinedChanges.customFields = angular.extend(combinedChanges.customFields || {}, eventData.customFields);
}
else {
angular.extend(combinedChanges, eventData);
}
}
//custom fields also emits SAVE_CHANGES_REQUEST and this will cause process count over run editable content count
if (!isCustomField) {
processedEventsCount++;
}
combinedBlocksCount += singleMode ? 0 : 1;
console.log('processed ' + processedEventsCount + ' events');
if (processedEventsCount === editableBlockCount) {
console.log('all editable block events processed');
if (_.size(combinedChanges)) {
console.log('combined changes object:');
console.log(combinedChanges);
// perform update
if (combinedChanges.isAssetUpdate) {
delete combinedChanges.isAssetUpdate;
assetModel.update(combinedChanges).then(handleSaveAllChangesSuccess, handleSaveAllChangesFault);
}
else {
ticketModel.update($scope.ticket.id, $scope.ticket.type, combinedChanges)
.then(function (result) {
if (result.data && result.data.error) {
childScope.$broadcast(events.DISCARD_CHANGES);
closeEditMode();
}
else {
handleSaveAllChangesSuccess(result);
}
}, handleSaveAllChangesFault);
}
}
else {
console.log('nothing changed or child sections saved themselves, closing edit mode');
handleSaveAllChangesSuccess({});
}
}
}
}
/**
* Handle successful update
*
* @param {Object} response
*/
function handleSaveAllChangesSuccess(response) {
childScope.$broadcast(events.SAVE_ALL_CHANGES_COMPLETE, response);
handleSaveChangesComplete(combinedBlocksCount);
}
function handleSaveAllChangesFault(response) {
childScope.$broadcast(events.SAVE_ALL_CHANGES_FAULT, response);
handleSaveChangesFault(combinedBlocksCount);
}
function handleSaveChangesComplete(eventCount) {
eventCount = angular.isNumber(eventCount) ? eventCount : 1;
finishSaving(eventCount);
}
function handleSaveChangesFault(eventCount) {
eventCount = angular.isNumber(eventCount) ? eventCount : 1;
finishSaving(eventCount);
}
function handleSaveChangesFaultContinue(eventCount) {
eventCount = angular.isNumber(eventCount) ? eventCount : 1;
savedEventsCount += eventCount;
if (savedEventsCount >= editableBlockCount) {
$scope.dataSaving = false;
resetState();
}
}
function startSaving() {
$scope.dataSaving = true;
}
function finishSaving(eventCount) {
savedEventsCount += eventCount;
if (savedEventsCount >= editableBlockCount) {
$scope.dataSaving = false;
resetState();
closeEditMode();
}
}
function resetState() {
combinedChanges = {};
processedEventsCount = 0;
combinedBlocksCount = 0;
savedEventsCount = 0;
}
function updateRequiredFieldsLabelVisibility() {
$scope.hasRequiredFields = hasRequiredFields();
}
function hasRequiredFields() {
return $element.find('div.editable-content-section__content .required').length;
}
function getElementId() {
return $element[0].id;
}
function closeEditMode() {
$scope.editMode = false;
childScope.editMode = false;
$scope.dataSaving = false;
// notify parents
$scope.$emit(events.EDIT_COMPLETE, getElementId());
}
$scope.$on('$destroy', function () {
transcludedContent.remove();
childScope.$destroy();
});
$scope.$on(events.CLOSE_EDIT_MODE_ON_STATUS_CLOSED_FROM_BLADE, function (event, updatedTicket) {
if (updatedTicket && !updatedTicket.detailsEditAllowed) {
$scope.onCancelClick();
}
});
}]
};
});
})();