Add query and quick filter for cost types index page

This commit is contained in:
Mir Bhatia
2026-05-19 14:08:57 +02:00
committed by Oliver Günther
parent 66a80ff463
commit 40a2f5fbf2
5 changed files with 172 additions and 13 deletions
@@ -49,9 +49,9 @@ module Admin
"unit_plural" => "#{CostType.table_name}.unit_plural" }
sort_update sort_columns
@status = params[:status] == "locked" ? "locked" : "active"
@cost_types = (@status == "locked" ? CostType.where.not(deleted_at: nil) : CostType.active)
.order(sort_clause)
@query = load_query
@status = @query.find_active_filter(:status).values.first
@cost_types = @query.results.reorder(sort_clause)
render action: "index", layout: !request.xhr?
end
@@ -144,6 +144,12 @@ module Admin
private
def load_query
query = ParamsToQueryService.new(CostType, current_user).call(params)
query.where("status", "=", ["active"]) unless query.find_active_filter(:status)
query
end
def find_cost_type
@cost_type = CostType.find(params[:id])
end
@@ -0,0 +1,35 @@
# frozen_string_literal: true
#-- 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.
#++
module Queries::CostTypes
::Queries::Register.register(CostTypeQuery) do
filter Filters::StatusFilter
end
end
@@ -0,0 +1,42 @@
# frozen_string_literal: true
#-- 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.
#++
class Queries::CostTypes::CostTypeQuery
include ::Queries::BaseQuery
include ::Queries::UnpersistedQuery
def self.model
CostType
end
def default_scope
CostType.all
end
end
@@ -0,0 +1,75 @@
# frozen_string_literal: true
#-- 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.
#++
class Queries::CostTypes::Filters::StatusFilter < Queries::Filters::Base
ACTIVE_VALUE = "active"
LOCKED_VALUE = "locked"
self.model = CostType
validate :validate_single_value
def allowed_values
[
[I18n.t(:label_active), ACTIVE_VALUE],
[I18n.t("members.menu.locked"), LOCKED_VALUE]
]
end
def where
if values.first == LOCKED_VALUE
"cost_types.deleted_at IS NOT NULL"
else
"cost_types.deleted_at IS NULL"
end
end
def human_name
I18n.t(:label_status)
end
def type
:list
end
def self.key
:status
end
def available_operators
[::Queries::Operators::Equals]
end
private
def validate_single_value
errors.add(:values, :invalid) if values.length != 1
end
end
@@ -52,16 +52,17 @@ See COPYRIGHT and LICENSE files for more details.
)
) do |subheader|
subheader.with_quick_filter do
render(Primer::Alpha::SegmentedControl.new("aria-label": t(:label_filter_plural), full_width: false)) do |control| %>
<% control.with_item(tag: :a,
href: admin_cost_types_path(status: "active"),
label: t(:label_active),
selected: @status == "active") %>
<% control.with_item(tag: :a,
href: admin_cost_types_path(status: "locked"),
label: t("members.menu.locked"),
selected: @status == "locked") %>
<% end
render(
OpPrimer::QuickFilter::SegmentedComponent.new(
name: t(:label_filter_plural),
query: @query,
filter_key: :status,
path_args: %i[admin cost_types]
)
) do |component|
component.with_item(label: t(:label_active), value: "active")
component.with_item(label: t("members.menu.locked"), value: "locked")
end
end
# TODO - Remove with https://community.openproject.org/wp/75158