diff --git a/app/components/attribute_help_texts/show_component.rb b/app/components/attribute_help_texts/show_component.rb
index c9fc4840208..aef5ddd073f 100644
--- a/app/components/attribute_help_texts/show_component.rb
+++ b/app/components/attribute_help_texts/show_component.rb
@@ -39,7 +39,7 @@ class AttributeHelpTexts::ShowComponent < ApplicationComponent
private
- def title = @attribute_help_text.attribute_caption
+ def title = @attribute_help_text.attribute_field_name
def has_attachments? = @attribute_help_text.attachments.any?
diff --git a/app/components/attribute_help_texts/show_dialog_component.rb b/app/components/attribute_help_texts/show_dialog_component.rb
index 9d589947683..8e7216e41aa 100644
--- a/app/components/attribute_help_texts/show_dialog_component.rb
+++ b/app/components/attribute_help_texts/show_dialog_component.rb
@@ -42,7 +42,7 @@ class AttributeHelpTexts::ShowDialogComponent < ApplicationComponent
@dialog_id = dom_id(@attribute_help_text, :dialog)
@system_arguments = system_arguments
@system_arguments[:id] = dialog_id
- @system_arguments[:title] = @attribute_help_text.attribute_caption
+ @system_arguments[:title] = @attribute_help_text.attribute_field_name
end
private
diff --git a/app/components/open_project/common/attribute_label_component.rb b/app/components/open_project/common/attribute_label_component.rb
index bc019c7dd3b..089850d25b6 100644
--- a/app/components/open_project/common/attribute_label_component.rb
+++ b/app/components/open_project/common/attribute_label_component.rb
@@ -31,6 +31,8 @@
module OpenProject
module Common
class AttributeLabelComponent < ApplicationComponent
+ include AttributeHelpTextsHelper
+
def initialize(
attribute:,
model:,
@@ -50,10 +52,7 @@ module OpenProject
)
@required = required
-
- @help_text = ::AttributeHelpText.for(model)
- &.cached(current_user)
- &.[](AttributeHelpText.normalize_value_for(:attribute_name, attribute))
+ @help_text = help_text_for(model, attribute, current_user:)
end
end
end
diff --git a/app/components/projects/wizard/help_text_component.html.erb b/app/components/projects/wizard/help_text_component.html.erb
index cbf5d963858..383da86a168 100644
--- a/app/components/projects/wizard/help_text_component.html.erb
+++ b/app/components/projects/wizard/help_text_component.html.erb
@@ -2,7 +2,7 @@
<% if attribute_help_text.present? %>
<%= render Primer::Beta::Text.new(tag: :p) do %>
<%= render Primer::Beta::Octicon.new(icon: :info, color: :muted, mr: 2) %>
- <%= attribute_help_text.attribute_caption %>
+ <%= attribute_help_text.attribute_field_name %>
<% end %>
<%= render AttributeHelpTexts::ShowComponent.new(attribute_help_text:) %>
<% else %>
diff --git a/app/contracts/attribute_help_texts/base_contract.rb b/app/contracts/attribute_help_texts/base_contract.rb
index 33adeab3886..fb8f12e55dd 100644
--- a/app/contracts/attribute_help_texts/base_contract.rb
+++ b/app/contracts/attribute_help_texts/base_contract.rb
@@ -38,6 +38,7 @@ module AttributeHelpTexts
attribute :type
attribute :attribute_name
+ attribute :caption
attribute :help_text
validate :user_allowed
diff --git a/app/controllers/attribute_help_texts_controller.rb b/app/controllers/attribute_help_texts_controller.rb
index 946f80a370f..43e58e590fd 100644
--- a/app/controllers/attribute_help_texts_controller.rb
+++ b/app/controllers/attribute_help_texts_controller.rb
@@ -41,7 +41,10 @@ class AttributeHelpTextsController < ApplicationController
authorization_checked! :show_dialog
def index
- @texts_by_type = AttributeHelpText.all_by_scope
+ @texts_by_type = AttributeHelpText
+ .where(type: @attribute_scope)
+ .to_a
+ .sort_by(&:attribute_field_name)
end
def show_dialog
@@ -102,7 +105,9 @@ class AttributeHelpTextsController < ApplicationController
private
def permitted_params_with_attachments
- permitted_params.attribute_help_text.merge(attachment_params)
+ permitted_params
+ .attribute_help_text
+ .merge(attachment_params)
end
def attachment_params
@@ -120,13 +125,13 @@ class AttributeHelpTextsController < ApplicationController
end
def find_type_scope
- name = params.fetch(:name, "WorkPackage")
+ name = params[:tab] || params[:name] || "WorkPackage"
submodule = AttributeHelpText.available_types.find { |mod| mod == name }
if submodule.nil?
render_404
end
- @attribute_scope = AttributeHelpText.const_get(submodule)
+ @attribute_scope = AttributeHelpText.const_get(submodule).to_s
end
end
diff --git a/app/forms/attribute_help_texts/form.rb b/app/forms/attribute_help_texts/form.rb
new file mode 100644
index 00000000000..881a3887d1d
--- /dev/null
+++ b/app/forms/attribute_help_texts/form.rb
@@ -0,0 +1,97 @@
+# 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 AttributeHelpTexts
+ class Form < ApplicationForm
+ form do |attribute_form|
+ attribute_form.hidden(
+ name: :type,
+ value: model.type
+ )
+
+ attribute_form.select_list(
+ name: :attribute_name,
+ label: AttributeHelpText.human_attribute_name(:attribute_name),
+ required: true,
+ disabled: model.persisted?
+ ) do |list|
+ selectable_attributes.each do |label, value|
+ list.option(
+ label:,
+ value:
+ )
+ end
+ end
+
+ attribute_form.text_field(
+ name: :caption,
+ caption: I18n.t("attribute_help_texts.caption"),
+ label: AttributeHelpText.human_attribute_name(:caption),
+ required: false
+ )
+
+ attribute_form.rich_text_area(
+ name: :help_text,
+ label: AttributeHelpText.human_attribute_name(:help_text),
+ required: true,
+ rich_text_options: {
+ showAttachments: true,
+ primerized: true,
+ resource: ::API::V3::HelpTexts::HelpTextRepresenter.new(
+ model,
+ current_user: User.current,
+ embed_links: true
+ ),
+ footer: render(Primer::Beta::Text.new(color: :muted)) { I18n.t("attribute_help_texts.note_public") }
+ }
+ )
+
+ attribute_form.submit(
+ name: :submit,
+ label: I18n.t(:button_save),
+ scheme: :primary
+ )
+ end
+
+ private
+
+ def selectable_attributes
+ @selectable_attributes ||= begin
+ available = model.class.available_attributes
+ used = AttributeHelpText.used_attributes(model.type)
+
+ available
+ .reject { |key,| used.include? key }
+ .map { |key, label| [label, key] }
+ .sort_by { |label, _key| label.downcase }
+ end
+ end
+ end
+end
diff --git a/app/helpers/attribute_help_texts_helper.rb b/app/helpers/attribute_help_texts_helper.rb
index 6e1644839f6..14b7ed55962 100644
--- a/app/helpers/attribute_help_texts_helper.rb
+++ b/app/helpers/attribute_help_texts_helper.rb
@@ -29,13 +29,9 @@
#++
module AttributeHelpTextsHelper
- def selectable_attributes(instance)
- available = instance.class.available_attributes
- used = AttributeHelpText.used_attributes(instance.type)
-
- available
- .reject { |key,| used.include? key }
- .map { |key, label| [label, key] }
- .sort_by { |label, _key| label.downcase }
+ def help_text_for(model, attribute_name, current_user: User.current)
+ AttributeHelpText.for(model)
+ &.cached(current_user)
+ &.[](AttributeHelpText.normalize_value_for(:attribute_name, attribute_name))
end
end
diff --git a/app/models/attribute_help_text.rb b/app/models/attribute_help_text.rb
index 9cace1d75ba..1b4b26cb94a 100644
--- a/app/models/attribute_help_text.rb
+++ b/app/models/attribute_help_text.rb
@@ -33,7 +33,7 @@ class AttributeHelpText < ApplicationRecord
def self.cached(user)
RequestStore.fetch(name) do
- visible(user).select(:id, :attribute_name).index_by(&:attribute_name)
+ visible(user).select(:id, :attribute_name, :caption).index_by(&:attribute_name)
end
end
@@ -71,8 +71,8 @@ class AttributeHelpText < ApplicationRecord
validates :help_text, presence: true
validates :attribute_name, uniqueness: { scope: :type }
- def attribute_caption
- @attribute_caption ||= self.class.available_attributes[attribute_name]
+ def attribute_field_name
+ @attribute_field_name ||= self.class.available_attributes[attribute_name]
end
def attribute_scope
diff --git a/app/models/attribute_help_text/work_package.rb b/app/models/attribute_help_text/work_package.rb
index f337db10f56..a81a3aa68f1 100644
--- a/app/models/attribute_help_text/work_package.rb
+++ b/app/models/attribute_help_text/work_package.rb
@@ -30,17 +30,19 @@
class AttributeHelpText::WorkPackage < AttributeHelpText
def self.available_attributes
- attributes = ::Type.translated_work_package_form_attributes
+ RequestStore.fetch(:attribute_help_text_work_package_attributes) do
+ attributes = ::Type.translated_work_package_form_attributes
- # Start and finish dates are joined into a single field for non-milestones
- attributes.delete "start_date"
- attributes.delete "due_date"
+ # Start and finish dates are joined into a single field for non-milestones
+ attributes.delete "start_date"
+ attributes.delete "due_date"
- # Status and project are currently special attribute that we need to add
- attributes["status"] = WorkPackage.human_attribute_name "status"
- attributes["project"] = WorkPackage.human_attribute_name "project"
+ # Status and project are currently special attribute that we need to add
+ attributes["status"] = WorkPackage.human_attribute_name "status"
+ attributes["project"] = WorkPackage.human_attribute_name "project"
- attributes
+ attributes
+ end
end
validates :attribute_name, inclusion: { in: ->(*) { available_attributes.keys } }
@@ -51,9 +53,9 @@ class AttributeHelpText::WorkPackage < AttributeHelpText
def self.visible_condition(user)
visible_cf_names = WorkPackageCustomField
- .manageable_by_user(user)
- .pluck(:id)
- .map { |id| "custom_field_#{id}" }
+ .manageable_by_user(user)
+ .pluck(:id)
+ .map { |id| "custom_field_#{id}" }
::AttributeHelpText
.where(attribute_name: visible_cf_names)
diff --git a/app/models/permitted_params.rb b/app/models/permitted_params.rb
index 7632b57eb3b..1ae6ee4a213 100644
--- a/app/models/permitted_params.rb
+++ b/app/models/permitted_params.rb
@@ -460,6 +460,7 @@ class PermittedParams
type
attribute_name
help_text
+ caption
),
ldap_auth_source: %i(
name
diff --git a/app/views/attribute_help_texts/_form.html.erb b/app/views/attribute_help_texts/_form.html.erb
deleted file mode 100644
index 5c7723c64d5..00000000000
--- a/app/views/attribute_help_texts/_form.html.erb
+++ /dev/null
@@ -1,63 +0,0 @@
-<%#-- 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.
-
-++#%>
-<%= error_messages_for "attribute_help_text" %>
-
-
- <%= t(:note) %>:
- <%= t("attribute_help_texts.note_public") %>
-
| - <%= link_to h(attribute_help_text.attribute_caption), + <%= link_to h(attribute_help_text.attribute_field_name), edit_attribute_help_text_path(attribute_help_text) %> |
diff --git a/app/views/attribute_help_texts/edit.html.erb b/app/views/attribute_help_texts/edit.html.erb
index 36e9e65e78c..3bd692afedb 100644
--- a/app/views/attribute_help_texts/edit.html.erb
+++ b/app/views/attribute_help_texts/edit.html.erb
@@ -27,28 +27,30 @@ See COPYRIGHT and LICENSE files for more details.
++#%>
-<% html_title t(:label_administration), t(:"attribute_help_texts.edit", attribute_caption: @attribute_help_text.attribute_caption) %>
+<% html_title t(:label_administration), t(:"attribute_help_texts.edit", attribute_field_name: @attribute_help_text.attribute_field_name) %>
<%=
render(Primer::OpenProject::PageHeader.new) do |header|
- header.with_title { @attribute_help_text.attribute_caption }
+ header.with_title { @attribute_help_text.attribute_field_name }
header.with_breadcrumbs(
[{ href: admin_index_path, text: t(:label_administration) },
{ href: attribute_help_texts_path, text: t(:"attribute_help_texts.label_plural") },
{ href: attribute_help_texts_path(tab: @attribute_help_text.attribute_scope), text: @attribute_help_text.type_caption },
- @attribute_help_text.attribute_caption]
+ @attribute_help_text.attribute_field_name]
)
end
%>
-<%= labelled_tabular_form_for @attribute_help_text,
- as: "attribute_help_text",
- url: { action: :update },
- html: {
- id: "attribute_help_text_form",
- data: { turbo: false } # reload page to update previews
- } do |f| %>
- <%= render partial: "form", locals: { f: f, editing: true } %>
- <%= hidden_field_tag "attribute_scope", @attribute_help_text.attribute_scope %>
- <%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
-<% end %>
+
+<%=
+ primer_form_with(
+ model: @attribute_help_text,
+ scope: :attribute_help_text,
+ url: { action: :update },
+ method: :patch,
+ data: { turbo: false } # reload page to update previews
+ ) do |f|
+ render AttributeHelpTexts::Form.new(f)
+ end
+%>
+
diff --git a/app/views/attribute_help_texts/new.html.erb b/app/views/attribute_help_texts/new.html.erb
index 48df86e592d..0d7751e04a4 100644
--- a/app/views/attribute_help_texts/new.html.erb
+++ b/app/views/attribute_help_texts/new.html.erb
@@ -41,11 +41,15 @@ See COPYRIGHT and LICENSE files for more details.
end
%>
-<%= labelled_tabular_form_for @attribute_help_text,
- as: "attribute_help_text",
- url: { action: :create },
- html: { id: "attribute_help_text_form" } do |f| %>
- <%= render partial: "form", locals: { f: f } %>
- <%= f.hidden_field :type, value: @attribute_help_text.type %>
- <%= styled_button_tag t(:button_save), class: "-primary -with-icon icon-checkmark" %>
-<% end %>
+
+<%=
+ primer_form_with(
+ model: @attribute_help_text,
+ scope: :attribute_help_text,
+ url: { action: :create },
+ method: :post,
+ ) do |f|
+ render AttributeHelpTexts::Form.new(f)
+ end
+%>
+
diff --git a/config/locales/en.yml b/config/locales/en.yml
index e0a653cc29a..d3c0b5f27d3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -205,12 +205,13 @@ en:
error_cannot_act_self: "Cannot perform actions on your own uploaded files."
attribute_help_texts:
- note_public: "Any text and images you add to this field is publicly visible to all logged in users!"
+ caption: "This short version will be displayed as caption of the attribute."
+ note_public: "Any text and images you add to this field is publicly visible to all logged in users."
text_overview: "In this view, you can create custom help texts for attributes view. When defined, these texts can be shown by clicking the help icon next to its belonging attribute."
label_plural: "Attribute help texts"
show_preview: "Preview text"
add_new: "Add help text"
- edit: "Edit help text for %{attribute_caption}"
+ edit: "Edit help text for %{attribute_field_name}"
background_jobs:
status:
@@ -1206,6 +1207,7 @@ en:
attribute_help_text:
attribute_name: "Attribute"
help_text: "Help text"
+ caption: "Caption"
auth_provider:
scim_clients: "SCIM clients"
calculated_value_error:
diff --git a/db/migrate/20251121073442_add_caption_to_attribute_help_texts.rb b/db/migrate/20251121073442_add_caption_to_attribute_help_texts.rb
new file mode 100644
index 00000000000..c634103963e
--- /dev/null
+++ b/db/migrate/20251121073442_add_caption_to_attribute_help_texts.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddCaptionToAttributeHelpTexts < ActiveRecord::Migration[8.0]
+ def change
+ add_column :attribute_help_texts, :caption, :text
+ end
+end
diff --git a/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.component.ts b/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.component.ts
index 92d857787de..a8778c8df71 100644
--- a/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.component.ts
+++ b/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.component.ts
@@ -86,6 +86,8 @@ export class CkeditorAugmentedTextareaComponent extends UntilDestroyedMixin impl
@Input() public showAttachments = true;
+ @Input() public primerized = false;
+
@Input() public storageKey?:string;
// Output save requests (ctrl+enter and cmd+enter)
diff --git a/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.html b/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.html
index 732c16c850f..cd007c5b787 100644
--- a/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.html
+++ b/frontend/src/app/shared/components/editor/components/ckeditor-augmented-textarea/ckeditor-augmented-textarea.html
@@ -1,25 +1,35 @@
|