diff --git a/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js b/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js index 628040782e31..fea78e235fe3 100644 --- a/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js +++ b/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js @@ -31,8 +31,7 @@ angular.module('openproject.workPackages.controllers') .constant('DEFAULT_WORK_PACKAGE_PROPERTIES', [ 'status', 'assignee', 'responsible', 'date', 'percentageDone', 'priority', - 'author', 'dueDate', 'estimatedTime', - 'startDate', 'versionName' + 'estimatedTime', 'versionName' ]) .constant('USER_TYPE', 'user') @@ -94,17 +93,21 @@ angular.module('openproject.workPackages.controllers') function getFormattedPropertyValue(property) { if (property === 'date') { - if (workPackage.props.startDate && workPackage.props.dueDate) { - return WorkPackagesHelper.formatWorkPackageProperty(workPackage.props['startDate'], 'startDate') + - ' - ' + - WorkPackagesHelper.formatWorkPackageProperty(workPackage.props['dueDate'], 'dueDate'); - - } + return getDateProperty(); } else { return WorkPackagesHelper.formatWorkPackageProperty(workPackage.props[property], property); } } + function getDateProperty() { + if (workPackage.props.startDate || workPackage.props.dueDate) { + var displayedStartDate = WorkPackagesHelper.formatWorkPackageProperty(workPackage.props.startDate, 'startDate') || I18n.t('js.label_no_start_date'), + displayedEndDate = WorkPackagesHelper.formatWorkPackageProperty(workPackage.props.dueDate, 'dueDate') || I18n.t('js.label_no_due_date'); + + return displayedStartDate + ' - ' + displayedEndDate; + } + } + function addFormattedValueToPresentProperties(property, label, value, format) { var propertyData = { property: property, diff --git a/config/locales/js-de.yml b/config/locales/js-de.yml index f5382587fa43..4f797e1740fa 100644 --- a/config/locales/js-de.yml +++ b/config/locales/js-de.yml @@ -93,6 +93,8 @@ de: label_move_column_right: "Spalte nach rechts verschieben" label_next: "Weiter" label_no_data: "Nichts anzuzeigen" + label_no_due_date: "kein Abgabedatum" + label_no_start_date: "kein Startdatum" label_none: "kein" label_not_contains: "enthält nicht" label_not_equals: "ist nicht" diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index ed368fad1529..07f15c5d3711 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -93,6 +93,8 @@ en: label_move_column_right: "Move column right" label_next: "Next" label_no_data: "No data to display" + label_no_due_date: "no end date" + label_no_start_date: "no start date" label_none: "none" label_not_contains: "doesn't contain" label_not_equals: "is not" diff --git a/karma/tests/controllers/work-package-details-controller-test.js b/karma/tests/controllers/work-package-details-controller-test.js index 5f28fb6aded1..63c3a5d70383 100644 --- a/karma/tests/controllers/work-package-details-controller-test.js +++ b/karma/tests/controllers/work-package-details-controller-test.js @@ -31,33 +31,45 @@ describe('WorkPackageDetailsController', function() { var scope; var buildController; + var I18n = { t: angular.identity }, + WorkPackagesHelper = { + formatWorkPackageProperty: angular.identity + }, + workPackage = { + props: { + status: 'open', + versionName: null + }, + embedded: { + activities: [] + }, + }; + + function buildWorkPackageWithId(id) { + angular.extend(workPackage.props, {id: id}); + return workPackage; + } beforeEach(module('openproject.api', 'openproject.services', 'openproject.workPackages.controllers')); beforeEach(inject(function($rootScope, $controller, $timeout) { - scope = $rootScope.$new(); - var workPackageId = 99; buildController = function() { + scope = $rootScope.$new(); + ctrl = $controller("WorkPackageDetailsController", { $scope: scope, $stateParams: { workPackageId: workPackageId }, + I18n: I18n, ConfigurationService: { commentsSortedInDescendingOrder: function() { return false; } }, - workPackage: { - props: { - id: workPackageId - }, - embedded: { - activities: [] - } - } + workPackage: buildWorkPackageWithId(workPackageId), }); - // $timeout.flush(); + $timeout.flush(); }; })); @@ -68,4 +80,157 @@ describe('WorkPackageDetailsController', function() { }); }); + describe('work package properties', function() { + function fetchPresentPropertiesWithName(propertyName) { + return scope.presentWorkPackageProperties.filter(function(propertyData) { + return propertyData.property === propertyName; + }); + } + + describe('when the property has a value', function() { + var propertyName = 'status'; + + beforeEach(function() { + buildController(); + }); + + it('adds properties to present properties', function() { + expect(fetchPresentPropertiesWithName(propertyName)).to.have.length(1); + }); + }); + + describe('when the property is among the first 3 properties', function() { + var propertyName = 'responsible'; + + beforeEach(function() { + buildController(); + }); + + it('is added to present properties even if it is empty', function() { + expect(fetchPresentPropertiesWithName(propertyName)).to.have.length(1); + }); + }); + + describe('when the property is among the second group of 3 properties', function() { + var propertyName = 'priority', + label = 'Priority'; + + beforeEach(function() { + sinon.stub(I18n, 't') + .withArgs('js.work_packages.properties.' + propertyName) + .returns(label); + + buildController(); + }); + + afterEach(function() { + I18n.t.restore(); + }); + + describe('and none of these 3 properties is present', function() { + beforeEach(function() { + buildController(); + }); + + it('is added to the empty properties', function() { + expect(scope.emptyWorkPackageProperties.indexOf(label)).to.be.greaterThan(-1); + }); + }); + + describe('and at least one of these 3 properties is present', function() { + beforeEach(function() { + workPackage.props.percentageDone = '20'; + buildController(); + }); + + it('is added to the present properties', function() { + expect(fetchPresentPropertiesWithName(propertyName)).to.have.length(1); + }); + }); + }); + + describe('when the property is not among the first 6 properties', function() { + var propertyName = 'versionName', + label = 'Version'; + + beforeEach(function() { + sinon.stub(I18n, 't') + .withArgs('js.work_packages.properties.' + propertyName) + .returns(label); + + buildController(); + }); + + afterEach(function() { + I18n.t.restore(); + }); + + it('adds properties that without values to empty properties', function() { + expect(scope.emptyWorkPackageProperties.indexOf(label)).to.be.greaterThan(-1); + }); + }); + + describe('date property', function() { + var startDate = '2014-07-09', + dueDate = '2014-07-10', + placeholder = 'placeholder'; + + + describe('when only the due date is present', function() { + beforeEach(function() { + sinon.stub(I18n, 't') + .withArgs('js.label_no_start_date') + .returns(placeholder); + + workPackage.props.startDate = null; + workPackage.props.dueDate = dueDate; + + buildController(); + }); + + afterEach(function() { + I18n.t.restore(); + }); + + it('renders the due date and a placeholder for the start date as date property', function() { + expect(fetchPresentPropertiesWithName('date')[0].value).to.equal(placeholder + ' - Jul 10, 2014'); + }); + }); + + describe('when only the start date is present', function() { + beforeEach(function() { + sinon.stub(I18n, 't') + .withArgs('js.label_no_due_date') + .returns(placeholder); + + workPackage.props.startDate = startDate; + workPackage.props.dueDate = null; + + buildController(); + }); + + afterEach(function() { + I18n.t.restore(); + }); + + it('renders the start date and a placeholder for the due date as date property', function() { + expect(fetchPresentPropertiesWithName('date')[0].value).to.equal('Jul 9, 2014 - ' + placeholder); + }); + }); + + describe('when both - start and due date are present', function() { + beforeEach(function() { + workPackage.props.startDate = startDate; + workPackage.props.dueDate = dueDate; + + buildController(); + }); + + it('combines them and renders them as date property', function() { + expect(fetchPresentPropertiesWithName('date')[0].value).to.equal('Jul 9, 2014 - Jul 10, 2014'); + }); + }); + }); + }); + }); diff --git a/public/templates/tabs/overview.html b/public/templates/tabs/overview.html deleted file mode 100644 index ed71f6d1278d..000000000000 --- a/public/templates/tabs/overview.html +++ /dev/null @@ -1,109 +0,0 @@ -
- -

Description

-
- {{ workPackage.props.description }} -
-
- -
-
- - - - Hide full description - - - - Show full description - - -
-
- -
- -
- -
-
- - - - Hide all attributes - - - - Show all attributes - - -
-
- -
-

Latest activity

- -
- -
-

Add your comments here

-
- -
- -
diff --git a/public/templates/work_packages/tabs/overview.html b/public/templates/work_packages/tabs/overview.html index 8845299c4082..39dd91055141 100644 --- a/public/templates/work_packages/tabs/overview.html +++ b/public/templates/work_packages/tabs/overview.html @@ -15,7 +15,7 @@

Description