diff --git a/app/components/concerns/op_turbo/streamable.rb b/app/components/concerns/op_turbo/streamable.rb index 5d8030f6789..858eb81e8c8 100644 --- a/app/components/concerns/op_turbo/streamable.rb +++ b/app/components/concerns/op_turbo/streamable.rb @@ -36,7 +36,7 @@ module OpTurbo class_methods do def wrapper_key - name.underscore.gsub("/", "-").gsub("_", "-") + name.underscore.tr("/", "-").tr("_", "-") end end @@ -61,7 +61,7 @@ module OpTurbo "Wrap your component in a `component_wrapper` block in order to use turbo-stream methods" end - OpTurbo::StreamWrapperComponent.new( + OpTurbo::StreamComponent.new( action:, target: wrapper_key, template: @@ -79,7 +79,7 @@ module OpTurbo "Wrap your component in a `component_wrapper` block in order to use turbo-stream methods" end - OpTurbo::StreamWrapperComponent.new( + OpTurbo::StreamComponent.new( action:, target: insert_target_modified? ? insert_target_modifier_id : wrapper_key, template: diff --git a/app/components/op_turbo/frame_component.html.erb b/app/components/op_turbo/frame_component.html.erb new file mode 100644 index 00000000000..64adfb7f55d --- /dev/null +++ b/app/components/op_turbo/frame_component.html.erb @@ -0,0 +1,31 @@ +<%#-- copyright +OpenProject is an open source project management software. +Copyright (C) 2012-2023 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. + +++#%> + + <%= content %> + diff --git a/app/components/op_turbo/frame_component.rb b/app/components/op_turbo/frame_component.rb new file mode 100644 index 00000000000..6f3876a84ad --- /dev/null +++ b/app/components/op_turbo/frame_component.rb @@ -0,0 +1,35 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2023 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 OpTurbo + class FrameComponent < ApplicationComponent + def turbo_frame_id + ActionView::RecordIdentifier.dom_id(model, options[:context]) + end + end +end diff --git a/app/components/op_turbo/stream_wrapper_component.html.erb b/app/components/op_turbo/stream_component.html.erb similarity index 100% rename from app/components/op_turbo/stream_wrapper_component.html.erb rename to app/components/op_turbo/stream_component.html.erb diff --git a/app/components/op_turbo/stream_wrapper_component.rb b/app/components/op_turbo/stream_component.rb similarity index 96% rename from app/components/op_turbo/stream_wrapper_component.rb rename to app/components/op_turbo/stream_component.rb index 6ad310353fc..2a1149d9465 100644 --- a/app/components/op_turbo/stream_wrapper_component.rb +++ b/app/components/op_turbo/stream_component.rb @@ -27,7 +27,7 @@ #++ module OpTurbo - class StreamWrapperComponent < ApplicationComponent + class StreamComponent < ApplicationComponent def initialize(template:, action:, target:) super() diff --git a/lookbook/previews/op_turbo/frame_component_preview.rb b/lookbook/previews/op_turbo/frame_component_preview.rb new file mode 100644 index 00000000000..cbacdabbe6f --- /dev/null +++ b/lookbook/previews/op_turbo/frame_component_preview.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module OpTurbo + # @logical_path OpenProject/OpTurbo + class FrameComponentPreview < Lookbook::Preview + # Renders a turbo-frame tag with a unique id + # @param context text + def default(context: nil) + model = FactoryBot.build_stubbed(:user) + render_with_template(locals: { model:, context: }) + end + end +end diff --git a/lookbook/previews/op_turbo/frame_component_preview/default.html.erb b/lookbook/previews/op_turbo/frame_component_preview/default.html.erb new file mode 100644 index 00000000000..36894e579fd --- /dev/null +++ b/lookbook/previews/op_turbo/frame_component_preview/default.html.erb @@ -0,0 +1,8 @@ +

+ Default
+ <%= render(OpTurbo::FrameComponent.new(model)) %> +

+

+ Context
+ <%= render(OpTurbo::FrameComponent.new(model, context: context)) %> +

diff --git a/lookbook/previews/op_turbo/stream_component_preview.rb b/lookbook/previews/op_turbo/stream_component_preview.rb new file mode 100644 index 00000000000..d58958d4465 --- /dev/null +++ b/lookbook/previews/op_turbo/stream_component_preview.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module OpTurbo + # @logical_path OpenProject/OpTurbo + class StreamComponentPreview < Lookbook::Preview + # Renders a turbo-stream tag with given action and target + # @param _action select { choices: [append, prepend, replace, update, remove, before, after] } + # @param target text + def default(_action: 'append', target: 'model_id') + template = template_example_from_action(_action, target) + render_with_template(locals: { template:, action: _action, target: }) + end + + private + + def template_example_from_action(action, target) + <<~HTML +
+ This div will #{action} to the element with the DOM ID "#{target}". +
+ HTML + end + end +end diff --git a/lookbook/previews/op_turbo/stream_component_preview/default.html.erb b/lookbook/previews/op_turbo/stream_component_preview/default.html.erb new file mode 100644 index 00000000000..ae50d59624e --- /dev/null +++ b/lookbook/previews/op_turbo/stream_component_preview/default.html.erb @@ -0,0 +1,4 @@ +

+ Default
+ <%= render(OpTurbo::StreamComponent.new(template:, action:, target:)) %> +

diff --git a/spec/components/op_turbo/frame_component_spec.rb b/spec/components/op_turbo/frame_component_spec.rb new file mode 100644 index 00000000000..9a056f96810 --- /dev/null +++ b/spec/components/op_turbo/frame_component_spec.rb @@ -0,0 +1,51 @@ +#-- copyright +# OpenProject is an open source project management software. +# Copyright (C) 2012-2023 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. +#++ +# +require 'spec_helper' + +RSpec.describe OpTurbo::FrameComponent, type: :component do + describe '#turbo_frame_id' do + context 'with `context:` option' do + it 'returns the turbo frame id' do + storage = build_stubbed(:nextcloud_storage, id: 1) + component = described_class.new(storage, context: :general_info) + + expect(component.turbo_frame_id).to eq('general_info_storages_nextcloud_storage_1') + end + end + + context 'without `context:` option' do + it 'returns just the model dom id' do + storage = build_stubbed(:nextcloud_storage, id: 1) + component = described_class.new(storage) + + expect(component.turbo_frame_id).to eq('storages_nextcloud_storage_1') + end + end + end +end