Skip to content

Commit

Permalink
Merge pull request #16448 from opf/code-maintenance/move_project_quer…
Browse files Browse the repository at this point in the history
…y_namespaces

Turn menu factory project independent - move ProjectQuery services and contracts
  • Loading branch information
ulferts authored Sep 27, 2024
2 parents 200d70e + 69f6194 commit 29f8097
Show file tree
Hide file tree
Showing 27 changed files with 174 additions and 294 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

module Queries::Projects::ProjectQueries
module ProjectQueries
class BaseContract < ::ModelContract
attribute :name
attribute :selects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

module Queries::Projects::ProjectQueries
module ProjectQueries
class CreateContract < BaseContract; end
end
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

module Queries::Projects::ProjectQueries
module ProjectQueries
class DeleteContract < ::DeleteContract
delete_permission -> { user == model.user }
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
#++

module Queries::Projects::ProjectQueries
module ProjectQueries
class PublishContract < BaseContract
attribute :public
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

module Queries::Projects::ProjectQueries
module ProjectQueries
class UpdateContract < BaseContract; end
end
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

module Queries::Projects::ProjectQueries
module Queries
class LoadingContract < ::ModelContract
attribute :filters
attribute :orders
Expand Down
12 changes: 6 additions & 6 deletions app/controllers/projects/queries_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# ++

class Projects::QueriesController < ApplicationController
include Projects::QueryLoading
include Queries::Loading
include OpTurbo::ComponentStream
include OpTurbo::DialogStreamHelper

Expand Down Expand Up @@ -81,15 +81,15 @@ def rename
end

def create
call = Queries::Projects::ProjectQueries::CreateService
call = ProjectQueries::CreateService
.new(from: @query, user: current_user)
.call(permitted_query_params)

render_result(call, success_i18n_key: "lists.create.success", error_i18n_key: "lists.create.failure")
end

def update
call = Queries::Projects::ProjectQueries::UpdateService
call = ProjectQueries::UpdateService
.new(user: current_user, model: @query)
.call(permitted_query_params)

Expand All @@ -100,7 +100,7 @@ def toggle_public # rubocop:disable Metrics/AbcSize
to_be_public = ActiveRecord::Type::Boolean.new.cast(params["value"])
i18n_key = to_be_public ? "lists.publish" : "lists.unpublish"

call = Queries::Projects::ProjectQueries::PublishService
call = ProjectQueries::PublishService
.new(user: current_user, model: @query)
.call(public: to_be_public)

Expand All @@ -119,8 +119,8 @@ def toggle_public # rubocop:disable Metrics/AbcSize
end

def destroy
Queries::Projects::ProjectQueries::DeleteService.new(user: current_user, model: @query)
.call
ProjectQueries::DeleteService.new(user: current_user, model: @query)
.call

redirect_to projects_path
end
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ProjectsController < ApplicationController
include PaginationHelper
include QueriesHelper
include ProjectsHelper
include Projects::QueryLoading
include Queries::Loading
include OpTurbo::DialogStreamHelper

helper_method :has_managed_project_folders?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@
#
# See COPYRIGHT and LICENSE files for more details.
# ++
module Projects
module QueryLoading
module Queries
module Loading
private

def load_query(duplicate:)
::Queries::Projects::Factory.find(params[:query_id],
params: permitted_query_params,
user: current_user,
duplicate:)
::Queries::Factory.find(params[:query_id],
query_class:,
params: permitted_query_params,
user: current_user,
duplicate:)
end

def load_query_or_deny_access
Expand All @@ -59,5 +60,17 @@ def permitted_query_params

query_params.with_indifferent_access
end

def query_class
controller_name = self.class.name.demodulize

model_name = if controller_name == "QueriesController"
self.class.name.deconstantize
else
controller_name.chomp("Controller")
end

"#{model_name.singularize}Query".constantize
end
end
end
18 changes: 9 additions & 9 deletions app/menus/projects/menu.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def selected?(query_params) # rubocop:disable Metrics/AbcSize
when "projects"
case params[:query_id]
when nil
query_params[:query_id].to_s == Queries::Projects::Factory::DEFAULT_STATIC
query_params[:query_id].to_s == ProjectQueries::Static::DEFAULT
when /\A\d+\z/
query_params[:query_id].to_s == params[:query_id]
else
Expand All @@ -78,24 +78,24 @@ def query_path(query_params)

def main_static_filters
static_filters [
::Queries::Projects::Factory::STATIC_ACTIVE,
::Queries::Projects::Factory::STATIC_MY,
::Queries::Projects::Factory::STATIC_FAVORED,
current_user.admin? ? ::Queries::Projects::Factory::STATIC_ARCHIVED : nil
ProjectQueries::Static::ACTIVE,
ProjectQueries::Static::MY,
ProjectQueries::Static::FAVORED,
current_user.admin? ? ProjectQueries::Static::ARCHIVED : nil
].compact
end

