mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
Create a update handler registry to be able to update different models from the inplaceEditField component
This commit is contained in:
@@ -13,12 +13,19 @@
|
||||
<!-- end-->
|
||||
<!-- end--> %>
|
||||
|
||||
<div id="<%= target_id %>">
|
||||
<%= primer_form_with(model:, url: polymorphic_path(model), method: :patch, data: { turbo_stream: true }) do |form|
|
||||
<%= component_wrapper(tag: :div) do %>
|
||||
<%= primer_form_with(
|
||||
model:,
|
||||
url: inplace_edit_field_update_path(model: model.class.name, id: model.id, attribute:),
|
||||
method: :patch,
|
||||
data: { turbo_stream: true }
|
||||
) do |form|
|
||||
render_field_component = ->(f) { render field_component(f) } # The render_inline_form method looses context and thus does not know about the `field_component` method
|
||||
system_arguments = @system_arguments
|
||||
|
||||
render_inline_form(form) do |f|
|
||||
f.hidden name: "system_arguments_json", value: system_arguments.to_json
|
||||
render_field_component.call(f)
|
||||
end
|
||||
end %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
module OpenProject
|
||||
module Common
|
||||
class InplaceEditFieldComponent < ViewComponent::Base
|
||||
include OpTurbo::Streamable
|
||||
|
||||
attr_reader :model, :attribute
|
||||
|
||||
def initialize(model:, attribute:, **system_arguments)
|
||||
@@ -41,13 +43,9 @@ module OpenProject
|
||||
end
|
||||
|
||||
def field_component(form)
|
||||
klass = OpenProject::InplaceFieldRegistry.fetch(attribute)
|
||||
klass = OpenProject::InplaceEdit::FieldRegistry.fetch(attribute)
|
||||
klass.new(form:, attribute:, model:, **@system_arguments)
|
||||
end
|
||||
|
||||
def target_id
|
||||
"#{model.model_name.singular}_#{model.id}_#{attribute}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# 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 InplaceEditFieldsController < ApplicationController
|
||||
include OpTurbo::ComponentStream
|
||||
|
||||
before_action :find_model
|
||||
before_action :set_attribute
|
||||
no_authorization_required! :update
|
||||
|
||||
def update
|
||||
handler = OpenProject::InplaceEdit::UpdateRegistry.fetch(@model)
|
||||
|
||||
success = handler.call(
|
||||
model: @model,
|
||||
attribute: @attribute,
|
||||
params: permitted_params,
|
||||
user: current_user
|
||||
)
|
||||
|
||||
if success
|
||||
render_success_flash_message_via_turbo_stream(
|
||||
message: I18n.t(:notice_successful_update)
|
||||
)
|
||||
end
|
||||
|
||||
replace_via_turbo_stream(
|
||||
component:,
|
||||
status: success ? :ok : :unprocessable_entity
|
||||
)
|
||||
|
||||
respond_with_turbo_streams
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_model
|
||||
@model =
|
||||
params[:model]
|
||||
.constantize
|
||||
.find(params[:id])
|
||||
rescue NameError, ActiveRecord::RecordNotFound
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def set_attribute
|
||||
@attribute = params[:attribute].to_sym
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
params
|
||||
.expect(@model.model_name.param_key => [@attribute])
|
||||
end
|
||||
|
||||
def component
|
||||
OpenProject::Common::InplaceEditFieldComponent.new(
|
||||
model: @model,
|
||||
attribute: @attribute,
|
||||
**system_arguments.to_h.symbolize_keys
|
||||
)
|
||||
end
|
||||
|
||||
def system_arguments
|
||||
arguments = params.to_unsafe_h
|
||||
.values
|
||||
.filter_map { |v| v["system_arguments_json"] }
|
||||
.first
|
||||
|
||||
JSON.parse(arguments)
|
||||
end
|
||||
end
|
||||
@@ -29,6 +29,12 @@
|
||||
#++
|
||||
|
||||
Rails.application.config.to_prepare do
|
||||
require_relative "../../lib/open_project/inplace_edit/registry"
|
||||
OpenProject::InplaceFieldRegistry.register(:description, OpenProject::Common::InplaceEditFields::TextInputComponent)
|
||||
# Register the edit fields per attribute
|
||||
require_relative "../../lib/open_project/inplace_edit/field_registry"
|
||||
OpenProject::InplaceEdit::FieldRegistry.register(:description, OpenProject::Common::InplaceEditFields::TextInputComponent)
|
||||
|
||||
# Register the update handler per model
|
||||
require_relative "../../lib/open_project/inplace_edit/handlers/default_update"
|
||||
require_relative "../../lib/open_project/inplace_edit/handlers/project_update"
|
||||
OpenProject::InplaceEdit::UpdateRegistry.register(Project, OpenProject::InplaceEdit::Handlers::ProjectUpdate)
|
||||
end
|
||||
|
||||
@@ -1056,6 +1056,11 @@ Rails.application.routes.draw do
|
||||
delete "Groups/:id", to: "groups#destroy"
|
||||
end
|
||||
|
||||
scope "inplace_edit_fields/:model/:id/:attribute", as: "inplace_edit_field" do
|
||||
post :update, controller: "inplace_edit_fields", action: :update
|
||||
patch :update, controller: "inplace_edit_fields", action: :update
|
||||
end
|
||||
|
||||
if OpenProject::Configuration.lookbook_enabled?
|
||||
mount Primer::ViewComponents::Engine, at: "/"
|
||||
mount Lookbook::Engine, at: "/lookbook"
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# 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 OpenProject
|
||||
module InplaceEdit
|
||||
class FieldRegistry
|
||||
@registry = {}
|
||||
|
||||
class << self
|
||||
def register(attribute_name, field_component)
|
||||
@registry[attribute_name.to_s] = field_component
|
||||
end
|
||||
|
||||
def fetch(attribute_name)
|
||||
@registry.fetch(attribute_name.to_s) { Common::InplaceEditFields::TextInputComponent }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
# 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 OpenProject
|
||||
module InplaceEdit
|
||||
module Handlers
|
||||
class DefaultUpdate
|
||||
def self.call(model:, attribute:, params:, user:)
|
||||
model.update!(params.slice(attribute))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
+9
-9
@@ -29,16 +29,16 @@
|
||||
#++
|
||||
|
||||
module OpenProject
|
||||
class InplaceFieldRegistry
|
||||
@registry = {}
|
||||
module InplaceEdit
|
||||
module Handlers
|
||||
class ProjectUpdate
|
||||
def self.call(model:, attribute:, params:, user:)
|
||||
call = ::Projects::UpdateService
|
||||
.new(model:, user:)
|
||||
.call(params)
|
||||
|
||||
class << self
|
||||
def register(attribute_name, field_component)
|
||||
@registry[attribute_name.to_s] = field_component
|
||||
end
|
||||
|
||||
def fetch(attribute_name)
|
||||
@registry.fetch(attribute_name.to_s) { Common::InplaceEditFields::TextInputComponent }
|
||||
call.success?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,47 @@
|
||||
# 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 OpenProject
|
||||
module InplaceEdit
|
||||
class UpdateRegistry
|
||||
@registry = {}
|
||||
|
||||
class << self
|
||||
def register(model_class, handler)
|
||||
@registry[model_class.name] = handler
|
||||
end
|
||||
|
||||
def fetch(model)
|
||||
@registry.fetch(model.class.name, OpenProject::InplaceEdit::Handlers::DefaultUpdate)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user