Reference field names via newly introduced field object

pull/3701/head
Alex Dik 9 years ago committed by Jens Ulferts
parent 66220d3f37
commit e582c304f3
  1. 6
      frontend/app/components/inplace-edit/directives/display-pane/display-pane.directive.html
  2. 38
      frontend/app/components/inplace-edit/directives/display-pane/display-pane.directive.js
  3. 30
      frontend/app/components/inplace-edit/directives/edit-pane/edit-pane.directive.js
  4. 4
      frontend/app/components/inplace-edit/directives/field-display/display-spent-time/display-spent-time.directive.html
  5. 4
      frontend/app/components/inplace-edit/directives/field-display/display-spent-time/display-spent-time.directive.js
  6. 1
      frontend/app/components/inplace-edit/directives/field-display/display-user/display-user.directive.js
  7. 1
      frontend/app/components/inplace-edit/directives/field-display/display-version/display-version.directive.js
  8. 1
      frontend/app/components/inplace-edit/directives/field-edit/edit-date-range/edit-date-range.directive.js
  9. 1
      frontend/app/components/inplace-edit/directives/field-edit/edit-date/edit-date.directive.js
  10. 29
      frontend/app/components/inplace-edit/directives/field-edit/edit-drop-down/edit-drop-down.directive.js
  11. 1
      frontend/app/components/inplace-edit/directives/field-edit/edit-duration/edit-duration.directive.js
  12. 1
      frontend/app/components/inplace-edit/directives/field-edit/edit-wiki-textarea/edit-wiki-textarea.directive.js
  13. 2
      frontend/app/components/inplace-edit/directives/main-pane/main-pane.directive.html
  14. 17
      frontend/app/components/inplace-edit/directives/main-pane/main-pane.directive.js
  15. 6
      frontend/app/components/inplace-edit/directives/work-package-field/work-package-field.directive.html
  16. 39
      frontend/app/components/inplace-edit/directives/work-package-field/work-package-field.directive.js
  17. 47
      frontend/app/components/inplace-edit/services/inplace-edit-field.service.js
  18. 22
      frontend/app/components/inplace-edit/services/work-package-field.service.js
  19. 4
      frontend/app/templates/inplace-edit/edit/fields/boolean.html
  20. 2
      frontend/app/templates/work_packages.list.details.html
  21. 6
      frontend/app/templates/work_packages.list.new.html
  22. 6
      frontend/app/templates/work_packages.show.html
  23. 4
      frontend/app/templates/work_packages/tabs/overview.html
  24. 12
      frontend/app/work_packages/services/index.js
  25. 24
      frontend/tests/unit/tests/components/inplace-edit/directives/edit-drop-down.directive.test.js

@ -1,13 +1,13 @@
<div class="inplace-edit--read" ng-hide="fieldController.isEditing">
<accessible-by-keyboard
ng-if="fieldController.isEditable()"
ng-if="field.isEditable()"
class="inplace-editing--trigger-container"
span-class="inplace-editing--container"
link-class="inplace-editing--trigger-link"
execute="displayPaneController.startEditing()">
<span
class="inplace-edit--read-value"
ng-class="{'-default': fieldController.isEmpty()}"
ng-class="{'-default': field.isEmpty()}"
ng-include="templateUrl">
</span>
<span class="inplace-edit--icon-wrapper">
@ -15,7 +15,7 @@
</icon-wrapper>
</span>
</accessible-by-keyboard>
<span ng-if="!fieldController.isEditable()">
<span ng-if="!field.isEditable()">
<span
class="inplace-edit--read-value"
ng-include="templateUrl">

