kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
6.0 KiB
185 lines
6.0 KiB
// -- copyright
|
|
// OpenProject is a project management system.
|
|
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License version 3.
|
|
//
|
|
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
// Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
// Copyright (C) 2010-2013 the ChiliProject Team
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
//
|
|
// See doc/COPYRIGHT.rdoc for more details.
|
|
// ++
|
|
|
|
angular
|
|
.module('openproject.inplace-edit')
|
|
.directive('inplaceEditorEditPane', inplaceEditorEditPane);
|
|
|
|
function inplaceEditorEditPane(EditableFieldsState, FocusHelper, $timeout) {
|
|
return {
|
|
transclude: true,
|
|
require: '^workPackageField',
|
|
templateUrl: '/components/inplace-edit/directives/edit-pane/edit-pane.directive.html',
|
|
|
|
controllerAs: 'editPaneController',
|
|
controller: InplaceEditorEditPaneController,
|
|
|
|
link: function(scope, element, attrs, fieldController) {
|
|
var field = scope.field;
|
|
|
|
scope.fieldController = fieldController;
|
|
scope.editableFieldsState = EditableFieldsState;
|
|
|
|
scope.focusInput = function() {
|
|
$timeout(function() {
|
|
var inputElement = element.find('.focus-input');
|
|
FocusHelper.focus(inputElement);
|
|
inputElement.triggerHandler('keyup');
|
|
scope.editPaneController.markActive();
|
|
inputElement.off('focus.inplace').on('focus.inplace', function() {
|
|
scope.$apply(function() {
|
|
scope.editPaneController.markActive();
|
|
});
|
|
});
|
|
});
|
|
};
|
|
|
|
if (!EditableFieldsState.forcedEditState) {
|
|
element.bind('keydown keypress', function(e) {
|
|
if (e.keyCode === 27 && !EditableFieldsState.editAll.state) {
|
|
scope.$apply(function() {
|
|
scope.editPaneController.discardEditing();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
scope.$watch('fieldController.isEditing', function(isEditing) {
|
|
var efs = EditableFieldsState;
|
|
|
|
if (isEditing && !efs.editAll.state && !efs.forcedEditState) {
|
|
scope.focusInput();
|
|
|
|
} else if (efs.editAll.state && efs.editAll.isFocusField(field.name)) {
|
|
$timeout(function () {
|
|
var focusElement = element.find('.focus-input');
|
|
focusElement.length && focusElement.focus()[0].select();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}
|
|
inplaceEditorEditPane.$inject = ['EditableFieldsState', 'FocusHelper', '$timeout'];
|
|
|
|
|
|
function InplaceEditorEditPaneController($rootScope, $scope, $element, $location, $timeout,
|
|
EditableFieldsState, NotificationsService, inplaceEditStorage, inplaceEditMultiStorage) {
|
|
|
|
var vm = this;
|
|
var field = $scope.field;
|
|
var wpStore = inplaceEditMultiStorage.stores.workPackage;
|
|
|
|
this.submit = function() {
|
|
var detectedViolations = [];
|
|
|
|
if (vm.editForm.$invalid) {
|
|
Object.keys(vm.editForm.$error).forEach(function(error) {
|
|
|
|
if (vm.editForm.$error[error]) {
|
|
detectedViolations.push(I18n.t('js.inplace.errors.' + error, {
|
|
field: field.getLabel()
|
|
}));
|
|
}
|
|
});
|
|
}
|
|
|
|
if (detectedViolations.length) {
|
|
EditableFieldsState.errors = EditableFieldsState.errors || {};
|
|
EditableFieldsState.errors[field.name] = detectedViolations.join(' ');
|
|
}
|
|
|
|
inplaceEditMultiStorage.save().then(function () {
|
|
$location.hash(null);
|
|
$timeout(function() {
|
|
$element[0].scrollIntoView(false);
|
|
});
|
|
|
|
}).catch(function () {
|
|
$scope.focusInput();
|
|
});
|
|
};
|
|
|
|
this.discardEditing = function() {
|
|
$scope.fieldController.isEditing = false;
|
|
EditableFieldsState.discard(field.name);
|
|
};
|
|
|
|
this.isActive = function() {
|
|
return EditableFieldsState.isActiveField(field.name);
|
|
};
|
|
|
|
this.markActive = function() {
|
|
wpStore.active = true;
|
|
EditableFieldsState.currentField = field.name;
|
|
};
|
|
|
|
this.isRequired = function() {
|
|
return field.isRequired();
|
|
};
|
|
|
|
$scope.$watch('editableFieldsState.editAll.state', function(state) {
|
|
$scope.fieldController.isEditing = state;
|
|
$scope.fieldController.lockFocus = true;
|
|
});
|
|
|
|
$scope.$watch('field.value', function(value) {
|
|
if ($scope.fieldController.isEditing) {
|
|
var pendingChanges = EditableFieldsState.getPendingFormChanges();
|
|
pendingChanges[field.name] = value;
|
|
vm.markActive();
|
|
}
|
|
}, true);
|
|
|
|
$scope.$watchCollection('field.resource.form', function(form) {
|
|
var strategy = field.getInplaceEditStrategy();
|
|
|
|
if (field.name === 'date' && strategy === 'date') {
|
|
form.pendingChanges = EditableFieldsState.getPendingFormChanges();
|
|
form.pendingChanges['startDate'] =
|
|
form.pendingChanges['dueDate'] =
|
|
field.value ? field.value['dueDate'] : null;
|
|
}
|
|
|
|
if (strategy !== $scope.strategy) {
|
|
$scope.strategy = strategy;
|
|
$scope.templateUrl = '/templates/inplace-edit/edit/fields/' + strategy + '.html';
|
|
}
|
|
});
|
|
|
|
$scope.$on('form.updateRequired', function() {
|
|
inplaceEditStorage.updateWorkPackageForm();
|
|
});
|
|
|
|
$scope.$on('workPackageRefreshed', function() {
|
|
vm.discardEditing();
|
|
});
|
|
}
|
|
InplaceEditorEditPaneController.$inject = ['$rootScope', '$scope', '$element', '$location',
|
|
'$timeout', 'EditableFieldsState', 'NotificationsService', 'inplaceEditStorage',
|
|
'inplaceEditMultiStorage'];
|
|
|