def status_static_filters
static_filters [
::Queries::Projects::Factory::STATIC_ON_TRACK,
::Queries::Projects::Factory::STATIC_OFF_TRACK,
::Queries::Projects::Factory::STATIC_AT_RISK
ProjectQueries::Static::ON_TRACK,
ProjectQueries::Static::OFF_TRACK,
ProjectQueries::Static::AT_RISK
]
end

def static_filters(ids)
ids.map do |id|
menu_item(title: ::Queries::Projects::Factory.static_query(id).name, query_params: { query_id: id })
menu_item(title: ::ProjectQueries::Static.query(id).name, query_params: { query_id: id })
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,42 +26,39 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

class Queries::Projects::Factory
STATIC_ACTIVE = "active".freeze
STATIC_MY = "my".freeze
STATIC_FAVORED = "favored".freeze
STATIC_ARCHIVED = "archived".freeze
STATIC_ON_TRACK = "on_track".freeze
STATIC_OFF_TRACK = "off_track".freeze
STATIC_AT_RISK = "at_risk".freeze
class ProjectQueries::Static
ACTIVE = "active".freeze
MY = "my".freeze
FAVORED = "favored".freeze
ARCHIVED = "archived".freeze
ON_TRACK = "on_track".freeze
OFF_TRACK = "off_track".freeze
AT_RISK = "at_risk".freeze

DEFAULT_STATIC = STATIC_ACTIVE
DEFAULT = ACTIVE

class << self
def find(id, params:, user:, duplicate: false)
find_static_query_and_set_attributes(id, params, user, duplicate:) ||
find_persisted_query_and_set_attributes(id, params, user, duplicate:)
end

def static_query(id)
def query(id)
case id
when STATIC_ACTIVE, nil
when ACTIVE, nil
static_query_active
when STATIC_MY
when MY
static_query_my
when STATIC_FAVORED
when FAVORED
static_query_favored
when STATIC_ARCHIVED
when ARCHIVED
static_query_archived
when STATIC_ON_TRACK
when ON_TRACK
static_query_status_on_track
when STATIC_OFF_TRACK
when OFF_TRACK
static_query_status_off_track
when STATIC_AT_RISK
when AT_RISK
static_query_status_at_risk
end
end

private

def static_query_active
list_with(:"projects.lists.active") do |query|
query.where("active", "=", OpenProject::Database::DB_VALUE_TRUE)
Expand Down Expand Up @@ -117,49 +114,5 @@ def list_with(name)
query.clear_changes_information
end
end

def find_static_query_and_set_attributes(id, params, user, duplicate:)
query = static_query(id)

return unless query

query = duplicate_query(query) if duplicate || params.any?

if params.any?
set_query_attributes(query, params, user)
else
query
end
end

def find_persisted_query_and_set_attributes(id, params, user, duplicate:)
query = ProjectQuery.visible(user).find_by(id:)

return unless query

query.valid_subset!
query.clear_changes_information

query = duplicate_query(query) if duplicate

if params.any?
set_query_attributes(query, params, user)
else
query
end
end

def duplicate_query(query)
ProjectQuery.new(query.attributes.slice("filters", "orders", "selects"))
end

def set_query_attributes(query, params, user)
Queries::Projects::ProjectQueries::SetAttributesService
.new(user:,
model: query,
contract_class: Queries::Projects::ProjectQueries::LoadingContract)
.call(params)
.result
end
end
end
86 changes: 86 additions & 0 deletions app/models/queries/factory.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# -- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2010-2024 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::Factory
class << self
def find(id, query_class:, params:, user:, duplicate: false)
find_static_query_and_set_attributes(id, query_class, params, user, duplicate:) ||
find_persisted_query_and_set_attributes(id, query_class, params, user, duplicate:)
end

private

def find_static_query_and_set_attributes(id, query_class, params, user, duplicate:)
query = query_namespace(query_class)::Static.query(id)

return unless query

query = duplicate_query(query) if duplicate || params.any?

if params.any?
set_query_attributes(query, query_class, params, user)
else
query
end
end

def find_persisted_query_and_set_attributes(id, query_class, params, user, duplicate:)
query = query_class.visible(user).find_by(id:)

return unless query

query.valid_subset!
query.clear_changes_information

query = duplicate_query(query) if duplicate

if params.any?
set_query_attributes(query, query_class, params, user)
else
query
end
end

def duplicate_query(query)
query.class.new(query.attributes.slice("filters", "orders", "selects"))
end

def set_query_attributes(query, query_class, params, user)
query_namespace(query_class)::SetAttributesService
.new(user:,
model: query,
contract_class: Queries::LoadingContract)
.call(params)
.result
end

def query_namespace(query_class)
query_class.name.pluralize.constantize
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# See COPYRIGHT and LICENSE files for more details.
# ++

class Queries::Projects::ProjectQueries::CreateService < BaseServices::Create
class ProjectQueries::CreateService < BaseServices::Create
def initialize(from: nil, **)
@from = from
super(**)
Expand Down
Loading

0 comments on commit 29f8097

Please sign in to comment.