@ -30,11 +30,10 @@ angular
.module('openproject.inplace-edit')
.directive('inplaceEditorDisplayPane', inplaceEditorDisplayPane);
function inplaceEditorDisplayPane(WorkPackageFieldService, EditableFieldsState, $timeout, I18n) {
function inplaceEditorDisplayPane(EditableFieldsState, $timeout, I18n) {
return {
replace: true,
transclude: true,
scope: {},
require: '^workPackageField',
templateUrl: '/components/inplace-edit/directives/display-pane/display-pane.directive.html',
controller: InplaceEditorDisplayPaneController,
@ -42,14 +41,11 @@ function inplaceEditorDisplayPane(WorkPackageFieldService, EditableFieldsState,
link: function(scope, element, attrs, fieldController) {
scope.fieldController = fieldController;
scope.displayPaneController.field = scope.fieldController.field;
scope.editableFieldsState = EditableFieldsState;
scope.$watchCollection('editableFieldsState.workPackage.form', function() {
var strategy = WorkPackageFieldService.getInplaceDisplayStrategy(
EditableFieldsState.workPackage,
fieldController.field
);
var strategy = scope.field.getInplaceDisplayStrategy();
if (strategy !== scope.displayStrategy) {
scope.displayStrategy = strategy;
scope.templateUrl = '/templates/inplace-edit/display/fields/' + strategy +'.html';
@ -57,13 +53,13 @@ function inplaceEditorDisplayPane(WorkPackageFieldService, EditableFieldsState,
});
// TODO: extract this when more placeholders come
if (fieldController.field === 'description') {
if (scope.field.name === 'description') {
scope.displayPaneController.placeholder = I18n.t('js.label_click_to_enter_description');
}
scope.$watch('editableFieldsState.errors', function(errors) {
if (errors) {
if (errors[scope.fieldController.field]) {
if (errors[scope.scope.field.name]) {
scope.displayPaneController.startEditing();
}
}
@ -87,12 +83,12 @@ function inplaceEditorDisplayPane(WorkPackageFieldService, EditableFieldsState,
}
};
}
inplaceEditorDisplayPane.$inject = ['WorkPackageFieldService', 'EditableFieldsState', '$timeout', 'I18n'];
inplaceEditorDisplayPane.$inject = ['EditableFieldsState', '$timeout', 'I18n'];
function InplaceEditorDisplayPaneController($scope, WorkPackageFieldService, EditableFieldsState,
HookService) {
function InplaceEditorDisplayPaneController($scope, EditableFieldsState, HookService) {
this.placeholder = WorkPackageFieldService.defaultPlaceholder;
this.placeholder = $scope.field.defaultPlaceholder;
this.startEditing = function() {
var fieldController = $scope.fieldController;
@ -100,25 +96,19 @@ function InplaceEditorDisplayPaneController($scope, WorkPackageFieldService, Edi
};
this.isReadValueEmpty = function() {
return WorkPackageFieldService.isEmpty(
EditableFieldsState.workPackage,
$scope.fieldController.field
);
return $scope.field.isEmpty();
};
this.getReadValue = function() {
return WorkPackageFieldService.format(
EditableFieldsState.workPackage,
$scope.fieldController.field
);
return $scope.field.format();
};
// for dynamic type that is set by plugins
// refactor to a service method the whole extraction
this.getDynamicDirectiveName = function() {
return HookService.call('workPackageOverviewAttributes', {
type: EditableFieldsState.workPackage.schema.props[$scope.fieldController.field].type,
field: $scope.fieldController.field,
type: EditableFieldsState.workPackage.schema.props[$scope.field.name].type,
field: $scope.field.name,
workPackage: EditableFieldsState.workPackage
})[0];
};
@ -128,4 +118,4 @@ function InplaceEditorDisplayPaneController($scope, WorkPackageFieldService, Edi
return EditableFieldsState.workPackage;
};
}
InplaceEditorDisplayPaneController.$inject = ['$scope', 'WorkPackageFieldService', 'EditableFieldsState', 'HookService'];
InplaceEditorDisplayPaneController.$inject = ['$scope', 'EditableFieldsState', 'HookService'];

@ -36,7 +36,6 @@ function inplaceEditorEditPane(WorkPackageFieldService, EditableFieldsState, Foc
return {
transclude: true,
replace: true,
scope: true,
require: '^workPackageField',
templateUrl: '/components/inplace-edit/directives/edit-pane/edit-pane.directive.html',
controllerAs: 'editPaneController',
@ -53,12 +52,9 @@ function inplaceEditorEditPane(WorkPackageFieldService, EditableFieldsState, Foc
};
scope.$watchCollection('editableFieldsState.workPackage.form', function(form) {
var strategy = WorkPackageFieldService.getInplaceEditStrategy(
EditableFieldsState.workPackage,
fieldController.field
);
var strategy = scope.field.getInplaceEditStrategy();
if (fieldController.field === 'date' && strategy === 'date') {
if (scope.field.name === 'date' && strategy === 'date') {
form.pendingChanges = EditableFieldsState.getPendingFormChanges();
form.pendingChanges['startDate'] =
form.pendingChanges['dueDate'] =
@ -101,7 +97,7 @@ function inplaceEditorEditPane(WorkPackageFieldService, EditableFieldsState, Foc
scope.$watch('fieldController.writeValue', function(writeValue) {
if (scope.fieldController.isEditing) {
var pendingChanges = EditableFieldsState.getPendingFormChanges();
pendingChanges[scope.fieldController.field] = writeValue;
pendingChanges[scope.field.name] = writeValue;
}
}, true);
scope.$on('workPackageRefreshed', function() {
@ -109,7 +105,7 @@ function inplaceEditorEditPane(WorkPackageFieldService, EditableFieldsState, Foc
});
scope.$watch('fieldController.isEditing', function(isEditing) {
var efs = EditableFieldsState, field = fieldController.field;
var efs = EditableFieldsState, field = scope.field.name;
if (isEditing && !efs.editAll.state && !efs.forcedEditState) {
scope.focusInput();
@ -170,7 +166,7 @@ function InplaceEditorEditPaneController($scope, $element, $location, $timeout,
submit.reject(e);
};
pendingFormChanges[fieldController.field] = fieldController.writeValue;
pendingFormChanges[$scope.field.name] = fieldController.writeValue;
if (vm.editForm.$invalid) {
var acknowledgedValidationErrors = Object.keys(vm.editForm.$error);
acknowledgedValidationErrors.forEach(function(error) {
@ -184,7 +180,7 @@ function InplaceEditorEditPaneController($scope, $element, $location, $timeout,
}
if (detectedViolations.length) {
EditableFieldsState.errors = EditableFieldsState.errors || {};
EditableFieldsState.errors[fieldController.field] = detectedViolations.join(' ');
EditableFieldsState.errors[$scope.field.name] = detectedViolations.join(' ');
showErrors();
submit.reject();
} else {
@ -228,27 +224,27 @@ function InplaceEditorEditPaneController($scope, $element, $location, $timeout,
this.discardEditing = function() {
$scope.fieldController.isEditing = false;
delete EditableFieldsState.submissionPromises['work_package'];
delete EditableFieldsState.getPendingFormChanges()[$scope.fieldController.field];
delete EditableFieldsState.getPendingFormChanges()[$scope.field.name];
$scope.fieldController.updateWriteValue();
if (
EditableFieldsState.errors &&
EditableFieldsState.errors.hasOwnProperty($scope.fieldController.field)
EditableFieldsState.errors.hasOwnProperty($scope.field.name)
) {
delete EditableFieldsState.errors[$scope.fieldController.field];
delete EditableFieldsState.errors[$scope.field.name];
}
};
this.isActive = function() {
return EditableFieldsState.isActiveField($scope.fieldController.field);
return EditableFieldsState.isActiveField($scope.field.name);
};
this.markActive = function() {
EditableFieldsState.submissionPromises['work_package'] = {
field: $scope.fieldController.field,
field: $scope.field.name,
thePromise: this.submitField,
prepend: true,
prepend: true
};
EditableFieldsState.currentField = $scope.fieldController.field;
EditableFieldsState.currentField = $scope.field.name;
};
function afterError() {

@ -1,6 +1,6 @@
<div class="spent-time-wrapper">
<span ng-if="fieldController.isEmpty()">{{ displayPaneController.placeholder }}</span>
<span ng-if="!fieldController.isEmpty()">
<span ng-if="field.isEmpty()">{{ displayPaneController.placeholder }}</span>
<span ng-if="!field.isEmpty()">
<span ng-if="customEditorController.isLinkViewable()">
<a href="{{ customEditorController.getPath() }}">
{{ displayPaneController.getReadValue() }}

@ -35,8 +35,7 @@ function inplaceDisplaySpentTime() {
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: ['^inplaceEditorDisplayPane', '^workPackageField'],
require: '^inplaceEditorDisplayPane',
templateUrl: '/components/inplace-edit/directives/field-display/display-spent-time/' +
'display-spent-time.directive.html',
@ -45,7 +44,6 @@ function inplaceDisplaySpentTime() {
link: function(scope, element, attrs, controllers) {
scope.displayPaneController = controllers[0];
scope.fieldController = controllers[1];
}
};
}

@ -35,7 +35,6 @@ function inplaceDisplayUser() {
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: '^inplaceEditorDisplayPane',
templateUrl: '/components/inplace-edit/directives/field-display/display-user/' +
'display-user.directive.html',

@ -35,7 +35,6 @@ function inplaceDisplayVersion() {
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: '^inplaceEditorDisplayPane',
templateUrl: '/components/inplace-edit/directives/field-display/display-version/' +
'display-version.directive.html',

@ -37,7 +37,6 @@ function inplaceEditorDateRange(TimezoneService, I18n, $timeout, WorkPackageFiel
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: '^workPackageField',
templateUrl: '/components/inplace-edit/directives/field-edit/edit-date-range/' +
'edit-date-range.directive.html',

@ -41,7 +41,6 @@ function inplaceEditorDate(EditableFieldsState, TimezoneService, $timeout, Datep
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: '^workPackageField',
templateUrl: '/components/inplace-edit/directives/field-edit/edit-date/' +
'edit-date.directive.html',

@ -30,12 +30,11 @@ angular
.module('openproject.inplace-edit')
.directive('inplaceEditorDropDown', inplaceEditorDropDown);
function inplaceEditorDropDown(WorkPackageFieldService, EditableFieldsState, FocusHelper) {
function inplaceEditorDropDown(EditableFieldsState, FocusHelper) {
return {
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: '^workPackageField',
templateUrl: '/components/inplace-edit/directives/field-edit/edit-drop-down/' +
'edit-drop-down.directive.html',
@ -44,16 +43,13 @@ function inplaceEditorDropDown(WorkPackageFieldService, EditableFieldsState, Foc
controllerAs: 'customEditorController',
link: function(scope, element, attrs, fieldController) {
var selected = WorkPackageFieldService.format(
EditableFieldsState.workPackage,
fieldController.field
);
var selected = scope.field.format();
scope.fieldController = fieldController;
scope.customEditorController.selected = selected && selected.props && selected.props.name;
scope.fieldController.state.isBusy = true;
scope.customEditorController.updateAllowedValues(fieldController.field).then(function() {
scope.customEditorController.updateAllowedValues(scope.field.name).then(function() {
fieldController.state.isBusy = false;
if (!EditableFieldsState.forcedEditState) {
@ -63,12 +59,10 @@ function inplaceEditorDropDown(WorkPackageFieldService, EditableFieldsState, Foc
}
};
}
inplaceEditorDropDown.$inject = ['WorkPackageFieldService', 'EditableFieldsState', 'FocusHelper'];
inplaceEditorDropDown.$inject = ['EditableFieldsState', 'FocusHelper'];
function InplaceEditorDropDownController($q, I18n, WorkPackageFieldService,
WorkPackageFieldConfigurationService, EditableFieldsState) {
function InplaceEditorDropDownController($q, $scope, I18n, WorkPackageFieldConfigurationService) {
this.allowedValues = [];
this.nullValueLabel = I18n.t('js.inplace.null_value_label');
@ -76,10 +70,8 @@ function InplaceEditorDropDownController($q, I18n, WorkPackageFieldService,
var customEditorController = this;
return $q(function(resolve) {
WorkPackageFieldService.getAllowedValues(
EditableFieldsState.workPackage,
field
).then(function(values) {
$scope.field.getAllowedValues()
.then(function(values) {
var sorting = WorkPackageFieldConfigurationService
.getDropdownSortingStrategy(field);
@ -88,8 +80,7 @@ function InplaceEditorDropDownController($q, I18n, WorkPackageFieldService,
values = _.sortBy(values, sorting);
}
if (!WorkPackageFieldService.isRequired(EditableFieldsState.workPackage,
field)) {
if (!$scope.field.isRequired()) {
var arrayWithEmptyOption = [{
href: null,
name: I18n.t('js.inplace.clear_value_label')
@ -104,5 +95,5 @@ function InplaceEditorDropDownController($q, I18n, WorkPackageFieldService,
});
};
}
InplaceEditorDropDownController.$inject = ['$q', 'I18n', 'WorkPackageFieldService',
'WorkPackageFieldConfigurationService', 'EditableFieldsState'];
InplaceEditorDropDownController.$inject = ['$q', '$scope', 'I18n',
'WorkPackageFieldConfigurationService'];

@ -35,7 +35,6 @@ function inplaceEditorDuration() {
restrict: 'E',
transclude: true,
replace: true,
scope: {},
require: '^workPackageField',
templateUrl: '/components/inplace-edit/directives/field-edit/edit-duration/' +
'edit-duration.directive.html',

@ -35,7 +35,6 @@ function inplaceEditorWikiTextarea(AutoCompleteHelper, $timeout) {
restrict: 'E',
transclude: true,
replace: true,
scope: {},
templateUrl: '/components/inplace-edit/directives/field-edit/edit-wiki-textarea/' +
'edit-wiki-textarea.directive.html',

@ -1,5 +1,5 @@
<div
class="inplace-edit attribute-{{ fieldController.field }}"
class="inplace-edit attribute-{{ field.name }}"
ng-class="{'-busy': fieldController.state.isBusy}"
aria-busy="{{ fieldController.state.isBusy }}">
<ng-transclude></ng-transclude>

@ -44,19 +44,10 @@ function inplaceEditorMainPane() {
function InplaceEditorMainPaneController($scope, $timeout) {
// controller is invoked before linker
$timeout(function() {
var fieldController = $scope.fieldController;
this.saveTitle = I18n.t(
'js.inplace.button_save',
{ attribute: fieldController.field }
);
this.saveAndSendTitle = I18n.t(
'js.inplace.button_save_and_send',
{ attribute: fieldController.field }
);
this.cancelTitle = I18n.t(
'js.inplace.button_cancel',
{ attribute: fieldController.field }
);
this.saveTitle = I18n.t('js.inplace.button_save', { attribute: $scope.field.name });
this.saveAndSendTitle = I18n.t('js.inplace.button_save_and_send',
{ attribute: $scope.field.name });
this.cancelTitle = I18n.t('js.inplace.button_cancel', { attribute: $scope.field.name });
});
}
InplaceEditorMainPaneController.$inject = ['$scope', '$timeout'];

@ -1,7 +1,7 @@
<div id="work-package-{{ fieldController.field }}"
class="work-package-field work-packages--details--{{ fieldController.field }}">
<div id="work-package-{{ field.name }}"
class="work-package-field work-packages--details--{{ field.name }}">
<inplace-editor-main-pane>
<inplace-editor-display-pane></inplace-editor-display-pane>
<inplace-editor-edit-pane ng-if="fieldController.isEditable()"></inplace-editor-edit-pane>
<inplace-editor-edit-pane ng-if="field.isEditable()"></inplace-editor-edit-pane>
</inplace-editor-main-pane>
</div>

@ -34,46 +34,37 @@ function workPackageField() {
return {
restrict: 'E',
replace: true,
controllerAs: 'fieldController',
bindToController: true,
templateUrl: '/components/inplace-edit/directives/work-package-field/work-package-field.directive.html',
templateUrl: '/components/inplace-edit/directives/work-package-field/' +
'work-package-field.directive.html',
scope: {
field: '='
fieldName: '='
},
controller: WorkPackageFieldController
bindToController: true,
controller: WorkPackageFieldController,
controllerAs: 'fieldController'
};
}
function WorkPackageFieldController($scope, EditableFieldsState, WorkPackageFieldService) {
function WorkPackageFieldController($scope, EditableFieldsState, inplaceEditField) {
this.state = EditableFieldsState;
this.isEditable = function() {
return WorkPackageFieldService.isEditable(EditableFieldsState.workPackage, this.field);
};
this.isEmpty = function() {
return WorkPackageFieldService.isEmpty(EditableFieldsState.workPackage, this.field);
};
this.getLabel = function() {
return WorkPackageFieldService.getLabel(EditableFieldsState.workPackage, this.field);
};
$scope.field = new inplaceEditField(EditableFieldsState.workPackage, this.fieldName);
this.updateWriteValue = function() {
this.writeValue = EditableFieldsState.editAll.getFieldValue(this.field) || _.cloneDeep(
WorkPackageFieldService.getValue(EditableFieldsState.workPackage, this.field));
this.writeValue = EditableFieldsState.editAll.getFieldValue($scope.field.name)
|| _.cloneDeep($scope.field.getValue());
};
if (this.isEditable()) {
if ($scope.field.isEditable()) {
this.state.isBusy = false;
this.isEditing = this.state.forcedEditState;
this.updateWriteValue();
this.editTitle = I18n.t('js.inplace.button_edit', { attribute: this.getLabel() });
this.editTitle = I18n.t('js.inplace.button_edit', { attribute: $scope.field.getLabel() });
}
$scope.$watch('fieldController.writeValue', angular.bind(this, function (newValue) {
EditableFieldsState.editAll.addFieldValue(this.field, newValue);
EditableFieldsState.editAll.addFieldValue(this.fieldName, newValue);
}));
}
WorkPackageFieldController.$inject = ['$scope', 'EditableFieldsState', 'WorkPackageFieldService'];
WorkPackageFieldController.$inject = ['$scope', 'EditableFieldsState', 'inplaceEditField'];

@ -0,0 +1,47 @@
// -- 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')
.factory('inplaceEditField', inplaceEditField);
function inplaceEditField(WorkPackageFieldService) {
function Field(resource, name) {
this.resource = resource;
this.name = name;
}
_.forOwn(WorkPackageFieldService, function (method, name) {
Field.prototype[name] = function () {
return method(this.resource, this.name);
}
});
return Field;
}
inplaceEditField.$indect = ['WorkPackageFieldService'];

@ -26,17 +26,15 @@
// See doc/COPYRIGHT.rdoc for more details.
//++
module.exports = function(
I18n,
WORK_PACKAGE_REGULAR_EDITABLE_FIELD,
WorkPackagesHelper,
$q,
$http,
$timeout,
$filter,
HookService,
EditableFieldsState
) {
angular
.module('openproject.services')
.service('WorkPackageFieldService', WorkPackageFieldService);
WorkPackageFieldService.$inject = ['$q', '$http', 'I18n', 'WorkPackagesHelper', 'HookService',
'EditableFieldsState'];
function WorkPackageFieldService($q, $http, I18n, WorkPackagesHelper, HookService,
EditableFieldsState ) {
function getSchema(workPackage) {
if (workPackage.form) {
@ -415,4 +413,4 @@ module.exports = function(
};
return WorkPackageFieldService;
};
}

@ -1,10 +1,10 @@
<div class="switch">
<input type="checkbox"
class="focus-input"
id="checkbox-switch-{{ fieldController.field }}"
id="checkbox-switch-{{ field.name }}"
name="value"
ng-disabled="fieldController.state.isBusy"
title="{{ fieldController.editTitle }}"
ng-model="fieldController.writeValue" />
<label for="checkbox-switch-{{ fieldController.field }}" title="{{ fieldController.editTitle }}"></label>
<label for="checkbox-switch-{{ field.name }}" title="{{ fieldController.editTitle }}"></label>
</div>

@ -27,7 +27,7 @@
</span>
<div class="work-packages--details--title">
<work-package-field field="'subject'"></work-package-field>
<work-package-field field-name="'subject'"></work-package-field>
</div>
<span class="subtitle">

@ -3,7 +3,7 @@
<h2>{{ ::I18n.t('js.work_packages.create.header') }}</h2>
<div class="work-packages--create--title">
<work-package-field field="'subject'" tabindex="0"></work-package-field>
<work-package-field field-name="'subject'" tabindex="0"></work-package-field>
</div>
<div class="attributes-group--header">
@ -15,7 +15,7 @@
</div>
<div class="single-attribute wiki">
<work-package-field field="'description'"></work-package-field>
<work-package-field field-name="'description'"></work-package-field>
</div>
<div ng-repeat="group in vm.groupedFields" ng-hide="vm.hideEmptyFields && vm.isGroupHideable(vm.groupedFields, group.groupName, vm.workPackage)" class="attributes-group">
@ -47,7 +47,7 @@
ng-if="vm.isSpecified(vm.workPackage, field) && vm.isEditable(vm.workPackage, field)"
ng-repeat-end
class="attributes-key-value--value-container">
<work-package-field field="field"></work-package-field>
<work-package-field field-name="field"></work-package-field>
</dd>
</dl>
</div>

@ -103,7 +103,7 @@
<ul class="subject-header">
<li class="subject-header-inner">
<div class="inline-edit">
<work-package-field field="'subject'"></work-package-field>
<work-package-field field-name="'subject'"></work-package-field>
</div>
</li>
</ul>
@ -134,7 +134,7 @@
</div>
<div class="single-attribute wiki">
<work-package-field field="'description'"></work-package-field>
<work-package-field field-name="'description'"></work-package-field>
</div>
</div>
@ -167,7 +167,7 @@
ng-if="vm.isSpecified(vm.workPackage, field)"
ng-repeat-end
class="attributes-key-value--value-container">
<work-package-field field="field"></work-package-field>
<work-package-field field-name="field"></work-package-field>
</dd>
</dl>
</div>

@ -9,7 +9,7 @@
</div>
<div class="single-attribute wiki">
<work-package-field field="'description'"></work-package-field>
<work-package-field field-name="'description'"></work-package-field>
</div>
</div>
@ -42,7 +42,7 @@
ng-if="vm.isSpecified(vm.workPackage, field)"
ng-repeat-end
class="attributes-key-value--value-container">
<work-package-field field="field"></work-package-field>
<work-package-field field-name="field"></work-package-field>
</dd>
</dl>
</div>

@ -60,18 +60,6 @@ angular.module('openproject.workPackages.services')
'WORK_PACKAGE_ATTRIBUTES',
require('./work-packages-overview-service')
])
.service('WorkPackageFieldService', [
'I18n',
'WORK_PACKAGE_REGULAR_EDITABLE_FIELD',
'WorkPackagesHelper',
'$q',
'$http',
'$timeout',
'$filter',
'HookService',
'EditableFieldsState',
require('./work-package-field-service')
])
.service('EditableFieldsState',[
'$q',
'$rootScope',

@ -27,20 +27,14 @@
//++
describe('Inplace editor drop-down directive', function() {
var element,
scope,
html,
workPackageFieldService = {},
workPackageFieldConfigurationService = {},
allowedValues = [],
angularCompile;
var element, scope, html, workPackageFieldConfigurationService = {},
allowedValues = [], angularCompile;
html = '<div><inplace-editor-drop-down></inplace-editor-drop-down></div>';
beforeEach(angular.mock.module('openproject.inplace-edit'));
beforeEach(module('openproject.services', function($provide) {
$provide.constant('WorkPackageFieldService', workPackageFieldService);
$provide.constant('WorkPackageService', {});
$provide.constant('WorkPackageFieldConfigurationService', workPackageFieldConfigurationService);
}));
@ -53,7 +47,7 @@ describe('Inplace editor drop-down directive', function() {
scope = $rootScope.$new();
allowedValues = [
{ href: '/1', name: 'zzzzzz' },
{ href: '/1', name: 'zzzzzz'},
{ href: '/2', name: 'mmmmmm'},
{ href: '/3', name: 'aaaaaa'}
];
@ -62,10 +56,11 @@ describe('Inplace editor drop-down directive', function() {
resolve(allowedValues);
});
workPackageFieldService.getAllowedValues = sinon.stub().returns(allowedValuePromise);
workPackageFieldService.format = sinon.stub().returns({
props: { name: allowedValues[0].name }
});
scope.field = {
getAllowedValues: sinon.stub().returns(allowedValuePromise),
format: sinon.stub().returns({ props: { name: allowedValues[0].name } }),
isRequired: sinon.stub().returns(true)
};
// severing dependency from the work package field directive as described by
// http://busypeoples.github.io/post/testing-angularjs-hierarchical-directives
@ -75,8 +70,7 @@ describe('Inplace editor drop-down directive', function() {
writeValue: { props: { href: allowedValues[0].href } }
};
element.data('$workPackageFieldController', workPackageFieldController);
workPackageFieldService.isRequired = sinon.stub().returns(true);
workPackageFieldConfigurationService.getDropdownSortingStrategy = sinon.stub().returns(null);
angularCompile(element)(scope);
Loading…
Cancel
Save