Skip to content

Commit 6525a14

Browse files
committed
Create a update handler registry to be able to update different models from the inplaceEditField component
1 parent ebdf9de commit 6525a14

File tree

9 files changed

+254
-19
lines changed

9 files changed

+254
-19
lines changed

app/components/open_project/common/inplace_edit_field_component.html.erb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@
1313
<!-- end-->
1414
<!-- end--> %>
1515

16-
<div id="<%= target_id %>">
17-
<%= primer_form_with(model:, url: polymorphic_path(model), method: :patch, data: { turbo_stream: true }) do |form|
16+
<%= component_wrapper(tag: :div) do %>
17+
<%= primer_form_with(model:,
18+
url: inplace_edit_field_update_path(model: model.class.name, id: model.id, attribute:),
19+
method: :patch,
20+
data: { turbo_stream: true }) do |form|
1821
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
1922

2023
render_inline_form(form) do |f|
2124
render_field_component.call(f)
2225
end
2326
end %>
24-
</div>
27+
<% end %>

app/components/open_project/common/inplace_edit_field_component.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
module OpenProject
3232
module Common
3333
class InplaceEditFieldComponent < ViewComponent::Base
34+
include OpTurbo::Streamable
35+
3436
attr_reader :model, :attribute
3537

3638
def initialize(model:, attribute:, **system_arguments)
@@ -41,13 +43,9 @@ def initialize(model:, attribute:, **system_arguments)
4143
end
4244

4345
def field_component(form)
44-
klass = OpenProject::InplaceFieldRegistry.fetch(attribute)
46+
klass = OpenProject::InplaceEdit::FieldRegistry.fetch(attribute)
4547
klass.new(form:, attribute:, model:, **@system_arguments)
4648
end
47-
48-
def target_id
49-
"#{model.model_name.singular}_#{model.id}_#{attribute}"
50-
end
5149
end
5250
end
5351
end
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
class InplaceEditFieldsController < ApplicationController
32+
include OpTurbo::ComponentStream
33+
34+
before_action :find_model
35+
before_action :set_attribute
36+
no_authorization_required! :update
37+
38+
def update
39+
handler = OpenProject::InplaceEdit::UpdateRegistry.fetch(@model)
40+
41+
success = handler.call(
42+
model: @model,
43+
attribute: @attribute,
44+
params: permitted_params,
45+
user: current_user
46+
)
47+
48+
if success
49+
render_success_flash_message_via_turbo_stream(
50+
message: I18n.t(:notice_successful_update)
51+
)
52+
end
53+
54+
replace_via_turbo_stream(
55+
component:,
56+
status: success ? :ok : :unprocessable_entity
57+
)
58+
59+
respond_with_turbo_streams
60+
end
61+
62+
private
63+
64+
def find_model
65+
@model =
66+
params[:model]
67+
.constantize
68+
.find(params[:id])
69+
rescue NameError, ActiveRecord::RecordNotFound
70+
head :not_found
71+
end
72+
73+
def set_attribute
74+
@attribute = params[:attribute].to_sym
75+
end
76+
77+
def permitted_params
78+
params
79+
.expect(@model.model_name.param_key => [@attribute])
80+
end
81+
82+
def component
83+
OpenProject::Common::InplaceEditFieldComponent.new(
84+
model: @model,
85+
attribute: @attribute
86+
)
87+
end
88+
end

config/initializers/inplace_edit_fields.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@
2929
#++
3030

3131
Rails.application.config.to_prepare do
32-
require_relative "../../lib/open_project/inplace_edit/registry"
33-
OpenProject::InplaceFieldRegistry.register(:description, OpenProject::Common::InplaceEditFields::TextInputComponent)
32+
# Register the edit fields per attribute
33+
require_relative "../../lib/open_project/inplace_edit/field_registry"
34+
OpenProject::InplaceEdit::FieldRegistry.register(:description, OpenProject::Common::InplaceEditFields::TextInputComponent)
35+
36+
# Register the update handler per model
37+
require_relative "../../lib/open_project/inplace_edit/handlers/default_update"
38+
require_relative "../../lib/open_project/inplace_edit/handlers/project_update"
39+
OpenProject::InplaceEdit::UpdateRegistry.register(Project, OpenProject::InplaceEdit::Handlers::ProjectUpdate)
3440
end

config/routes.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,11 @@
10531053
delete "Groups/:id", to: "groups#destroy"
10541054
end
10551055

1056+
scope "inplace_edit_fields/:model/:id/:attribute", as: "inplace_edit_field" do
1057+
post :update, controller: "inplace_edit_fields", action: :update
1058+
patch :update, controller: "inplace_edit_fields", action: :update
1059+
end
1060+
10561061
if OpenProject::Configuration.lookbook_enabled?
10571062
mount Primer::ViewComponents::Engine, at: "/"
10581063
mount Lookbook::Engine, at: "/lookbook"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
module OpenProject
32+
module InplaceEdit
33+
class FieldRegistry
34+
@registry = {}
35+
36+
class << self
37+
def register(attribute_name, field_component)
38+
@registry[attribute_name.to_s] = field_component
39+
end
40+
41+
def fetch(attribute_name)
42+
@registry.fetch(attribute_name.to_s) { Common::InplaceEditFields::TextInputComponent }
43+
end
44+
end
45+
end
46+
end
47+
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
module OpenProject
32+
module InplaceEdit
33+
module Handlers
34+
class DefaultUpdate
35+
def self.call(model:, attribute:, params:, user:)
36+
model.update!(params.slice(attribute))
37+
end
38+
end
39+
end
40+
end
41+
end

lib/open_project/inplace_edit/registry.rb renamed to lib/open_project/inplace_edit/handlers/project_update.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,16 @@
2929
#++
3030

3131
module OpenProject
32-
class InplaceFieldRegistry
33-
@registry = {}
32+
module InplaceEdit
33+
module Handlers
34+
class ProjectUpdate
35+
def self.call(model:, attribute:, params:, user:)
36+
call = ::Projects::UpdateService
37+
.new(model:, user:)
38+
.call(params)
3439

35-
class << self
36-
def register(attribute_name, field_component)
37-
@registry[attribute_name.to_s] = field_component
38-
end
39-
40-
def fetch(attribute_name)
41-
@registry.fetch(attribute_name.to_s) { Common::InplaceEditFields::TextInputComponent }
40+
call.success?
41+
end
4242
end
4343
end
4444
end
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
module OpenProject
32+
module InplaceEdit
33+
class UpdateRegistry
34+
@registry = {}
35+
36+
class << self
37+
def register(model_class, handler)
38+
@registry[model_class.name] = handler
39+
end
40+
41+
def fetch(model)
42+
@registry.fetch(model.class.name, OpenProject::InplaceEdit::Handlers::DefaultUpdate)
43+
end
44+
end
45+
end
46+
end
47+
end

0 commit comments

Comments
 (0)