From bb48a3b36d9a0569cf7e429157419f32e31cf578 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20G=C3=BCnther?= Date: Thu, 8 Aug 2019 14:38:46 +0200 Subject: [PATCH] Allow WYSIWYG in project/other long text formattible fields The project text custom field was not using the WYSIWYG editor, but was outputting plain text. https://community.openproject.com/wp/30433 --- .../custom_value/formattable_strategy.rb | 42 +++++++++++++++++++ app/views/customizable/_form.html.erb | 2 +- config/initializers/custom_field_format.rb | 3 +- lib/custom_field_form_builder.rb | 3 +- lib/open_project/form_tag_helper.rb | 2 +- spec/features/projects/copy_spec.rb | 8 ++-- .../projects/projects_custom_fields_spec.rb | 29 ++++++++++++- spec/lib/custom_field_form_builder_spec.rb | 3 +- 8 files changed, 82 insertions(+), 10 deletions(-) create mode 100644 app/models/custom_value/formattable_strategy.rb diff --git a/app/models/custom_value/formattable_strategy.rb b/app/models/custom_value/formattable_strategy.rb new file mode 100644 index 0000000000..268ab6432c --- /dev/null +++ b/app/models/custom_value/formattable_strategy.rb @@ -0,0 +1,42 @@ +#-- encoding: UTF-8 +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +# +# 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-2017 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 docs/COPYRIGHT.rdoc for more details. +#++ + +class + CustomValue::FormattableStrategy < CustomValue::FormatStrategy + + def formatted_value + OpenProject::TextFormatting::Renderer.format_text value + end + + def typed_value + value.to_s + end + + def validate_type_of_value; end +end diff --git a/app/views/customizable/_form.html.erb b/app/views/customizable/_form.html.erb index bffe793b98..2fba4bd656 100644 --- a/app/views/customizable/_form.html.erb +++ b/app/views/customizable/_form.html.erb @@ -32,7 +32,7 @@ See docs/COPYRIGHT.rdoc for more details. <% form.object.custom_field_values.each do |value| %> <%= form.fields_for_custom_fields :custom_field_values, value do |value_form| %> <% required = value.custom_field.is_required? %> -
+
<%# display all fields OR only display required fields OR only display optional fields #%> <% if all_fields || (only_required && required) || (!only_required && !required) %> <%= value_form.custom_field(container_class: '-wide', required: required) %> diff --git a/config/initializers/custom_field_format.rb b/config/initializers/custom_field_format.rb index 1e54ce8a9f..1f5c9b6e06 100644 --- a/config/initializers/custom_field_format.rb +++ b/config/initializers/custom_field_format.rb @@ -34,7 +34,8 @@ OpenProject::CustomFieldFormat.map do |fields| order: 1) fields.register OpenProject::CustomFieldFormat.new('text', label: :label_text, - order: 2) + order: 2, + formatter: 'CustomValue::FormattableStrategy') fields.register OpenProject::CustomFieldFormat.new('int', label: :label_integer, order: 3, diff --git a/lib/custom_field_form_builder.rb b/lib/custom_field_form_builder.rb index 6326393b21..00e6186fca 100644 --- a/lib/custom_field_form_builder.rb +++ b/lib/custom_field_form_builder.rb @@ -31,6 +31,7 @@ require 'action_view/helpers/form_helper' class CustomFieldFormBuilder < TabularFormBuilder include ActionView::Context + # Return custom field html tag corresponding to its format def custom_field(options = {}) input = custom_field_input(options) @@ -67,7 +68,7 @@ class CustomFieldFormBuilder < TabularFormBuilder input_options[:class] = (input_options[:class] || '') << ' -augmented-datepicker' text_field(field, input_options) when 'text' - text_area(field, input_options.merge(rows: 3)) + text_area(field, input_options.merge(rows: 3, with_text_formatting: true)) when 'bool' formatter = field_format.formatter.new(object) check_box(field, input_options.merge(checked: formatter.checked?)) diff --git a/lib/open_project/form_tag_helper.rb b/lib/open_project/form_tag_helper.rb index e9a84fc362..7ecb2d74ad 100644 --- a/lib/open_project/form_tag_helper.rb +++ b/lib/open_project/form_tag_helper.rb @@ -85,7 +85,7 @@ module OpenProject ## # Create a wrapper for the text formatting toolbar for this field - def text_formatting_wrapper(target_id, options) + def text_formatting_wrapper(target_id, options = {}) return ''.html_safe unless target_id.present? helper = ::OpenProject::TextFormatting::Formats.rich_helper.new(self) diff --git a/spec/features/projects/copy_spec.rb b/spec/features/projects/copy_spec.rb index 77468ec40c..b6ebcac400 100644 --- a/spec/features/projects/copy_spec.rb +++ b/spec/features/projects/copy_spec.rb @@ -136,8 +136,8 @@ describe 'Projects copy', check 'only_wiki_page_attachments' # the value of the custom field should be preselected - expect(page) - .to have_field(project_custom_field.name, with: 'some text cf') + editor = ::Components::WysiwygEditor.new ".form--field.custom_field_#{project_custom_field.id}" + editor.expect_value 'some text cf' click_button 'Copy' @@ -160,8 +160,8 @@ describe 'Projects copy', selected: parent_project.name) # copies over the value of the custom field - expect(page) - .to have_field(project_custom_field.name, with: 'some text cf') + editor = ::Components::WysiwygEditor.new ".form--field.custom_field_#{project_custom_field.id}" + editor.expect_value 'some text cf' # has wp custom fields of original project active copied_settings_page.visit_tab!('custom_fields') diff --git a/spec/features/projects/projects_custom_fields_spec.rb b/spec/features/projects/projects_custom_fields_spec.rb index 82884e54fb..d76a2bafde 100644 --- a/spec/features/projects/projects_custom_fields_spec.rb +++ b/spec/features/projects/projects_custom_fields_spec.rb @@ -54,12 +54,39 @@ describe 'Projects custom fields', type: :feature do end end + describe 'with long text CF' do + let!(:custom_field) do + FactoryBot.create(:text_project_custom_field) + end + let(:editor) { ::Components::WysiwygEditor.new ".form--field.custom_field_#{custom_field.id}" } + + scenario 'allows settings the project boolean CF (regression #26313)', js: true do + visit settings_project_path(id: project.id) + + # expect CF and description ckeditor + expect(page).to have_selector('.op-ckeditor--wrapper', count: 2) + + # single hash autocomplete + editor.insert_link 'http://example.org/link with spaces' + + # Save wiki page + click_on 'Save' + + expect(page).to have_selector('.flash.notice') + + project.reload + cv = project.custom_values.find_by(custom_field_id: custom_field.id).value + + expect(cv).to include '[http://example.org/link with spaces](http://example.org/link%20with%20spaces)' + expect(page).to have_selector('a[href="http://example.org/link%20with%20spaces"]') + end + end + describe 'with boolean CF' do let!(:custom_field) do FactoryBot.create(:bool_project_custom_field) end - scenario 'allows settings the project boolean CF (regression #26313)', js: true do visit settings_project_path(id: project.id) expect(page).to have_no_checked_field identifier diff --git a/spec/lib/custom_field_form_builder_spec.rb b/spec/lib/custom_field_form_builder_spec.rb index 8d723d265c..4e226a272e 100644 --- a/spec/lib/custom_field_form_builder_spec.rb +++ b/spec/lib/custom_field_form_builder_spec.rb @@ -103,7 +103,8 @@ describe CustomFieldFormBuilder do }).at_path('textarea') end