From 591f1cbb1db2b8215da65345d2e80104efe4108b Mon Sep 17 00:00:00 2001 From: Dennis Baurichter Date: Sat, 28 Sep 2019 22:12:17 +0200 Subject: [PATCH] Allow adjusting projects per_page for groups Respect the per_page parameter when listing the projects of a group. Add a dropdown to facilitate this. --- .../javascripts/groups/groups_filterable_list.js | 14 ++++++++++++++ app/assets/stylesheets/pages/groups.scss | 4 ++++ app/views/groups/show.html.haml | 12 +++++++++++- app/views/shared/groups/_per_page.html.haml | 12 ++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 app/views/shared/groups/_per_page.html.haml diff --git a/app/assets/javascripts/groups/groups_filterable_list.js b/app/assets/javascripts/groups/groups_filterable_list.js index 693519729acfaf..a35b070030f402 100644 --- a/app/assets/javascripts/groups/groups_filterable_list.js +++ b/app/assets/javascripts/groups/groups_filterable_list.js @@ -20,6 +20,7 @@ export default class GroupFilterableList extends FilterableList { this.pagePath = pagePath; this.filterInputField = filterInputField; this.$dropdown = $(dropdownSel); + this.$perPage = $('.js-group-filter-per-page-wrap'); this.action = action; } @@ -40,6 +41,7 @@ export default class GroupFilterableList extends FilterableList { this.onFilterOptionClickWrapper = this.onOptionClick.bind(this); this.$dropdown.on('click', 'a', this.onFilterOptionClickWrapper); + this.$perPage.on('click', 'a', this.onFilterOptionClickWrapper); } onFilterInput() { @@ -84,6 +86,7 @@ export default class GroupFilterableList extends FilterableList { const isOptionFilterByArchivedProjects = currentTargetClassList.contains( 'js-filter-archived-projects', ); + const isOptionFilterByPerPage = currentTargetClassList.contains('js-filter-per-page'); // Get option query param, also preserve currently applied query param const sortParam = getParameterByName( @@ -94,6 +97,10 @@ export default class GroupFilterableList extends FilterableList { 'archived', isOptionFilterByArchivedProjects ? e.currentTarget.href : window.location.href, ); + const perPageParam = getParameterByName( + 'per_page', + isOptionFilterByPerPage ? e.currentTarget.href : window.location.href, + ); if (sortParam) { queryData.sort = sortParam; @@ -103,6 +110,10 @@ export default class GroupFilterableList extends FilterableList { queryData.archived = archivedParam; } + if (perPageParam) { + queryData.per_page = perPageParam; + } + this.filterResults(queryData); // Active selected option @@ -113,6 +124,9 @@ export default class GroupFilterableList extends FilterableList { this.$dropdown .find('.dropdown-menu li.js-filter-archived-projects a') .removeClass('is-active'); + } else if (isOptionFilterByPerPage) { + this.$perPage.find('.dropdown-label').text(parseInt(e.currentTarget.text)); + this.$perPage.find('.dropdown-menu li.js-filter-per-page a').removeClass('is-active'); } $(e.target).addClass('is-active'); diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index 1502cf1844039e..8d0e51e8a2b018 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -44,6 +44,10 @@ margin-top: 0; } + .js-group-filter-per-page-wrap button { + width: 70px; + } + @include media-breakpoint-down(sm) { .dropdown, .dropdown .dropdown-toggle, diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml index 0e6c16f0f06a40..f499213f7c85cf 100644 --- a/app/views/groups/show.html.haml +++ b/app/views/groups/show.html.haml @@ -1,13 +1,21 @@ - breadcrumb_title _("Details") - @content_class = "limit-container-width" unless fluid_layout +- unless @per_page.present? + - if params[:per_page] + - @per_page = params[:per_page].to_i + - else + - @per_page = 20 +- if @per_page <= 0 + - @per_page = 20 + = content_for :meta_tags do = auto_discovery_link_tag(:atom, group_url(@group, rss_url_options), title: "#{@group.name} activity") %div{ class: [("limit-container-width" unless fluid_layout)] } = render 'groups/home_panel' - .groups-listing{ data: { endpoints: { default: group_children_path(@group, format: :json), shared: group_shared_projects_path(@group, format: :json) } } } + .groups-listing{ data: { endpoints: { default: group_children_path(@group, format: :json, per_page: @per_page), shared: group_shared_projects_path(@group, format: :json, per_page: @per_page) } } } .top-area.group-nav-container.justify-content-between .scrolling-tabs-container.inner-page-scroll-tabs .fade-left= icon('angle-left') @@ -29,6 +37,8 @@ = render "shared/groups/dropdown", options_hash: subgroups_sort_options_hash + = render "shared/groups/per_page", default_per_page: @per_page + .tab-content #subgroups_and_projects.tab-pane = render "subgroups_and_projects", group: @group diff --git a/app/views/shared/groups/_per_page.html.haml b/app/views/shared/groups/_per_page.html.haml new file mode 100644 index 00000000000000..8d8bb06128bcfc --- /dev/null +++ b/app/views/shared/groups/_per_page.html.haml @@ -0,0 +1,12 @@ +.dropdown.inline.js-group-filter-per-page-wrap.append-right-10 + %button.dropdown-menu-toggle{ type: 'button', 'data-toggle' => 'dropdown' } + %span.dropdown-label + = default_per_page.to_s + = icon('chevron-down') + %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-selectable + %li.dropdown-header + = _("Projects shown") + - [10, 20, 30, 50, 70, 100].each do |per_page| + %li.js-filter-per-page + = link_to filter_groups_path(per_page: per_page), class: ("is-active" if default_per_page == per_page) do + = per_page.to_s + _(" per page") -- GitLab