diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d7dc524f4..442ce5ae3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - Fixes to CILogon / `openid_connect` Tests [#922](https://github.com/portagenetwork/roadmap/pull/922) + - Fix Paginating, Sorting, and Searching Issues Within "Research Outputs" Tab [#938](https://github.com/portagenetwork/roadmap/pull/938) + ## [4.1.1+portage-4.2.2] - 2024-09-18 ### Changed diff --git a/app/controllers/paginable/research_outputs_controller.rb b/app/controllers/paginable/research_outputs_controller.rb new file mode 100644 index 0000000000..9eb5d7f338 --- /dev/null +++ b/app/controllers/paginable/research_outputs_controller.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Paginable + # Controller for paginating/sorting/searching the research_outputs table + class ResearchOutputsController < ApplicationController + include Paginable + + after_action :verify_authorized + + # GET /paginable/plans/:plan_id/research_outputs + def index + @plan = Plan.find_by(id: params[:plan_id]) + # Same assignment as app/controllers/research_outputs_controller.rb + research_outputs = ResearchOutput.includes(:repositories).where(plan_id: @plan.id) + # Same authorize handling as app/controllers/research_outputs_controller.rb + # `|| ResearchOutput.new(plan_id: @plan.id)` prevents Pundit::NotDefinedError when a direct + # GET /paginable/plans/:id/research_outputs request is made on a plan with 0 research_outputs + authorize(research_outputs.first || ResearchOutput.new(plan_id: @plan.id)) + paginable_renderise( + partial: 'index', + scope: research_outputs, + query_params: { sort_field: 'research_outputs.title' }, + format: :json + ) + end + end +end diff --git a/app/models/research_output.rb b/app/models/research_output.rb index 4165f0b7ea..f1bef1f16b 100644 --- a/app/models/research_output.rb +++ b/app/models/research_output.rb @@ -70,6 +70,15 @@ class ResearchOutput < ApplicationRecord # Ensure presence of the :output_type_description if the user selected 'other' validates_presence_of :output_type_description, if: -> { other? }, message: PRESENCE_MESSAGE + # ========== + # = Scopes = + # ========== + + scope :search, lambda { |term| + search_pattern = "%#{term}%" + where('lower(title) LIKE lower(?)', search_pattern) + } + # ==================== # = Instance methods = # ====================