diff --git a/app/components/op_primer/quick_filter/select_panel_component.html.erb b/app/components/op_primer/quick_filter/select_panel_component.html.erb index 0c561708b86..adf6b3b3b07 100644 --- a/app/components/op_primer/quick_filter/select_panel_component.html.erb +++ b/app/components/op_primer/quick_filter/select_panel_component.html.erb @@ -34,7 +34,8 @@ See COPYRIGHT and LICENSE files for more details. <%= render( Primer::Alpha::SelectPanel.new( select_variant: :multiple, - fetch_strategy: :local, + fetch_strategy: fetch_strategy, + src: panel_src, title: @name, dynamic_label: true, dynamic_label_prefix: current_values.any? ? @name : nil @@ -44,12 +45,14 @@ See COPYRIGHT and LICENSE files for more details. button.with_trailing_visual_icon(icon: :"triangle-down") current_label end %> - <% items.each do |item| %> - <% panel.with_item( - label: item.label, - active: current_values.include?(item.value.to_s), - content_arguments: { data: { value: item.value.to_s } } - ) %> + <% unless @src.present? %> + <% items.each do |item| %> + <% panel.with_item( + label: item.label, + active: current_values.include?(item.value.to_s), + content_arguments: { data: { value: item.value.to_s } } + ) %> + <% end %> <% end %> <% panel.with_footer(show_divider: true) do %> <%= render(Primer::Beta::Button.new(scheme: :primary, data: { action: "click->quick-filter--select-panel#apply" })) do %> diff --git a/app/components/op_primer/quick_filter/select_panel_component.rb b/app/components/op_primer/quick_filter/select_panel_component.rb index 93b4e24223d..ad02b2a9fa8 100644 --- a/app/components/op_primer/quick_filter/select_panel_component.rb +++ b/app/components/op_primer/quick_filter/select_panel_component.rb @@ -35,7 +35,7 @@ module OpPrimer renders_many :items, OpPrimer::QuickFilter::Item - def initialize(name:, query:, filter_key:, path_args:, operator: "=") + def initialize(name:, query:, filter_key:, path_args:, operator: "=", src: nil) super @name = name @@ -43,10 +43,11 @@ module OpPrimer @filter_key = filter_key @path_args = path_args @operator = operator + @src = src end def render? - items.any? + @src.present? || items.any? end private @@ -66,6 +67,21 @@ module OpPrimer I18n.t(:label_x_items_selected, count: selected.size) end + def panel_src + return nil if @src.blank? + return @src if current_values.empty? + + uri = URI.parse(@src) + params = Rack::Utils.parse_nested_query(uri.query.to_s) + params["selected"] = current_values.join(",") + uri.query = params.to_query + uri.to_s + end + + def fetch_strategy + @src.present? ? :eventually_local : :local + end + def base_url polymorphic_path(@path_args, base_url_params) end diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb index c9f81e6e7b7..d252629d9d0 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.html.erb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.html.erb @@ -20,10 +20,11 @@ name: I18n.t(:label_project), query: @query, filter_key: :project_id, - path_args: [@project, :meetings] + path_args: [@project, :meetings], + src: project_items_meetings_path ) ) do |component| - project_items.each do |project| + selected_projects.each do |project| component.with_item(label: project.name, value: project.id) end end diff --git a/modules/meeting/app/components/meetings/index_sub_header_component.rb b/modules/meeting/app/components/meetings/index_sub_header_component.rb index a0084251a90..99f51891c96 100644 --- a/modules/meeting/app/components/meetings/index_sub_header_component.rb +++ b/modules/meeting/app/components/meetings/index_sub_header_component.rb @@ -67,8 +67,11 @@ module Meetings params[:filters].present? end - def project_items - Project.visible.order(:name) + def selected_projects + selected_ids = @query.find_active_filter(:project_id)&.values&.map(&:to_s) || [] + return [] if selected_ids.empty? + + Project.visible.where(id: selected_ids) end end end diff --git a/modules/meeting/app/controllers/meetings_controller.rb b/modules/meeting/app/controllers/meetings_controller.rb index fbebcf7051b..ad0af222e8f 100644 --- a/modules/meeting/app/controllers/meetings_controller.rb +++ b/modules/meeting/app/controllers/meetings_controller.rb @@ -34,7 +34,7 @@ class MeetingsController < ApplicationController before_action :determine_date_range, only: %i[history] before_action :determine_author, only: %i[history] before_action :build_meeting, only: %i[new new_dialog fetch_timezone] - before_action :find_meeting, except: %i[index new create new_dialog fetch_timezone fetch_templates] + before_action :find_meeting, except: %i[index new create new_dialog fetch_timezone fetch_templates project_items] before_action :redirect_to_project, only: %i[show] before_action :set_activity, only: %i[history] before_action :find_copy_from_meeting, only: %i[create] @@ -383,6 +383,19 @@ class MeetingsController < ApplicationController respond_with_turbo_streams end + def project_items + projects = Project.visible.order(:name) + selected_ids = params[:selected]&.split(",") || [] + + respond_to do |format| + format.html_fragment do + render "meetings/project_items", + locals: { projects:, selected_ids: }, + layout: false + end + end + end + def generate_pdf_dialog respond_with_dialog Meetings::Exports::ModalDialogComponent.new( meeting: @meeting, diff --git a/modules/meeting/app/views/meetings/project_items.html.erb b/modules/meeting/app/views/meetings/project_items.html.erb new file mode 100644 index 00000000000..fcee3df2f36 --- /dev/null +++ b/modules/meeting/app/views/meetings/project_items.html.erb @@ -0,0 +1,38 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) the OpenProject GmbH + +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 COPYRIGHT and LICENSE files for more details. + +++#%> + +<%= render(Primer::Alpha::SelectPanel::ItemList.new(select_variant: :multiple)) do |list| %> + <% projects.each do |project| %> + <% list.with_item( + label: project.name, + active: selected_ids.include?(project.id.to_s), + content_arguments: { data: { value: project.id.to_s } } + ) %> + <% end %> +<% end %> diff --git a/modules/meeting/config/routes.rb b/modules/meeting/config/routes.rb index acb0be0aeea..526fe05f80e 100644 --- a/modules/meeting/config/routes.rb +++ b/modules/meeting/config/routes.rb @@ -47,6 +47,7 @@ Rails.application.routes.draw do get "menu" => "meetings/menus#show" get :fetch_timezone get :fetch_templates + get :project_items get "ical/:token", controller: "meetings/ical", action: :index, as: "ical_feed" diff --git a/modules/meeting/lib/open_project/meeting/engine.rb b/modules/meeting/lib/open_project/meeting/engine.rb index c7894770d41..b6ce5cf588a 100644 --- a/modules/meeting/lib/open_project/meeting/engine.rb +++ b/modules/meeting/lib/open_project/meeting/engine.rb @@ -44,7 +44,7 @@ module OpenProject::Meeting permission :view_meetings, { meetings: %i[index show check_for_updates download_ics - presentation generate_pdf_dialog history], + presentation generate_pdf_dialog history project_items], "meetings/filters": %i[show], "meetings/menus": %i[show], work_package_meetings_tab: %i[index count],