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