commit
6b5d8ba71d
@ -0,0 +1,56 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
// TODO move to UI components
|
||||||
|
angular.module('openproject.uiComponents') |
||||||
|
|
||||||
|
.directive('activityComment', ['I18n', 'ActivityService', 'ConfigurationService', function(I18n, ActivityService, ConfigurationService) { |
||||||
|
return { |
||||||
|
restrict: 'E', |
||||||
|
replace: true, |
||||||
|
scope: { |
||||||
|
workPackage: '=', |
||||||
|
activities: '=' |
||||||
|
}, |
||||||
|
templateUrl: '/templates/components/activity_comment.html', |
||||||
|
link: function(scope, element, attrs) { |
||||||
|
scope.title = I18n.t('js.label_add_comment_title'); |
||||||
|
scope.buttonTitle = I18n.t('js.label_add_comment'); |
||||||
|
|
||||||
|
scope.createComment = function() { |
||||||
|
var comment = angular.element('#add-comment-text').val(); |
||||||
|
var descending = ConfigurationService.commentsSortedInDescendingOrder(); |
||||||
|
ActivityService.createComment(scope.workPackage.props.id, scope.activities, descending, comment) |
||||||
|
.then(function(response){ |
||||||
|
angular.element('#add-comment-text').val(''); |
||||||
|
return response; |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,74 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.services') |
||||||
|
|
||||||
|
.service('ActivityService', ['HALAPIResource', |
||||||
|
'$http', |
||||||
|
'PathHelper', function(HALAPIResource, $http, PathHelper){ |
||||||
|
|
||||||
|
var ActivityService = { |
||||||
|
createComment: function(workPackageId, activities, descending, comment) { |
||||||
|
var resource = HALAPIResource.setup(PathHelper.activitiesPath(workPackageId)); |
||||||
|
var options = { |
||||||
|
ajax: { |
||||||
|
method: "POST", |
||||||
|
data: { comment: comment } |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return resource.fetch(options).then(function(activity){ |
||||||
|
// We are unable to add to the work package's embedded activities directly
|
||||||
|
if(activity) { |
||||||
|
if(descending){ |
||||||
|
activities.unshift(activity); |
||||||
|
} else { |
||||||
|
activities.push(activity); |
||||||
|
} |
||||||
|
return activity; |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
|
||||||
|
updateComment: function(activityId, comment) { |
||||||
|
var resource = HALAPIResource.setup(PathHelper.activityPath(activityId)); |
||||||
|
var options = { |
||||||
|
ajax: { |
||||||
|
method: "PUT", |
||||||
|
data: { comment: comment } |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
return resource.fetch(options).then(function(activity){ |
||||||
|
return activity; |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return ActivityService; |
||||||
|
}]); |
@ -0,0 +1,155 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.controllers') |
||||||
|
|
||||||
|
.constant('DEFAULT_WORK_PACKAGE_PROPERTIES', [ |
||||||
|
'status', 'assignee', 'responsible', |
||||||
|
'date', 'percentageDone', 'priority', |
||||||
|
'estimatedTime', 'versionName' |
||||||
|
]) |
||||||
|
.constant('USER_TYPE', 'user') |
||||||
|
|
||||||
|
.controller('DetailsTabOverviewController', [ |
||||||
|
'$scope', |
||||||
|
'I18n', |
||||||
|
'DEFAULT_WORK_PACKAGE_PROPERTIES', |
||||||
|
'USER_TYPE', |
||||||
|
'CustomFieldHelper', |
||||||
|
'WorkPackagesHelper', |
||||||
|
'UserService', |
||||||
|
'$q', |
||||||
|
function($scope, I18n, DEFAULT_WORK_PACKAGE_PROPERTIES, USER_TYPE, CustomFieldHelper, WorkPackagesHelper, UserService, $q) { |
||||||
|
|
||||||
|
// work package properties
|
||||||
|
|
||||||
|
$scope.presentWorkPackageProperties = []; |
||||||
|
$scope.emptyWorkPackageProperties = []; |
||||||
|
$scope.userPath = PathHelper.staticUserPath; |
||||||
|
|
||||||
|
var workPackageProperties = DEFAULT_WORK_PACKAGE_PROPERTIES; |
||||||
|
|
||||||
|
function getPropertyValue(property, format) { |
||||||
|
if (format === USER_TYPE) { |
||||||
|
return $scope.workPackage.embedded[property]; |
||||||
|
} else { |
||||||
|
return getFormattedPropertyValue(property); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function getFormattedPropertyValue(property) { |
||||||
|
if (property === 'date') { |
||||||
|
return getDateProperty(); |
||||||
|
} else { |
||||||
|
return WorkPackagesHelper.formatWorkPackageProperty($scope.workPackage.props[property], property); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function getDateProperty() { |
||||||
|
if ($scope.workPackage.props.startDate || $scope.workPackage.props.dueDate) { |
||||||
|
var displayedStartDate = WorkPackagesHelper.formatWorkPackageProperty($scope.workPackage.props.startDate, 'startDate') || I18n.t('js.label_no_start_date'), |
||||||
|
displayedEndDate = WorkPackagesHelper.formatWorkPackageProperty($scope.workPackage.props.dueDate, 'dueDate') || I18n.t('js.label_no_due_date'); |
||||||
|
|
||||||
|
return displayedStartDate + ' - ' + displayedEndDate; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function addFormattedValueToPresentProperties(property, label, value, format) { |
||||||
|
var propertyData = { |
||||||
|
property: property, |
||||||
|
label: label, |
||||||
|
format: format, |
||||||
|
value: null |
||||||
|
}; |
||||||
|
$q.when(value).then(function(value) { |
||||||
|
propertyData.value = value; |
||||||
|
}); |
||||||
|
$scope.presentWorkPackageProperties.push(propertyData); |
||||||
|
} |
||||||
|
|
||||||
|
function secondRowToBeDisplayed() { |
||||||
|
return !!workPackageProperties |
||||||
|
.slice(3, 6) |
||||||
|
.map(function(property) { |
||||||
|
return $scope.workPackage.props[property]; |
||||||
|
}) |
||||||
|
.reduce(function(a, b) { |
||||||
|
return a || b; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
var userFields = ['assignee', 'author', 'responsible']; |
||||||
|
|
||||||
|
(function setupWorkPackageProperties() { |
||||||
|
angular.forEach(workPackageProperties, function(property, index) { |
||||||
|
var label = I18n.t('js.work_packages.properties.' + property), |
||||||
|
format = userFields.indexOf(property) === -1 ? 'text' : USER_TYPE, |
||||||
|
value = getPropertyValue(property, format); |
||||||
|
|
||||||
|
if (!!value || |
||||||
|
index < 3 || |
||||||
|
index < 6 && secondRowToBeDisplayed()) { |
||||||
|
addFormattedValueToPresentProperties(property, label, value, format); |
||||||
|
} else { |
||||||
|
$scope.emptyWorkPackageProperties.push(label); |
||||||
|
} |
||||||
|
}); |
||||||
|
})(); |
||||||
|
|
||||||
|
function getCustomPropertyValue(customProperty) { |
||||||
|
if (!!customProperty.value && customProperty.format === USER_TYPE) { |
||||||
|
return UserService.getUser(customProperty.value); |
||||||
|
} else { |
||||||
|
return CustomFieldHelper.formatCustomFieldValue(customProperty.value, customProperty.format); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
(function setupCustomProperties() { |
||||||
|
angular.forEach($scope.workPackage.props.customProperties, function(customProperty) { |
||||||
|
var property = customProperty.name, |
||||||
|
label = customProperty.name, |
||||||
|
value = getCustomPropertyValue(customProperty), |
||||||
|
format = customProperty.format; |
||||||
|
|
||||||
|
if (customProperty.value) { |
||||||
|
addFormattedValueToPresentProperties(property, label, value, format); |
||||||
|
} else { |
||||||
|
$scope.emptyWorkPackageProperties.push(label); |
||||||
|
} |
||||||
|
}); |
||||||
|
})(); |
||||||
|
|
||||||
|
// toggles
|
||||||
|
|
||||||
|
$scope.toggleStates = { |
||||||
|
hideFullDescription: true, |
||||||
|
hideAllAttributes: true |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
}]); |
@ -0,0 +1,92 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.controllers') |
||||||
|
|
||||||
|
.controller('DetailsTabWatchersController', ['$scope', 'workPackage', function($scope, workPackage) { |
||||||
|
// available watchers
|
||||||
|
|
||||||
|
$scope.$watch('watchers.length', fetchAvailableWatchers); fetchAvailableWatchers(); |
||||||
|
|
||||||
|
/** |
||||||
|
* @name getResourceIdentifier |
||||||
|
* @function |
||||||
|
* |
||||||
|
* @description |
||||||
|
* Returns the resource identifier of an API resource retrieved via hyperagent |
||||||
|
* |
||||||
|
* @param {Object} resource The resource object |
||||||
|
* |
||||||
|
* @returns {String} identifier |
||||||
|
*/ |
||||||
|
function getResourceIdentifier(resource) { |
||||||
|
// TODO move to helper
|
||||||
|
return resource.links.self.href; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* @name getFilteredCollection |
||||||
|
* @function |
||||||
|
* |
||||||
|
* @description |
||||||
|
* Filters collection of HAL resources by entries listed in resourcesToBeFilteredOut |
||||||
|
* |
||||||
|
* @param {Array} collection Array of resources retrieved via hyperagend |
||||||
|
* @param {Array} resourcesToBeFilteredOut Entries to be filtered out |
||||||
|
* |
||||||
|
* @returns {Array} filtered collection |
||||||
|
*/ |
||||||
|
function getFilteredCollection(collection, resourcesToBeFilteredOut) { |
||||||
|
return collection.filter(function(resource) { |
||||||
|
return resourcesToBeFilteredOut.map(getResourceIdentifier).indexOf(getResourceIdentifier(resource)) === -1; |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function fetchAvailableWatchers() { |
||||||
|
$scope.workPackage.links.availableWatchers |
||||||
|
.fetch() |
||||||
|
.then(function(data) { |
||||||
|
// Temporarily filter out watchers already assigned to the work package on the client-side
|
||||||
|
$scope.availableWatchers = getFilteredCollection(data.embedded.availableWatchers, $scope.watchers); |
||||||
|
// TODO do filtering on the API side and replace the update of the available watchers with the code provided in the following line
|
||||||
|
// $scope.availableWatchers = data.embedded.availableWatchers;
|
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
$scope.addWatcher = function(id) { |
||||||
|
$scope.workPackage.link('addWatcher', {user_id: id}) |
||||||
|
.fetch({ajax: {method: 'POST'}}) |
||||||
|
.then($scope.refreshWorkPackage, $scope.outputError); |
||||||
|
}; |
||||||
|
|
||||||
|
$scope.deleteWatcher = function(watcher) { |
||||||
|
watcher.links.removeWatcher |
||||||
|
.fetch({ ajax: watcher.links.removeWatcher.props }) |
||||||
|
.then($scope.refreshWorkPackage, $scope.outputError); |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,48 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.directives') |
||||||
|
|
||||||
|
.directive('attachmentFileSize', [function(){ |
||||||
|
return { |
||||||
|
restrict: 'A', |
||||||
|
replace: false, |
||||||
|
templateUrl: '/templates/work_packages/tabs/_attachment_file_size.html', |
||||||
|
scope: { |
||||||
|
attachment: '=' |
||||||
|
}, |
||||||
|
link: function(scope, element, attributes) { |
||||||
|
scope.displayFileSize = "(" + formattedFileSize(scope.attachment.props.fileSize) + ")"; |
||||||
|
|
||||||
|
function formattedFileSize(fileSize) { |
||||||
|
var size = parseFloat(fileSize); |
||||||
|
return isNaN(size) ? "0kB" : (size / 1000).toFixed(2) + "kB"; |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,43 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.directives') |
||||||
|
|
||||||
|
.directive('attachmentTitleCell', ['PathHelper', function(PathHelper){ |
||||||
|
return { |
||||||
|
restrict: 'A', |
||||||
|
replace: false, |
||||||
|
templateUrl: '/templates/work_packages/tabs/_attachment_title_cell.html', |
||||||
|
scope: { |
||||||
|
attachment: '=' |
||||||
|
}, |
||||||
|
link: function(scope, element, attributes) { |
||||||
|
scope.attachmentPath = PathHelper.staticAttachmentPath(scope.attachment.props.id, scope.attachment.props.fileName); |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,47 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.directives') |
||||||
|
|
||||||
|
.directive('attachmentUserCell', ['PathHelper', function(PathHelper){ |
||||||
|
return { |
||||||
|
restrict: 'A', |
||||||
|
templateUrl: '/templates/work_packages/tabs/_attachment_user_cell.html', |
||||||
|
scope: { |
||||||
|
attachment: '=' |
||||||
|
}, |
||||||
|
link: function(scope, element, attributes) { |
||||||
|
scope.attachment.links.author.fetch() |
||||||
|
.then(function(author){ |
||||||
|
scope.authorName = author.props.name; |
||||||
|
scope.authorId = author.props.id; |
||||||
|
scope.userPath = PathHelper.staticUserPath(author.props.id); |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,42 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.directives') |
||||||
|
|
||||||
|
.directive('attachmentsTable', ['PathHelper', 'I18n', function(PathHelper, I18n){ |
||||||
|
return { |
||||||
|
restrict: 'E', |
||||||
|
templateUrl: '/templates/work_packages/tabs/_attachments_table.html', |
||||||
|
scope: { |
||||||
|
attachments: '=' |
||||||
|
}, |
||||||
|
link: function(scope) { |
||||||
|
scope.I18n = I18n; |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,43 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.directives') |
||||||
|
|
||||||
|
.directive('attachmentsTitle', [function(){ |
||||||
|
return { |
||||||
|
restrict: 'E', |
||||||
|
replace: true, |
||||||
|
templateUrl: '/templates/work_packages/tabs/_attachments_title.html', |
||||||
|
scope: { |
||||||
|
attachments: '=' |
||||||
|
}, |
||||||
|
link: function(scope, element, attributes) { |
||||||
|
scope.attachmentsTitle = "Attachments (" + scope.attachments.length + ")"; |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,43 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.directives') |
||||||
|
|
||||||
|
.directive('editableComment', [function(){ |
||||||
|
return { |
||||||
|
restrict: 'A', |
||||||
|
scope: { |
||||||
|
activity: '=', |
||||||
|
commentInEdit: '=' |
||||||
|
}, |
||||||
|
templateUrl: '/templates/work_packages/tabs/_editable_comment.html', |
||||||
|
link: function(scope){ |
||||||
|
|
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,50 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.workPackages.tabs') |
||||||
|
|
||||||
|
.directive('exclusiveEdit', function() { |
||||||
|
return { |
||||||
|
restrict: 'EA', |
||||||
|
replace: true, |
||||||
|
transclude: true, |
||||||
|
template: '<div class="exclusive-edit" ng-transclude></div>', |
||||||
|
controller: function() { |
||||||
|
var editors = []; |
||||||
|
this.gotEditable = function(selectedEditor) { |
||||||
|
angular.forEach(editors, function(editor) { |
||||||
|
if (selectedEditor != editor) { |
||||||
|
editor.inEdit = false; } |
||||||
|
}); |
||||||
|
}; |
||||||
|
this.addEditable = function(editor) { |
||||||
|
editors.push(editor); |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
}) |
@ -0,0 +1,81 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
// TODO move to UI components
|
||||||
|
angular.module('openproject.uiComponents') |
||||||
|
|
||||||
|
.directive('workPackageRelation', [ |
||||||
|
'I18n', |
||||||
|
'PathHelper', |
||||||
|
'WorkPackagesHelper', |
||||||
|
function(I18n, PathHelper, WorkPackagesHelper) { |
||||||
|
return { |
||||||
|
restrict: 'E', |
||||||
|
replace: true, |
||||||
|
scope: { title: '@', relatedWorkPackages: '=', btnTitle: '@buttonTitle', btnIcon: '@buttonIcon', isSingletonRelation: '@singletonRelation' }, |
||||||
|
templateUrl: '/templates/work_packages/tabs/_work_package_relation.html', |
||||||
|
link: function(scope, element, attrs) { |
||||||
|
scope.I18n = I18n; |
||||||
|
scope.WorkPackagesHelper = WorkPackagesHelper; |
||||||
|
scope.workPackagePath = PathHelper.staticWorkPackagePath; |
||||||
|
scope.userPath = PathHelper.staticUserPath; |
||||||
|
|
||||||
|
var setExpandState = function() { |
||||||
|
scope.expand = scope.relatedWorkPackages && scope.relatedWorkPackages.length > 0; |
||||||
|
}; |
||||||
|
|
||||||
|
scope.$watch('relatedWorkPackages', function() { |
||||||
|
setExpandState(); |
||||||
|
}); |
||||||
|
|
||||||
|
scope.collapseStateIcon = function(collapsed) { |
||||||
|
var iconClass = 'icon-arrow-right5-'; |
||||||
|
|
||||||
|
if (collapsed) { |
||||||
|
iconClass += '3'; |
||||||
|
} else { |
||||||
|
iconClass += '2'; |
||||||
|
} |
||||||
|
|
||||||
|
return iconClass; |
||||||
|
} |
||||||
|
|
||||||
|
scope.getFullIdentifier = function(workPackage) { |
||||||
|
var id = '#' + workPackage.props.id; |
||||||
|
|
||||||
|
if (workPackage.props.type) { |
||||||
|
id += ' ' + workPackage.props.type + ':'; |
||||||
|
} |
||||||
|
|
||||||
|
id += ' ' + workPackage.props.subject; |
||||||
|
|
||||||
|
return id; |
||||||
|
}; |
||||||
|
} |
||||||
|
}; |
||||||
|
}]); |
@ -0,0 +1,7 @@ |
|||||||
|
# Components - Add comments - default |
||||||
|
|
||||||
|
``` |
||||||
|
<div class="activity-comment"> |
||||||
|
<textarea class="add-comment-text" placeholder="Add your comments here" rows=1></textarea> |
||||||
|
</div> |
||||||
|
``` |
@ -0,0 +1,44 @@ |
|||||||
|
/*-- copyright |
||||||
|
* OpenProject is a project management system. |
||||||
|
* Copyright (C) 2012-2014 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. ++*/ |
||||||
|
|
||||||
|
.activity-comment |
||||||
|
textarea |
||||||
|
border: 1px solid #cacaca |
||||||
|
background: #ffffff |
||||||
|
border-radius: 2px |
||||||
|
padding: 8px |
||||||
|
font-family: $font_family_normal |
||||||
|
font-size: $global_font_size |
||||||
|
width: 100% |
||||||
|
box-sizing: border-box |
||||||
|
&:hover |
||||||
|
border: 1px solid #aaaaaa |
||||||
|
&:focus |
||||||
|
border: 1px solid #aaaaaa |
||||||
|
box-shadow: 1px 1px 1px #dddddd inset |
||||||
|
.add-comment-text |
||||||
|
resize: none |
@ -0,0 +1,10 @@ |
|||||||
|
# Components - Add comments - onclick |
||||||
|
|
||||||
|
``` |
||||||
|
<div class="activity-comment"> |
||||||
|
<textarea class="add-comment-text-big" placeholder="Add your comments here" rows=4></textarea> |
||||||
|
<button class="button"><i class="icon-yes icon-left"></i>Add comment</button><button class="button"><i class="icon-close icon-left"></i>Cancel</button> |
||||||
|
</div> |
||||||
|
|
||||||
|
``` |
||||||
|
|
@ -0,0 +1,28 @@ |
|||||||
|
/*-- copyright |
||||||
|
* OpenProject is a project management system. |
||||||
|
* Copyright (C) 2012-2014 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. ++*/ |
||||||
|
|
||||||
|
|
@ -0,0 +1,41 @@ |
|||||||
|
/*-- copyright |
||||||
|
* OpenProject is a project management system. |
||||||
|
* Copyright (C) 2012-2014 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. ++ |
||||||
|
*/ |
||||||
|
|
||||||
|
.activity-comment |
||||||
|
textarea |
||||||
|
width: 100% |
||||||
|
height: 6em |
||||||
|
-webkit-box-sizing: border-box |
||||||
|
-moz-box-sizing: border-box |
||||||
|
box-sizing: border-box |
||||||
|
-webkit-border-radius: 3px |
||||||
|
-moz-border-radius: 3px |
||||||
|
border-radius: 3px |
||||||
|
.button |
||||||
|
float: right |
||||||
|
margin-right: 0px |
@ -0,0 +1,87 @@ |
|||||||
|
/*-- copyright |
||||||
|
* OpenProject is a project management system. |
||||||
|
* Copyright (C) 2012-2014 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. ++ |
||||||
|
*/ |
||||||
|
|
||||||
|
.attachments-container |
||||||
|
float: left |
||||||
|
margin: 0 0 30px 0 |
||||||
|
width: 100% |
||||||
|
ul |
||||||
|
margin: 0 |
||||||
|
padding: 0 |
||||||
|
list-style-type: none |
||||||
|
li |
||||||
|
margin: 0 |
||||||
|
padding: 0 |
||||||
|
line-height: 20px |
||||||
|
table |
||||||
|
padding: 0 |
||||||
|
margin: 0px 0 10px 0 |
||||||
|
float: left |
||||||
|
border-collapse: collapse |
||||||
|
border: 0px solid #ddd |
||||||
|
width: 100% |
||||||
|
table-layout: fixed |
||||||
|
tbody |
||||||
|
tr |
||||||
|
td |
||||||
|
white-space: nowrap |
||||||
|
overflow: hidden |
||||||
|
text-overflow: ellipsis |
||||||
|
width: 10% |
||||||
|
tr |
||||||
|
&:hover |
||||||
|
background: #ffffae |
||||||
|
th |
||||||
|
text-align: left |
||||||
|
font-family: 'LatoBold' |
||||||
|
font-weight: normal |
||||||
|
text-transform: uppercase |
||||||
|
background: #fff |
||||||
|
padding: 6px 10px 6px 0 |
||||||
|
border-bottom: 2px solid #eee |
||||||
|
td |
||||||
|
text-align: left |
||||||
|
font-weight: normal |
||||||
|
border-bottom: 0px solid #ddd |
||||||
|
padding: 6px 10px 6px 0 |
||||||
|
|
||||||
|
|
||||||
|
.add-file |
||||||
|
float: left |
||||||
|
padding: 8px 0 0 10px |
||||||
|
i |
||||||
|
font-size: 12px |
||||||
|
padding: 0 2px 0 0 |
||||||
|
|
||||||
|
.upload-file |
||||||
|
display: block |
||||||
|
width: 100% |
||||||
|
float: left |
||||||
|
margin: 20px 0 0 0 |
||||||
|
padding: 20px 0 0 0 |
||||||
|
border-top: 1px solid #ddd |
@ -0,0 +1,52 @@ |
|||||||
|
/*-- copyright |
||||||
|
* OpenProject is a project management system. |
||||||
|
* Copyright (C) 2012-2013 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. ++ |
||||||
|
*/ |
||||||
|
|
||||||
|
.detail-panel-description |
||||||
|
width: 100% |
||||||
|
.detail-panel-description-content |
||||||
|
.relation |
||||||
|
h3 |
||||||
|
cursor: pointer |
||||||
|
.content |
||||||
|
.workpackages |
||||||
|
table |
||||||
|
width: 100% |
||||||
|
table-layout: fixed |
||||||
|
thead |
||||||
|
font-weight: bold |
||||||
|
text-transform: uppercase |
||||||
|
line-height: 32px |
||||||
|
tr |
||||||
|
td |
||||||
|
text-overflow: ellipsis |
||||||
|
white-space: nowrap |
||||||
|
overflow: hidden |
||||||
|
&:first-of-type |
||||||
|
width: 55% |
||||||
|
&:last-of-type |
||||||
|
width: 30% |
@ -0,0 +1,37 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
#-- copyright |
||||||
|
# OpenProject is a project management system. |
||||||
|
# Copyright (C) 2012-2014 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. |
||||||
|
#++ |
||||||
|
|
||||||
|
module ContentForHelper |
||||||
|
# Thanks to http://blog.plataformatec.com.br/2012/07/flushing-content-blocks-with-rails-4/ |
||||||
|
# TODO: This method becomes obsolete with Rails 4 and the 'flush' parameter |
||||||
|
def single_content_for(name, content = nil, &block) |
||||||
|
@view_flow.set(name, ActiveSupport::SafeBuffer.new) |
||||||
|
content_for(name, content, &block) |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,32 @@ |
|||||||
|
<%#-- copyright |
||||||
|
OpenProject is a project management system. |
||||||
|
Copyright (C) 2012-2014 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. |
||||||
|
|
||||||
|
++#%> |
||||||
|
|
||||||
|
<div id="nav-login-content"> |
||||||
|
<%= render :partial => 'account/auth_providers' %> |
||||||
|
</div> |
@ -0,0 +1,63 @@ |
|||||||
|
<%#-- copyright |
||||||
|
OpenProject is a project management system. |
||||||
|
Copyright (C) 2012-2014 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. |
||||||
|
|
||||||
|
++#%> |
||||||
|
|
||||||
|
<%= form_tag({:action=> "login"}, autocomplete: 'off') do %> |
||||||
|
<%= back_url_hidden_field_tag %> |
||||||
|
|
||||||
|
<div class="attribute_wrapper"> |
||||||
|
<label for="username"><%= User.human_attribute_name :login %></label> |
||||||
|
<%= text_field_tag 'username', nil %> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="attribute_wrapper"> |
||||||
|
<label for="password"><%= User.human_attribute_name :password %></label> |
||||||
|
<%= password_field_tag 'password', nil %> |
||||||
|
</div> |
||||||
|
|
||||||
|
<div class="login-options-container"> |
||||||
|
<div class="login-links"> |
||||||
|
<% if Setting.lost_password? %> |
||||||
|
<%= link_to l(:label_password_lost), :controller => '/account', :action => 'lost_password' %> |
||||||
|
<br> |
||||||
|
<% end %> |
||||||
|
<% if Setting.self_registration? %> |
||||||
|
<%= link_to l(:label_register), { :controller => '/account', :action => 'register' } %> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
<% if Setting.autologin? %> |
||||||
|
<div class="attribute_wrapper indented"> |
||||||
|
<label for="autologin"> |
||||||
|
<%= check_box_tag 'autologin', 1, false %> <%= l(:label_stay_logged_in) %> |
||||||
|
</label> |
||||||
|
</div> |
||||||
|
<% end %> |
||||||
|
</div> |
||||||
|
<input type="submit" name="login" value="<%=l(:button_login)%>" class="button_highlight" /> |
||||||
|
<%= javascript_tag "Form.Element.focus('username');" %> |
||||||
|
<% end %> |
@ -0,0 +1,175 @@ |
|||||||
|
package Apache::Authn::OpenProject; |
||||||
|
|
||||||
|
=head1 Apache::Authn::OpenProject |
||||||
|
|
||||||
|
OpenProject - a mod_perl module to authenticate webdav subversion users |
||||||
|
against an OpenProject web service |
||||||
|
|
||||||
|
=head1 SYNOPSIS |
||||||
|
|
||||||
|
This module allow anonymous users to browse public project and |
||||||
|
registred users to browse and commit their project. Authentication is |
||||||
|
done against an OpenProject web service. |
||||||
|
|
||||||
|
=head1 INSTALLATION |
||||||
|
|
||||||
|
For this to automagically work, you need to have a recent reposman.rb. |
||||||
|
|
||||||
|
Sorry ruby users but you need some perl modules, at least mod_perl2 and apache2-svn. |
||||||
|
|
||||||
|
On debian/ubuntu you must do : |
||||||
|
|
||||||
|
aptitude install libapache2-mod-perl2 libapache2-svn |
||||||
|
|
||||||
|
=head1 CONFIGURATION |
||||||
|
|
||||||
|
## This module has to be in your perl path |
||||||
|
## eg: /usr/lib/perl5/Apache/Authn/OpenProjectAuthentication.pm |
||||||
|
PerlLoadModule Apache::Authn::OpenProjectAuthentication |
||||||
|
<Location /svn> |
||||||
|
DAV svn |
||||||
|
SVNParentPath "/var/svn" |
||||||
|
|
||||||
|
AuthType Basic |
||||||
|
AuthName OpenProject |
||||||
|
Require valid-user |
||||||
|
|
||||||
|
PerlAccessHandler Apache::Authn::OpenProject::access_handler |
||||||
|
PerlAuthenHandler Apache::Authn::OpenProject::authen_handler |
||||||
|
|
||||||
|
OpenProjectUrl "http://example.com/openproject/" |
||||||
|
OpenProjectApiKey "<API key>" |
||||||
|
</Location> |
||||||
|
|
||||||
|
To be able to browse repository inside openproject, you must add something |
||||||
|
like that : |
||||||
|
|
||||||
|
<Location /svn-private> |
||||||
|
DAV svn |
||||||
|
SVNParentPath "/var/svn" |
||||||
|
Order deny,allow |
||||||
|
Deny from all |
||||||
|
# only allow reading orders |
||||||
|
<Limit GET PROPFIND OPTIONS REPORT> |
||||||
|
Allow from openproject.server.ip |
||||||
|
</Limit> |
||||||
|
</Location> |
||||||
|
|
||||||
|
and you will have to use this reposman.rb command line to create repository : |
||||||
|
|
||||||
|
reposman.rb --openproject my.openproject.server --svn-dir /var/svn --owner www-data -u http://svn.server/svn-private/ |
||||||
|
|
||||||
|
=cut |
||||||
|
|
||||||
|
use strict; |
||||||
|
use warnings FATAL => 'all', NONFATAL => 'redefine'; |
||||||
|
|
||||||
|
use Digest::SHA; |
||||||
|
|
||||||
|
use Apache2::Module; |
||||||
|
use Apache2::Access; |
||||||
|
use Apache2::ServerRec qw(); |
||||||
|
use Apache2::RequestRec qw(); |
||||||
|
use Apache2::RequestUtil qw(); |
||||||
|
use Apache2::Const qw(:common :override :cmd_how); |
||||||
|
use APR::Pool (); |
||||||
|
use APR::Table (); |
||||||
|
|
||||||
|
use HTTP::Request::Common qw(POST); |
||||||
|
use LWP::UserAgent; |
||||||
|
|
||||||
|
# use Apache2::Directive qw(); |
||||||
|
|
||||||
|
my @directives = ( |
||||||
|
{ |
||||||
|
name => 'OpenProjectUrl', |
||||||
|
req_override => OR_AUTHCFG, |
||||||
|
args_how => TAKE1, |
||||||
|
errmsg => 'URL of your (local) OpenProject. (e.g. http://localhost/ or http://www.example.com/openproject/)', |
||||||
|
}, |
||||||
|
{ |
||||||
|
name => 'OpenProjectApiKey', |
||||||
|
req_override => OR_AUTHCFG, |
||||||
|
args_how => TAKE1, |
||||||
|
}, |
||||||
|
); |
||||||
|
|
||||||
|
sub OpenProjectUrl { set_val('OpenProjectUrl', @_); } |
||||||
|
sub OpenProjectApiKey { set_val('OpenProjectApiKey', @_); } |
||||||
|
|
||||||
|
sub trim { |
||||||
|
my $string = shift; |
||||||
|
$string =~ s/\s{2,}/ /g; |
||||||
|
return $string; |
||||||
|
} |
||||||
|
|
||||||
|
sub set_val { |
||||||
|
my ($key, $self, $parms, $arg) = @_; |
||||||
|
$self->{$key} = $arg; |
||||||
|
} |
||||||
|
|
||||||
|
Apache2::Module::add(__PACKAGE__, \@directives); |
||||||
|
|
||||||
|
sub access_handler { |
||||||
|
my $r = shift; |
||||||
|
|
||||||
|
unless ($r->some_auth_required) { |
||||||
|
$r->log_reason("No authentication has been configured"); |
||||||
|
return FORBIDDEN; |
||||||
|
} |
||||||
|
|
||||||
|
return OK |
||||||
|
} |
||||||
|
|
||||||
|
sub authen_handler { |
||||||
|
my $r = shift; |
||||||
|
|
||||||
|
my ($status, $password) = $r->get_basic_auth_pw(); |
||||||
|
my $login = $r->user; |
||||||
|
|
||||||
|
return $status unless $status == OK; |
||||||
|
|
||||||
|
my $identifier = get_project_identifier($r); |
||||||
|
my $method = $r->method; |
||||||
|
|
||||||
|
if( is_access_allowed( $login, $password, $identifier, $method, $r ) ) { |
||||||
|
return OK; |
||||||
|
} else { |
||||||
|
$r->note_auth_failure(); |
||||||
|
return AUTH_REQUIRED; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
# we send a request to the openproject sys api |
||||||
|
# and use the user's given login and password for basic auth |
||||||
|
# for accessing the openproject sys api an api key is needed |
||||||
|
sub is_access_allowed { |
||||||
|
my $login = shift; |
||||||
|
my $password = shift; |
||||||
|
my $identifier = shift; |
||||||
|
my $method = shift; |
||||||
|
my $r = shift; |
||||||
|
|
||||||
|
my $cfg = Apache2::Module::get_config( __PACKAGE__, $r->server, $r->per_dir_config ); |
||||||
|
|
||||||
|
my $key = $cfg->{OpenProjectApiKey}; |
||||||
|
my $openproject_url = $cfg->{OpenProjectUrl} . '/sys/repo_auth'; |
||||||
|
|
||||||
|
my $openproject_req = POST $openproject_url , [ repository => $identifier, key => $key, method => $method ]; |
||||||
|
$openproject_req->authorization_basic( $login, $password ); |
||||||
|
|
||||||
|
my $ua = LWP::UserAgent->new; |
||||||
|
my $response = $ua->request($openproject_req); |
||||||
|
|
||||||
|
return $response->is_success(); |
||||||
|
} |
||||||
|
|
||||||
|
sub get_project_identifier { |
||||||
|
my $r = shift; |
||||||
|
|
||||||
|
my $location = $r->location; |
||||||
|
my ($identifier) = $r->uri =~ m{$location/*([^/]+)}; |
||||||
|
$identifier; |
||||||
|
} |
||||||
|
|
||||||
|
1; |
@ -1,52 +0,0 @@ |
|||||||
-- -- copyright |
|
||||||
-- OpenProject is a project management system. |
|
||||||
-- Copyright (C) 2012-2014 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. |
|
||||||
-- ++ |
|
||||||
|
|
||||||
/* ssh views */ |
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW ssh_users as |
|
||||||
select login as username, hashed_password as password |
|
||||||
from users |
|
||||||
where status = 1; |
|
||||||
|
|
||||||
|
|
||||||
/* nss views */ |
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW nss_groups AS |
|
||||||
select identifier AS name, (id + 5000) AS gid, 'x' AS password |
|
||||||
from projects; |
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW nss_users AS |
|
||||||
select login AS username, CONCAT_WS(' ', firstname, lastname) as realname, (id + 5000) AS uid, 'x' AS password |
|
||||||
from users |
|
||||||
where status = 1; |
|
||||||
|
|
||||||
CREATE OR REPLACE VIEW nss_grouplist AS |
|
||||||
select (members.project_id + 5000) AS gid, users.login AS username |
|
||||||
from users, members |
|
||||||
where users.id = members.user_id |
|
||||||
and users.status = 1; |
|
@ -0,0 +1,295 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
/*jshint expr: true*/ |
||||||
|
|
||||||
|
describe('DetailsTabOverviewController', function() { |
||||||
|
var scope; |
||||||
|
var buildController; |
||||||
|
var I18n = { t: angular.identity }, |
||||||
|
WorkPackagesHelper = { |
||||||
|
formatWorkPackageProperty: angular.identity |
||||||
|
}, |
||||||
|
UserService = { |
||||||
|
getUser: angular.identity |
||||||
|
}, |
||||||
|
CustomFieldHelper = { |
||||||
|
formatCustomFieldValue: angular.identity |
||||||
|
}, |
||||||
|
workPackage = { |
||||||
|
props: { |
||||||
|
status: 'open', |
||||||
|
versionName: null, |
||||||
|
customProperties: [ |
||||||
|
{ format: 'text', name: 'color', value: 'red' }, |
||||||
|
] |
||||||
|
}, |
||||||
|
embedded: { |
||||||
|
activities: [], |
||||||
|
watchers: [], |
||||||
|
attachments: [] |
||||||
|
}, |
||||||
|
}; |
||||||
|
|
||||||
|
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) { |
||||||
|
var workPackageId = 99; |
||||||
|
|
||||||
|
buildController = function() { |
||||||
|
scope = $rootScope.$new(); |
||||||
|
scope.workPackage = workPackage; |
||||||
|
|
||||||
|
ctrl = $controller("DetailsTabOverviewController", { |
||||||
|
$scope: scope, |
||||||
|
I18n: I18n, |
||||||
|
UserService: UserService, |
||||||
|
CustomFieldHelper: CustomFieldHelper, |
||||||
|
}); |
||||||
|
|
||||||
|
$timeout.flush(); |
||||||
|
}; |
||||||
|
|
||||||
|
})); |
||||||
|
|
||||||
|
describe('initialisation', function() { |
||||||
|
it('should initialise', function() { |
||||||
|
buildController(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
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'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('custom field properties', function() { |
||||||
|
var customPropertyName = 'color'; |
||||||
|
|
||||||
|
describe('when the property has a value', function() { |
||||||
|
beforeEach(function() { |
||||||
|
formatCustomFieldValueSpy = sinon.spy(CustomFieldHelper, 'formatCustomFieldValue'); |
||||||
|
|
||||||
|
buildController(); |
||||||
|
}); |
||||||
|
|
||||||
|
afterEach(function() { |
||||||
|
CustomFieldHelper.formatCustomFieldValue.restore(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('adds properties to present properties', function() { |
||||||
|
expect(fetchPresentPropertiesWithName(customPropertyName)).to.have.length(1); |
||||||
|
}); |
||||||
|
|
||||||
|
it('formats values using the custom field helper', function() { |
||||||
|
expect(CustomFieldHelper.formatCustomFieldValue.calledWith('red', 'text')).to.be.true; |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('when the property does not have a value', function() { |
||||||
|
beforeEach(function() { |
||||||
|
workPackage.props.customProperties[0].value = null; |
||||||
|
buildController(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('adds the custom property to empty properties', function() { |
||||||
|
expect(scope.emptyWorkPackageProperties.indexOf(customPropertyName)).to.be.greaterThan(-1); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('user custom property', function() { |
||||||
|
var userId = '1'; |
||||||
|
|
||||||
|
beforeEach(function() { |
||||||
|
workPackage.props.customProperties[0].value = userId; |
||||||
|
workPackage.props.customProperties[0].format = 'user'; |
||||||
|
|
||||||
|
getUserSpy = sinon.spy(UserService, 'getUser'); |
||||||
|
buildController(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('fetches the user using the user service', function() { |
||||||
|
expect(UserService.getUser.calledWith(userId)).to.be.true; |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
}); |
@ -0,0 +1,186 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
describe('date time Directives', function() { |
||||||
|
var I18n, compile, element, scope, timezoneService, configurationService; |
||||||
|
|
||||||
|
var formattedDate = function() { |
||||||
|
var formattedDateElement = element[0]; |
||||||
|
|
||||||
|
return formattedDateElement.innerText || formattedDateElement.textContent; |
||||||
|
}; |
||||||
|
|
||||||
|
beforeEach(angular.mock.module('openproject.uiComponents', 'openproject.services')); |
||||||
|
beforeEach(module('templates', function($provide) { |
||||||
|
configurationService = new Object(); |
||||||
|
|
||||||
|
configurationService.isTimezoneSet = sinon.stub().returns(false); |
||||||
|
|
||||||
|
$provide.constant('ConfigurationService', configurationService); |
||||||
|
})); |
||||||
|
|
||||||
|
beforeEach(inject(function($rootScope, $compile, _I18n_, _TimezoneService_) { |
||||||
|
scope = $rootScope.$new(); |
||||||
|
|
||||||
|
scope.testDateTime = "2013-02-08T09:30:26"; |
||||||
|
|
||||||
|
compile = function(html) { |
||||||
|
element = $compile(html)(scope); |
||||||
|
scope.$digest(); |
||||||
|
}; |
||||||
|
|
||||||
|
TimezoneService = _TimezoneService_; |
||||||
|
|
||||||
|
I18n = _I18n_; |
||||||
|
|
||||||
|
I18n.locale = 'en'; |
||||||
|
})); |
||||||
|
|
||||||
|
var shouldBehaveLikeHashTitle = function(title) { |
||||||
|
it('has title', function() { |
||||||
|
expect(angular.element(element)[0].title).to.eq(title); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
describe('date directive', function() { |
||||||
|
var html = '<date date-value="testDateTime"></date>'; |
||||||
|
|
||||||
|
describe('without configuration', function() { |
||||||
|
beforeEach(function() { |
||||||
|
configurationService.dateFormatPresent = sinon.stub().returns(false); |
||||||
|
|
||||||
|
compile(html); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should use default formatting', function() { |
||||||
|
expect(formattedDate()).to.contain('02/08/2013'); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeHashTitle('02/08/2013'); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('with configuration', function() { |
||||||
|
beforeEach(function() { |
||||||
|
configurationService.dateFormatPresent = sinon.stub().returns(true); |
||||||
|
configurationService.dateFormat = sinon.stub().returns("DD-MM-YYYY"); |
||||||
|
|
||||||
|
compile(html); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should use user specified formatting', function() { |
||||||
|
expect(formattedDate()).to.contain('08-02-2013'); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeHashTitle('08-02-2013'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('time directive', function() { |
||||||
|
var html = '<time time-value="testDateTime"></time>'; |
||||||
|
|
||||||
|
describe('without configuration', function() { |
||||||
|
beforeEach(function() { |
||||||
|
configurationService.timeFormatPresent = sinon.stub().returns(false); |
||||||
|
|
||||||
|
compile(html); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should use default formatting', function() { |
||||||
|
expect(formattedDate()).to.contain('9:30 AM'); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeHashTitle('9:30 AM'); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('with configuration', function() { |
||||||
|
beforeEach(function() { |
||||||
|
configurationService.timeFormatPresent = sinon.stub().returns(true); |
||||||
|
configurationService.timeFormat = sinon.stub().returns("HH:mm a"); |
||||||
|
|
||||||
|
compile(html); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should use user specified formatting', function() { |
||||||
|
expect(formattedDate()).to.contain('09:30 am'); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeHashTitle('09:30 am'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('date time directive', function() { |
||||||
|
var html = '<date-time date-time-value="testDateTime"></date-time>'; |
||||||
|
|
||||||
|
var formattedDateTime = function() { |
||||||
|
var formattedDateElements = [element.children()[0], element.children()[1]]; |
||||||
|
var formattedDateTime = ""; |
||||||
|
|
||||||
|
for (var x = 0; x < formattedDateElements.length; x++) { |
||||||
|
formattedDateTime += (formattedDateElements[x].innerText || formattedDateElements[x].textContent) + " "; |
||||||
|
} |
||||||
|
|
||||||
|
return formattedDateTime; |
||||||
|
}; |
||||||
|
|
||||||
|
describe('without configuration', function() { |
||||||
|
beforeEach(function() { |
||||||
|
configurationService.dateFormatPresent = sinon.stub().returns(false); |
||||||
|
configurationService.timeFormatPresent = sinon.stub().returns(false); |
||||||
|
|
||||||
|
scope.dateTimeValue = "2013-02-08T09:30:26"; |
||||||
|
|
||||||
|
compile(html); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should use default formatting', function() { |
||||||
|
expect(formattedDateTime()).to.contain('02/08/2013'); |
||||||
|
expect(formattedDateTime()).to.contain('9:30 AM'); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeHashTitle('02/08/2013 9:30 AM'); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('with configuration', function() { |
||||||
|
beforeEach(function() { |
||||||
|
configurationService.dateFormatPresent = sinon.stub().returns(true); |
||||||
|
configurationService.timeFormatPresent = sinon.stub().returns(true); |
||||||
|
configurationService.dateFormat = sinon.stub().returns("DD-MM-YYYY"); |
||||||
|
configurationService.timeFormat = sinon.stub().returns("HH:mm a"); |
||||||
|
|
||||||
|
compile(html); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should use user specified formatting', function() { |
||||||
|
expect(formattedDateTime()).to.contain('08-02-2013'); |
||||||
|
expect(formattedDateTime()).to.contain('09:30 am'); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeHashTitle('08-02-2013 09:30 am'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,234 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
describe('Work Package Relation Directive', function() { |
||||||
|
var I18n, PathHelper, compile, element, scope; |
||||||
|
|
||||||
|
beforeEach(angular.mock.module('openproject.uiComponents', 'openproject.helpers', 'ngSanitize')); |
||||||
|
beforeEach(module('templates', function($provide) { |
||||||
|
})); |
||||||
|
|
||||||
|
beforeEach(inject(function($rootScope, $compile, _I18n_, _PathHelper_) { |
||||||
|
scope = $rootScope.$new(); |
||||||
|
|
||||||
|
compile = function(html) { |
||||||
|
element = $compile(html)(scope); |
||||||
|
scope.$digest(); |
||||||
|
}; |
||||||
|
|
||||||
|
I18n = _I18n_; |
||||||
|
PathHelper = _PathHelper_; |
||||||
|
|
||||||
|
var stub = sinon.stub(I18n, 't'); |
||||||
|
|
||||||
|
stub.withArgs('js.work_packages.properties.subject').returns('Column0'); |
||||||
|
stub.withArgs('js.work_packages.properties.status').returns('Column1'); |
||||||
|
stub.withArgs('js.work_packages.properties.assignee').returns('Column2'); |
||||||
|
})); |
||||||
|
|
||||||
|
afterEach(function() { |
||||||
|
I18n.t.restore(); |
||||||
|
}); |
||||||
|
|
||||||
|
var multiElementHtml = "<work-package-relation title='MyRelation' related-work-packages='relations' button-title='Add Relation' button-icon='%MyIcon%'></work-package-relation>" |
||||||
|
var singleElementHtml = "<work-package-relation title='MyRelation' related-work-packages='relations' button-title='Add Relation' button-icon='%MyIcon%' singleton-relation='true'></work-package-relation>" |
||||||
|
|
||||||
|
|
||||||
|
var workPackage1; |
||||||
|
var workPackage2; |
||||||
|
|
||||||
|
beforeEach(function() { |
||||||
|
workPackage1 = { |
||||||
|
props: { |
||||||
|
id: "1", |
||||||
|
subject: "Subject 1", |
||||||
|
status: "Status 1" |
||||||
|
}, |
||||||
|
embedded: { |
||||||
|
assignee: { |
||||||
|
props: { |
||||||
|
name: "Assignee 1", |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
workPackage2 = { |
||||||
|
props: { |
||||||
|
id: "2", |
||||||
|
subject: "Subject 2", |
||||||
|
status: "Status 2" |
||||||
|
}, |
||||||
|
embedded: { |
||||||
|
assignee: { |
||||||
|
props: { |
||||||
|
name: "Assignee 2", |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
}); |
||||||
|
|
||||||
|
var shouldBehaveLikeRelationDirective = function() { |
||||||
|
it('should have a title', function() { |
||||||
|
var title = angular.element(element.find('h3')); |
||||||
|
|
||||||
|
expect(title.text()).to.include('MyRelation'); |
||||||
|
}); |
||||||
|
|
||||||
|
//it('should have a button', function() {
|
||||||
|
// var button = angular.element(element.find('button.button'));
|
||||||
|
|
||||||
|
// expect(button.attr('title')).to.include('Add Relation');
|
||||||
|
// expect(button.text()).to.include('Add Relation');
|
||||||
|
// expect(button.text()).to.include('%MyIcon%');
|
||||||
|
//});
|
||||||
|
}; |
||||||
|
|
||||||
|
var shouldBehaveLikeHasTableHeader = function() { |
||||||
|
it('should have a table head', function() { |
||||||
|
var column0 = angular.element(element.find('.workpackages table thead td:nth-child(1)')); |
||||||
|
var column1 = angular.element(element.find('.workpackages table thead td:nth-child(2)')); |
||||||
|
var column2 = angular.element(element.find('.workpackages table thead td:nth-child(3)')); |
||||||
|
|
||||||
|
expect(angular.element(column0).text()).to.eq(I18n.t('js.work_packages.properties.subject')); |
||||||
|
expect(angular.element(column1).text()).to.eq(I18n.t('js.work_packages.properties.status')); |
||||||
|
expect(angular.element(column2).text()).to.eq(I18n.t('js.work_packages.properties.assignee')); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var shouldBehaveLikeHasTableContent = function(count) { |
||||||
|
it('should have table content', function() { |
||||||
|
for (var x = 1; x <= count; x++) { |
||||||
|
var column0 = angular.element(element.find('.workpackages table tbody:nth-of-type(' + x + ') tr td:nth-child(1)')); |
||||||
|
var column1 = angular.element(element.find('.workpackages table tbody:nth-of-type(' + x + ') tr td:nth-child(2)')); |
||||||
|
var column2 = angular.element(element.find('.workpackages table tbody:nth-of-type(' + x + ') tr td:nth-child(3)')); |
||||||
|
|
||||||
|
expect(angular.element(column0).text()).to.include('Subject ' + x); |
||||||
|
expect(angular.element(column1).text()).to.include('Status ' + x); |
||||||
|
expect(angular.element(column2).text()).to.include('Assignee ' + x); |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var shouldBehaveLikeCollapsedRelationsDirective = function() { |
||||||
|
|
||||||
|
shouldBehaveLikeRelationDirective(); |
||||||
|
|
||||||
|
it('should be initially collapsed', function() { |
||||||
|
var content = angular.element(element.find('div.content')); |
||||||
|
expect(content.hasClass('ng-hide')).to.eq(true); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var shouldBehaveLikeExpandedRelationsDirective = function() { |
||||||
|
|
||||||
|
shouldBehaveLikeRelationDirective(); |
||||||
|
|
||||||
|
it('should be initially expanded', function() { |
||||||
|
var content = angular.element(element.find('div.content')); |
||||||
|
expect(content.hasClass('ng-hide')).to.eq(false); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var shouldBehaveLikeSingleRelationDirective = function() { |
||||||
|
it('should not have an elements count', function() { |
||||||
|
var title = angular.element(element.find('h3')); |
||||||
|
|
||||||
|
expect(title.text()).not.to.include('('); |
||||||
|
expect(title.text()).not.to.include(')'); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
var shouldBehaveLikeMultiRelationDirective = function() { |
||||||
|
it('should have an elements count', function() { |
||||||
|
var title = angular.element(element.find('h3')); |
||||||
|
|
||||||
|
expect(title.text()).to.include('(' + scope.relations.length + ')'); |
||||||
|
}); |
||||||
|
}; |
||||||
|
|
||||||
|
describe('no element markup', function() { |
||||||
|
describe('single element behavior', function() { |
||||||
|
beforeEach(function() { |
||||||
|
compile(singleElementHtml); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeSingleRelationDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeCollapsedRelationsDirective(); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('multi element behavior', function() { |
||||||
|
beforeEach(function() { |
||||||
|
scope.relations = []; |
||||||
|
|
||||||
|
compile(multiElementHtml); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeMultiRelationDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeCollapsedRelationsDirective(); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('single element markup', function() { |
||||||
|
beforeEach(function() { |
||||||
|
scope.relations = [workPackage1]; |
||||||
|
|
||||||
|
compile(singleElementHtml); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeRelationDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeSingleRelationDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeExpandedRelationsDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeHasTableHeader(); |
||||||
|
|
||||||
|
shouldBehaveLikeHasTableContent(1); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('multi element markup', function() { |
||||||
|
beforeEach(function() { |
||||||
|
scope.relations = [workPackage1, workPackage2]; |
||||||
|
|
||||||
|
compile(multiElementHtml); |
||||||
|
}); |
||||||
|
|
||||||
|
shouldBehaveLikeRelationDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeMultiRelationDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeExpandedRelationsDirective(); |
||||||
|
|
||||||
|
shouldBehaveLikeHasTableHeader(); |
||||||
|
|
||||||
|
shouldBehaveLikeHasTableContent(2); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,90 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
describe('attachmentFileSize Directive', function() { |
||||||
|
var compile, element, rootScope, scope; |
||||||
|
|
||||||
|
beforeEach(angular.mock.module('openproject.workPackages.directives')); |
||||||
|
beforeEach(module('templates')); |
||||||
|
|
||||||
|
beforeEach(inject(function($rootScope, $compile) { |
||||||
|
var html; |
||||||
|
html = '<td attachment-file-size attachment="attachment"></td>'; |
||||||
|
|
||||||
|
element = angular.element(html); |
||||||
|
rootScope = $rootScope; |
||||||
|
scope = $rootScope.$new(); |
||||||
|
|
||||||
|
compile = function() { |
||||||
|
$compile(element)(scope); |
||||||
|
scope.$digest(); |
||||||
|
}; |
||||||
|
})); |
||||||
|
|
||||||
|
describe('element', function() { |
||||||
|
describe('with file size present on attachment', function(){ |
||||||
|
beforeEach(function() { |
||||||
|
scope.attachment = { |
||||||
|
props: { |
||||||
|
id: 1, |
||||||
|
fileSize: '12340' |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
compile(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render element', function() { |
||||||
|
expect(element.prop('tagName')).to.equal('TD'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render file size in kB', function() { |
||||||
|
var el = element.find('span'); |
||||||
|
expect(el.text()).to.equal('(12.34kB)'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
describe('with missing file size', function(){ |
||||||
|
beforeEach(function() { |
||||||
|
scope.attachment = { |
||||||
|
props: { |
||||||
|
id: 1 |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
compile(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render 0kB', function() { |
||||||
|
var el = element.find('span'); |
||||||
|
expect(el.text()).to.equal('(0kB)'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,72 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
describe('attachmentTitleCell Directive', function() { |
||||||
|
var compile, element, rootScope, scope; |
||||||
|
|
||||||
|
beforeEach(angular.mock.module('openproject.workPackages.directives')); |
||||||
|
beforeEach(module('templates')); |
||||||
|
|
||||||
|
beforeEach(inject(function($rootScope, $compile) { |
||||||
|
var html; |
||||||
|
html = '<td attachment-title-cell attachment="attachment"></td>'; |
||||||
|
|
||||||
|
element = angular.element(html); |
||||||
|
rootScope = $rootScope; |
||||||
|
scope = $rootScope.$new(); |
||||||
|
|
||||||
|
compile = function() { |
||||||
|
$compile(element)(scope); |
||||||
|
scope.$digest(); |
||||||
|
}; |
||||||
|
})); |
||||||
|
|
||||||
|
describe('element', function() { |
||||||
|
beforeEach(function() { |
||||||
|
scope.attachment = { |
||||||
|
props: { |
||||||
|
id: 1, |
||||||
|
fileName: 'hearmi.now', |
||||||
|
fileSize: '12340' |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
compile(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render element', function() { |
||||||
|
expect(element.prop('tagName')).to.equal('TD'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render link to attachment', function() { |
||||||
|
var link = element.find('a'); |
||||||
|
expect(link.text()).to.equal('hearmi.now'); |
||||||
|
expect(link.attr('href')).to.equal('/attachments/1/hearmi.now'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,79 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
describe('attachmentUserCell Directive', function() { |
||||||
|
var compile, element, rootScope, scope; |
||||||
|
|
||||||
|
beforeEach(angular.mock.module('openproject.workPackages.directives')); |
||||||
|
beforeEach(module('templates')); |
||||||
|
|
||||||
|
beforeEach(inject(function($rootScope, $compile) { |
||||||
|
var html; |
||||||
|
html = '<td attachment-user-cell attachment="attachment"></td>'; |
||||||
|
|
||||||
|
element = angular.element(html); |
||||||
|
rootScope = $rootScope; |
||||||
|
scope = $rootScope.$new(); |
||||||
|
|
||||||
|
compile = function() { |
||||||
|
$compile(element)(scope); |
||||||
|
scope.$digest(); |
||||||
|
}; |
||||||
|
})); |
||||||
|
|
||||||
|
describe('element', function() { |
||||||
|
var userName = 'Big Phil Scolari'; |
||||||
|
var userId = 5; |
||||||
|
|
||||||
|
beforeEach(inject(function($q) { |
||||||
|
scope.attachment = { |
||||||
|
links: { |
||||||
|
author: { |
||||||
|
fetch: function() { |
||||||
|
deferred = $q.defer(); |
||||||
|
deferred.resolve({ props: { id: userId, name: userName} } ); |
||||||
|
return deferred.promise; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
compile(); |
||||||
|
})); |
||||||
|
|
||||||
|
it('should render element', function() { |
||||||
|
expect(element.prop('tagName')).to.equal('TD'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render link to user', function() { |
||||||
|
var link = element.find('a'); |
||||||
|
expect(link.text()).to.equal(userName); |
||||||
|
expect(link.attr('href')).to.equal('/users/' + userId); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,67 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
describe('attachmentsTitle Directive', function() { |
||||||
|
var compile, element, rootScope, scope; |
||||||
|
|
||||||
|
beforeEach(angular.mock.module('openproject.workPackages.directives')); |
||||||
|
beforeEach(module('templates')); |
||||||
|
|
||||||
|
beforeEach(inject(function($rootScope, $compile) { |
||||||
|
var html; |
||||||
|
html = '<attachments-title attachments="attachments"></attachments-title>'; |
||||||
|
|
||||||
|
element = angular.element(html); |
||||||
|
rootScope = $rootScope; |
||||||
|
scope = $rootScope.$new(); |
||||||
|
|
||||||
|
compile = function() { |
||||||
|
$compile(element)(scope); |
||||||
|
scope.$digest(); |
||||||
|
}; |
||||||
|
})); |
||||||
|
|
||||||
|
describe('element', function() { |
||||||
|
beforeEach(function() { |
||||||
|
scope.attachments = [ |
||||||
|
{ filename: 'bomba' }, |
||||||
|
{ filename: 'clat' } |
||||||
|
]; |
||||||
|
|
||||||
|
compile(); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render element', function() { |
||||||
|
expect(element.prop('tagName')).to.equal('H3'); |
||||||
|
}); |
||||||
|
|
||||||
|
it('should render title', function() { |
||||||
|
expect(element.text()).to.equal('Attachments (2)'); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,55 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
/*jshint expr: true*/ |
||||||
|
|
||||||
|
describe('Latest items filter', function() { |
||||||
|
|
||||||
|
beforeEach(module('openproject.workPackages.filters')); |
||||||
|
|
||||||
|
describe('latestItems', function() { |
||||||
|
var items; |
||||||
|
|
||||||
|
beforeEach(function(){ |
||||||
|
items = [1,2,3,4,5,6,7,8,9]; |
||||||
|
}); |
||||||
|
|
||||||
|
it('should be defined', inject(function($filter) { |
||||||
|
expect($filter('latestItems')).not.to.equal(null); |
||||||
|
})); |
||||||
|
|
||||||
|
it('should return the first 3 items', inject(function($filter) { |
||||||
|
expect($filter('latestItems')(items, false, 3)).to.eql([9,8,7]); |
||||||
|
})); |
||||||
|
|
||||||
|
it('should return the last 3 items reversed', inject(function($filter) { |
||||||
|
expect($filter('latestItems')(items, true, 3)).to.eql([1,2,3]); |
||||||
|
})); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,82 @@ |
|||||||
|
//-- copyright
|
||||||
|
// OpenProject is a project management system.
|
||||||
|
// Copyright (C) 2012-2014 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.
|
||||||
|
//++
|
||||||
|
|
||||||
|
/*jshint expr: true*/ |
||||||
|
|
||||||
|
describe('ActivityService', function() { |
||||||
|
|
||||||
|
var $httpBackend, ActivityService; |
||||||
|
beforeEach(module('openproject.api', 'openproject.services', 'openproject.models')); |
||||||
|
|
||||||
|
beforeEach(inject(function(_$httpBackend_, _ActivityService_) { |
||||||
|
$httpBackend = _$httpBackend_; |
||||||
|
ActivityService = _ActivityService_; |
||||||
|
})); |
||||||
|
|
||||||
|
describe('createComment', function() { |
||||||
|
var setupFunction; |
||||||
|
var workPackageId = 5; |
||||||
|
var actvityId = 10; |
||||||
|
var activities = []; |
||||||
|
var descending = false; |
||||||
|
var comment = "Jack Bauer 24 hour power shower"; |
||||||
|
var apiResource; |
||||||
|
var apiFetchResource; |
||||||
|
|
||||||
|
beforeEach(inject(function($q) { |
||||||
|
apiResource = { |
||||||
|
fetch: function() { |
||||||
|
deferred = $q.defer(); |
||||||
|
deferred.resolve({ id: actvityId, comment: comment } ); |
||||||
|
return deferred.promise; |
||||||
|
} |
||||||
|
} |
||||||
|
})); |
||||||
|
|
||||||
|
beforeEach(inject(function(HALAPIResource) { |
||||||
|
setupFunction = sinon.stub(HALAPIResource, 'setup').returns(apiResource); |
||||||
|
})); |
||||||
|
|
||||||
|
beforeEach(inject(function() { |
||||||
|
apiFetchResource = ActivityService.createComment(workPackageId, activities, descending, comment); |
||||||
|
})); |
||||||
|
|
||||||
|
it('makes an api setup call', function() { |
||||||
|
expect(setupFunction).to.have.been.calledWith("/work_packages/" + workPackageId + "/activities"); |
||||||
|
}); |
||||||
|
|
||||||
|
it('returns an activity', function() { |
||||||
|
apiFetchResource.then(function(activity){ |
||||||
|
expect(activity.id).to.equal(activityId); |
||||||
|
expect(activity.comment).to.equal(comment); |
||||||
|
expect(activities.length).to.equal(1); |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
}); |
||||||
|
}); |
@ -0,0 +1,57 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
#-- copyright |
||||||
|
# OpenProject is a project management system. |
||||||
|
# Copyright (C) 2012-2014 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. |
||||||
|
#++ |
||||||
|
|
||||||
|
require 'roar/decorator' |
||||||
|
require 'roar/representer/json/hal' |
||||||
|
|
||||||
|
module API |
||||||
|
module Decorators |
||||||
|
class Collection < Roar::Decorator |
||||||
|
include Roar::Representer::JSON::HAL |
||||||
|
include Roar::Representer::Feature::Hypermedia |
||||||
|
include OpenProject::StaticRouting::UrlHelpers |
||||||
|
|
||||||
|
attr_reader :current_user, :as |
||||||
|
|
||||||
|
def initialize(models, current_user: nil, as: nil) |
||||||
|
@current_user = current_user |
||||||
|
@as = as.to_s.camelize(:lower) |
||||||
|
super(models) |
||||||
|
end |
||||||
|
|
||||||
|
as_strategy = API::Utilities::CamelCasingStrategy.new |
||||||
|
|
||||||
|
property :total, as: :_total, exec_context: :decorator |
||||||
|
|
||||||
|
def total |
||||||
|
represented.first.model.class.count |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,43 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
#-- copyright |
||||||
|
# OpenProject is a project management system. |
||||||
|
# Copyright (C) 2012-2014 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. |
||||||
|
#++ |
||||||
|
|
||||||
|
module API |
||||||
|
module V3 |
||||||
|
module Watchers |
||||||
|
class WatchersRepresenter < ::API::Decorators::Collection |
||||||
|
|
||||||
|
collection :watchers, as: -> (*) { as || :watchers }, exec_context: :decorator, embedded: true |
||||||
|
|
||||||
|
def watchers |
||||||
|
represented.map { |model| ::API::V3::Users::UserRepresenter.new(model) } |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,53 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
#-- copyright |
||||||
|
# OpenProject is a project management system. |
||||||
|
# Copyright (C) 2012-2014 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. |
||||||
|
#++ |
||||||
|
|
||||||
|
require 'reform' |
||||||
|
require 'reform/form/coercion' |
||||||
|
|
||||||
|
module API |
||||||
|
module V3 |
||||||
|
module WorkPackages |
||||||
|
class RelationModel < Reform::Form |
||||||
|
include Coercion |
||||||
|
|
||||||
|
# NOTE: to avoid a naming collision with DelayedJob, we define an |
||||||
|
# explicit method here rather than relying on the #property macro. |
||||||
|
# |
||||||
|
# @see Relation#delay |
||||||
|
def delay |
||||||
|
model.delay |
||||||
|
end |
||||||
|
|
||||||
|
def delay=(value) |
||||||
|
model.delay = value |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,79 @@ |
|||||||
|
#-- encoding: UTF-8 |
||||||
|
#-- copyright |
||||||
|
# OpenProject is a project management system. |
||||||
|
# Copyright (C) 2012-2014 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. |
||||||
|
#++ |
||||||
|
|
||||||
|
require 'roar/decorator' |
||||||
|
require 'roar/representer/json/hal' |
||||||
|
|
||||||
|
module API |
||||||
|
module V3 |
||||||
|
module WorkPackages |
||||||
|
class RelationRepresenter < Roar::Decorator |
||||||
|
include Roar::Representer::JSON::HAL |
||||||
|
include Roar::Representer::Feature::Hypermedia |
||||||
|
include OpenProject::StaticRouting::UrlHelpers |
||||||
|
|
||||||
|
self.as_strategy = API::Utilities::CamelCasingStrategy.new |
||||||
|
|
||||||
|
def initialize(model, options = {}, *expand) |
||||||
|
@current_user = options[:current_user] |
||||||
|
@work_package = options[:work_package] |
||||||
|
@expand = expand |
||||||
|
|
||||||
|
super(model) |
||||||
|
end |
||||||
|
|
||||||
|
property :_type, exec_context: :decorator |
||||||
|
|
||||||
|
link :self do |
||||||
|
{ href: "#{root_url}api/v3/relationships/#{represented.model.id}" } |
||||||
|
end |
||||||
|
|
||||||
|
link :relatedFrom do |
||||||
|
{ href: "#{root_url}api/v3/work_packages/#{represented.model.from_id}" } |
||||||
|
end |
||||||
|
|
||||||
|
link :relatedTo do |
||||||
|
{ href: "#{root_url}api/v3/work_packages/#{represented.model.to_id}" } |
||||||
|
end |
||||||
|
|
||||||
|
property :delay, getter: -> (*) { model.delay }, render_nil: true, if: -> (*) { model.relation_type == 'precedes' } |
||||||
|
|
||||||
|
def _type |
||||||
|
"Relation::#{relation_type}" |
||||||
|
end |
||||||
|
|
||||||
|
private |
||||||
|
|
||||||
|
def relation_type |
||||||
|
represented.model.relation_type_for(@work_package).camelize |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -0,0 +1,62 @@ |
|||||||
|
module API |
||||||
|
module V3 |
||||||
|
module WorkPackages |
||||||
|
class WatchersAPI < Grape::API |
||||||
|
|
||||||
|
get '/available_watchers' do |
||||||
|
available_watchers = @work_package.possible_watcher_users |
||||||
|
build_representer( |
||||||
|
available_watchers, |
||||||
|
::API::V3::Users::UserModel, |
||||||
|
::API::V3::Watchers::WatchersRepresenter, |
||||||
|
as: :available_watchers |
||||||
|
) |
||||||
|
end |
||||||
|
|
||||||
|
resources :watchers do |
||||||
|
|
||||||
|
params do |
||||||
|
requires :user_id, desc: 'The watcher\'s user id', type: Integer |
||||||
|
end |
||||||
|
post do |
||||||
|
if current_user.id == params[:user_id] |
||||||
|
authorize(:view_work_packages, context: @work_package.project) |
||||||
|
else |
||||||
|
authorize(:add_work_package_watchers, context: @work_package.project) |
||||||
|
end |
||||||
|
|
||||||
|
user = User.find params[:user_id] |
||||||
|
|
||||||
|
Services::CreateWatcher.new(@work_package, user).run( |
||||||
|
-> (result) { status(200) unless result[:created]}, |
||||||
|
-> (watcher) { raise ::API::Errors::Validation.new(watcher) } |
||||||
|
) |
||||||
|
|
||||||
|
build_representer(user, ::API::V3::Users::UserModel, ::API::V3::Users::UserRepresenter) |
||||||
|
end |
||||||
|
|
||||||
|
namespace ':user_id' do |
||||||
|
params do |
||||||
|
requires :user_id, desc: 'The watcher\'s user id', type: Integer |
||||||
|
end |
||||||
|
|
||||||
|
delete do |
||||||
|
if current_user.id == params[:user_id] |
||||||
|
authorize(:view_work_packages, context: @work_package.project) |
||||||
|
else |
||||||
|
authorize(:delete_work_package_watchers, context: @work_package.project) |
||||||
|
end |
||||||
|
|
||||||
|
user = User.find_by_id params[:user_id] |
||||||
|
|
||||||
|
Services::RemoveWatcher.new(@work_package, user).run |
||||||
|
|
||||||
|
status 204 |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
||||||
|
end |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue