kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
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.
200 lines
5.7 KiB
200 lines
5.7 KiB
#-- encoding: UTF-8
|
|
#-- copyright
|
|
# OpenProject is a project management system.
|
|
# Copyright (C) 2012-2017 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-2017 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 'will_paginate'
|
|
|
|
module PaginationHelper
|
|
def pagination_links_full(paginator, options = {})
|
|
return unless paginator.total_entries > 0
|
|
|
|
pagination_options = default_options.merge(options)
|
|
|
|
content_tag(:div, class: 'pagination') do
|
|
content = content_tag(:nav, pagination_entries(paginator, pagination_options),
|
|
class: 'pagination--pages')
|
|
|
|
if pagination_options[:per_page_links]
|
|
content << content_tag(:div, pagination_settings(paginator, pagination_options[:params]),
|
|
class: 'pagination--options')
|
|
end
|
|
|
|
content.html_safe
|
|
end
|
|
end
|
|
|
|
##
|
|
# Builds the pagination nav with pages and range
|
|
def pagination_entries(paginator, options)
|
|
page_first = paginator.offset + 1
|
|
page_last = paginator.offset + paginator.length
|
|
total = paginator.total_entries
|
|
|
|
content_tag(:ul, class: 'pagination--items') do
|
|
# will_paginate will return nil early when no pages available
|
|
content = will_paginate(paginator, options) || ''
|
|
|
|
range = "(#{page_first} - #{page_last}/#{total})"
|
|
content << content_tag(:li, range, class: 'pagination--range', title: range)
|
|
|
|
content.html_safe
|
|
end
|
|
end
|
|
|
|
##
|
|
# Builds pagination options (range).
|
|
def pagination_settings(paginator, options)
|
|
links = per_page_links(paginator, options)
|
|
|
|
if links.size > 1
|
|
label = I18n.t(:label_per_page)
|
|
content_tag(:ul, class: 'pagination--items') do
|
|
content_tag(:li, label + ':', class: 'pagination--label', title: label) + links
|
|
end
|
|
end
|
|
end
|
|
|
|
##
|
|
# Constructs the 'n items per page' entries
|
|
# determined from available options in the settings.
|
|
def per_page_links(paginator, options)
|
|
Setting.per_page_options_array.inject('') { |html, n|
|
|
if n == paginator.per_page
|
|
html + content_tag(:li, n, class: 'pagination--item -current')
|
|
else
|
|
link = link_to_content_update(n, options.merge(page: 1, per_page: n))
|
|
html + content_tag(:li, link.html_safe, class: 'pagination--item')
|
|
end
|
|
}.html_safe
|
|
end
|
|
|
|
# Returns page option used for pagination
|
|
# based on:
|
|
# * offset
|
|
# * limit
|
|
# * page
|
|
# parameters.
|
|
# Preferes page over the other two and
|
|
# calculates page in it's absence based on limit and offset.
|
|
# Return 1 if all else fails.
|
|
|
|
def page_param(options = params)
|
|
page = if options[:page]
|
|
|
|
options[:page].to_i
|
|
|
|
elsif options[:offset] && options[:limit]
|
|
|
|
begin
|
|
# + 1 as page is not 0 but 1 based
|
|
options[:offset].to_i / per_page_param(options) + 1
|
|
rescue ZeroDivisionError
|
|
1
|
|
end
|
|
|
|
else
|
|
|
|
1
|
|
|
|
end
|
|
|
|
page > 0 ?
|
|
page :
|
|
1
|
|
end
|
|
|
|
# Returns per_page option used for pagination
|
|
# based on:
|
|
# * per_page session value
|
|
# * per_page options value
|
|
# * limit options value
|
|
# in that order
|
|
# Return smallest possible setting if all else fails.
|
|
|
|
def per_page_param(options = params)
|
|
per_page_candidates = [options[:per_page].to_i, session[:per_page].to_i, options[:limit].to_i]
|
|
|
|
unless (union = per_page_candidates & Setting.per_page_options_array).empty?
|
|
session[:per_page] = union.first
|
|
|
|
union.first
|
|
else
|
|
Setting.per_page_options_array.sort.first
|
|
end
|
|
end
|
|
|
|
class LinkRenderer < ::WillPaginate::ActionView::LinkRenderer
|
|
def to_html
|
|
pagination.inject('') { |html, item|
|
|
html + (item.is_a?(Fixnum) ? page_number(item) : send(item))
|
|
}.html_safe
|
|
end
|
|
|
|
protected
|
|
|
|
def page_number(page)
|
|
if page == current_page
|
|
tag(:li, page, class: 'pagination--item -current')
|
|
else
|
|
tag(:li, link(page, page), class: 'pagination--item')
|
|
end
|
|
end
|
|
|
|
def gap
|
|
tag(:li, '…', class: 'pagination--space')
|
|
end
|
|
|
|
def previous_page
|
|
num = @collection.current_page > 1 && @collection.current_page - 1
|
|
previous_or_next_page(num, I18n.t(:label_previous), '-prev')
|
|
end
|
|
|
|
def next_page
|
|
num = @collection.current_page < total_pages && @collection.current_page + 1
|
|
previous_or_next_page(num, I18n.t(:label_next), '-next')
|
|
end
|
|
|
|
def previous_or_next_page(page, text, classname)
|
|
if page
|
|
tag(:li, link(text, page), class: 'pagination--item ' + classname)
|
|
else
|
|
''
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def default_options
|
|
{
|
|
renderer: LinkRenderer,
|
|
per_page_links: true,
|
|
params: {}
|
|
}
|
|
end
|
|
end
|
|
|