OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openproject/frontend/app/layout/menu-item-factory.js

116 lines
3.6 KiB

//-- copyright
// OpenProject is a project management system.
// Copyright (C) 2012-2015 the OpenProject Foundation (OPF)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License version 3.
//
// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
// Copyright (C) 2006-2013 Jean-Philippe Lang
// Copyright (C) 2010-2013 the ChiliProject Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// See doc/COPYRIGHT.rdoc for more details.
//++
/**
* menuItemFactory
*
* Provides a function to generate menu items for the project menu on the fly.
* The container element of the menu items to be inserted is a mandatory option. Moreover a
* link function can be set, which will be applied to the generated menu item.
*
* An example for setting up the factory is given in angular/layout/query-menu-items.js
*/
module.exports = function($rootScope, $compile, $http, $templateCache, $animate) {
return function(options) {
if (!options.container) {
throw new Error('Container must be specified menu item to have exacly one of either `template` or `templateUrl`');
}
var templateUrl = '/templates/layout/menu_item.html',
type = options.type,
linkFn = options.linkFn,
container, scope;
function getContainer() {
return angular.element(options.container);
}
function generateMenuItem(title, path, objectId) {
container = getContainer();
if(!container) return;
var menuItem;
scope = $rootScope.$new(true);
scope.type = type;
scope.title = title;
scope.path = path;
scope.objectId = objectId;
return $http.get(templateUrl, {
cache: $templateCache
}).then(function (response) {
menuItem = angular.element(response.data);
if (linkFn) linkFn(scope, menuItem.children('a'), {});
$compile(menuItem)(scope);
var previousItem = previousMenuItem(title);
return $animate.enter(menuItem, container, previousItem);
});
}
/**
* previousMenuItem
*
* Returns the menu item within the factories's container that has a title
* alphabetically before the provided title. The considered menu items have
* the type (css class) this factory is responsible for.
*
* Params
* * title: The string used for comparing.
*/
function previousMenuItem(title) {
var allItems = getContainer().find('li'),
previousElement = angular.element(allItems[allItems.length - 1]),
i = allItems.length - 2;
for (i; i >= 0; i--) {
if ((title > previousElement.find('a').attr('title')) ||
(previousElement.find('.' + type).length === 0))
{
return previousElement;
}
else {
previousElement = angular.element(allItems[i]);
}
}
}
return {
generateMenuItem: generateMenuItem,
link: linkFn
};
};
};