235 lines
12 KiB
JavaScript
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();
|
|
}
|
|
});
|
|
}]
|
|
};
|
|
});
|
|
})();
|