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.
193 lines
6.3 KiB
193 lines
6.3 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.
|
|
// ++
|
|
|
|
function inplaceEditorEditPane($timeout, EditableFieldsState, FocusHelper, inplaceEditAll) {
|
|
return {
|
|
transclude: true,
|
|
require: '^wpField',
|
|
templateUrl: '/components/inplace-edit/edit-pane/edit-pane.directive.html',
|
|
|
|
controllerAs: 'editPaneController',
|
|
controller: InplaceEditorEditPaneController,
|
|
|
|
link: function(scope, element, attrs, fieldController) {
|
|
var field = scope.field;
|
|
|
|
scope.fieldSchema = field.getFieldSchema();
|
|
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 (!inplaceEditAll.state) {
|
|
element.bind('keydown keypress', function(e) {
|
|
if (e.keyCode === 27) {
|
|
scope.$apply(function() {
|
|
scope.editPaneController.discardEditing();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
scope.$watch('fieldController.isEditing', function(isEditing) {
|
|
if (isEditing && !inplaceEditAll.state) {
|
|
scope.focusInput();
|
|
|
|
} else if (inplaceEditAll.state && EditableFieldsState.isFocusField(field.name)) {
|
|
$timeout(function () {
|
|
var focusElement = element.find('.focus-input');
|
|
focusElement.length && focusElement.focus()[0].select();
|
|
});
|
|
}
|
|
});
|
|
}
|
|
};
|
|
}
|
|
|
|
function InplaceEditorEditPaneController($scope,
|
|
$element,
|
|
$location,
|
|
$timeout,
|
|
EditableFieldsState,
|
|
inplaceEditStorage,
|
|
inplaceEditMultiStorage,
|
|
inplaceEditErrors,
|
|
I18n,
|
|
inplaceEditAll) {
|
|
|
|
var vm = this;
|
|
var field = $scope.field;
|
|
var fieldLabel = field.getLabel();
|
|
var wpStore = inplaceEditMultiStorage.stores.workPackage;
|
|
|
|
this.saveTitle = I18n.t('js.inplace.button_save', { attribute: fieldLabel });
|
|
this.cancelTitle = I18n.t('js.inplace.button_cancel', { attribute: fieldLabel });
|
|
|
|
this.submit = function() {
|
|
var detectedViolations = [];
|
|
|
|
if (vm.editForm.$invalid) {
|
|
Object.keys(vm.editForm.$error).forEach(function(error) {
|
|
|
|
if (vm.editForm.$error[error]) {
|
|
var localizationArgs = _.extend({ field: field.getLabel() }, field.getFieldSchema());
|
|
detectedViolations.push(I18n.t('js.inplace.errors.' + error, localizationArgs));
|
|
}
|
|
});
|
|
}
|
|
|
|
if (detectedViolations.length) {
|
|
inplaceEditErrors.errors = inplaceEditErrors.errors || {};
|
|
inplaceEditErrors.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.inplaceEditAll = inplaceEditAll;
|
|
|
|
$scope.$watch('inplaceEditAll.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') {
|
|
//noinspection TypeScriptUnresolvedVariable
|
|
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 = '/components/inplace-edit/field-templates/edit/' + strategy + '.html';
|
|
}
|
|
});
|
|
|
|
$scope.$on('form.updateRequired', function() {
|
|
inplaceEditStorage.refreshWorkPackageForm();
|
|
});
|
|
|
|
$scope.$on('workPackageRefreshed', function() {
|
|
vm.discardEditing();
|
|
});
|
|
}
|
|
|
|
angular
|
|
.module('openproject.inplace-edit')
|
|
.directive('inplaceEditorEditPane', inplaceEditorEditPane);
|
|
|