diff --git a/app/components/messages/show_page_header_component.html.erb b/app/components/messages/show_page_header_component.html.erb new file mode 100644 index 000000000000..7b7ce34f5323 --- /dev/null +++ b/app/components/messages/show_page_header_component.html.erb @@ -0,0 +1,60 @@ +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @topic.subject } + header.with_breadcrumbs(breadcrumb_items) + + watcher_button_args = watcher_button_arguments(@topic, User.current) + header.with_action_button(**watcher_button_args) do |button| + button.with_leading_visual_icon(icon: watcher_button_args[:mobile_icon]) + watcher_button_args[:mobile_label] + end + + if !@topic.locked? && authorize_for('messages', 'reply') + header.with_action_button(tag: :a, + scheme: :default, + mobile_icon: :quote, + mobile_label: t(:button_quote), + size: :medium, + href: url_for({ action: 'quote', id: @topic }), + aria: { label: I18n.t(:button_delete) }, + data: { 'action': 'forum-messages#quote', test_selector: "message-quote-button" }, + title: t(:button_quote)) do |button| + button.with_leading_visual_icon(icon: :quote) + t(:button_quote) + end + end + + if @message.editable_by?(User.current) + header.with_action_button(tag: :a, + scheme: :default, + mobile_icon: :pencil, + mobile_label: t(:button_edit), + size: :medium, + href: edit_topic_path(@topic), + aria: { label: t(:button_edit) }, + data: { test_selector: "message-edit-button" }, + title: t(:button_edit)) do |button| + button.with_leading_visual_icon(icon: :pencil) + t(:button_edit) + end + end + + if @message.destroyable_by?(User.current) + header.with_action_button(tag: :a, + scheme: :danger, + mobile_icon: :trash, + mobile_label: t(:button_delete), + size: :medium, + href: topic_path(@topic), + aria: { label: I18n.t(:button_delete) }, + data: { + confirm: I18n.t(:text_are_you_sure), + method: :delete + }, + title: I18n.t(:button_delete)) do |button| + button.with_leading_visual_icon(icon: :trash) + t(:button_delete) + end + end + end +%> diff --git a/app/components/messages/show_page_header_component.rb b/app/components/messages/show_page_header_component.rb new file mode 100644 index 000000000000..23a606034599 --- /dev/null +++ b/app/components/messages/show_page_header_component.rb @@ -0,0 +1,54 @@ +# 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 Messages + class ShowPageHeaderComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + include ApplicationHelper + include WatchersHelper + + def initialize(topic:, message:, forum:, project:) + super + @topic = topic + @message = message + @forum = forum + @project = project + end + + def breadcrumb_items + [ + { href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project), text: t(:label_forum_plural) }, + { href: project_forum_path(@project, @forum), text: @forum.name }, + @topic.subject + ] + end + end +end diff --git a/app/components/projects/settings/index_page_header_component.html.erb b/app/components/projects/settings/index_page_header_component.html.erb new file mode 100644 index 000000000000..06c1f59002e5 --- /dev/null +++ b/app/components/projects/settings/index_page_header_component.html.erb @@ -0,0 +1,100 @@ +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_information_plural) } + header.with_breadcrumbs( [ + { href: project_overview_path(@project.id), text: @project.name }, + { href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") }, + t(:label_information_plural) + ]) + + if User.current.allowed_in_project?(:add_subprojects, @project) + header.with_action_button(scheme: :primary, + mobile_icon: :plus, + mobile_label: t(:label_subproject_new), + aria: { label: t(:label_subproject_new) }, + title: t(:label_subproject_new), + tag: :a, + href: new_project_path(parent_id: @project.id)) do |button| + button.with_leading_visual_icon(icon: :plus) + t(:label_subproject) + end + end + + header.with_action_button(tag: :a, + mobile_icon: :pencil, + mobile_label: t('projects.settings.change_identifier'), + size: :medium, + href: project_identifier_path(@project), + aria: { label: t('projects.settings.change_identifier') }, + title: t('projects.settings.change_identifier')) do |button| + button.with_leading_visual_icon(icon: :pencil) + t('projects.settings.change_identifier') + end + + header.with_action_menu( + menu_arguments: { + anchor_align: :end + }, + button_arguments: { + icon: "op-kebab-vertical", + "aria-label": t(:label_more), + test_selector: "project-settings-more-menu" + } + ) do |menu| + if @project.copy_allowed? + menu.with_item( + label:t(:button_copy), + href: copy_project_path(@project), + content_arguments: { + data: { turbo: false }, + test_selector: "project-settings--copy" + }, + accesskey: helpers.accesskey(:copy), + ) do |item| + item.with_leading_visual_icon(icon: :copy) + end + end + + if User.current.allowed_in_project?(:archive_project, @project) + menu.with_item( + tag: :a, + label: t(:button_archive), + href: project_archive_path(@project, status: '', name: @project.name), + content_arguments: { + data: { confirm: t('project.archive.are_you_sure', name: @project.name), method: :post, }, + test_selector: "project-settings--archive" + } + ) do |item| + item.with_leading_visual_icon(icon: 'lock') + end + end + if User.current.admin? + label = @project.templated ? 'remove_from_templates' : 'make_template' + menu.with_item( + tag: :a, + label: t("project.template.#{label}"), + href: project_templated_path(@project), + content_arguments: { + data: { method: @project.templated ? :delete : :post }, + test_selector: "project-settings--mark-template" + } + ) do |item| + item.with_leading_visual_icon(icon: @project.templated ? :"file-removed" : :"file-added") + end + + menu.with_item( + tag: :a, + scheme: :danger, + label: t(:button_delete), + href: confirm_destroy_project_path(@project), + content_arguments: { + data: { turbo: false }, + test_selector: "project-settings--delete" + } + ) do |item| + item.with_leading_visual_icon(icon: :trash) + end + end + end + end +%> diff --git a/app/components/projects/settings/index_page_header_component.rb b/app/components/projects/settings/index_page_header_component.rb new file mode 100644 index 000000000000..a57128ce4f05 --- /dev/null +++ b/app/components/projects/settings/index_page_header_component.rb @@ -0,0 +1,39 @@ +# 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 Projects::Settings::IndexPageHeaderComponent < ApplicationComponent + include OpPrimer::ComponentHelpers + + def initialize(project:) + super + + @project = project + end +end diff --git a/app/controllers/forums_controller.rb b/app/controllers/forums_controller.rb index 434b7686ffd9..414248f8161a 100644 --- a/app/controllers/forums_controller.rb +++ b/app/controllers/forums_controller.rb @@ -35,7 +35,6 @@ class ForumsController < ApplicationController accept_key_auth :show include SortHelper - include WatchersHelper include PaginationHelper def index diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index 22e7fb2743be..27f883a66b93 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -30,25 +30,75 @@ module WatchersHelper # Create a link to watch/unwatch object # # * :replace - a string or array of strings with css selectors that will be updated, whenever the watcher status is changed - def watcher_link(object, user, options = { replace: ".watcher_link", class: "watcher_link" }) - options = options.with_indifferent_access - raise ArgumentError, "Missing :replace option in options hash" if options["replace"].blank? + def watcher_link(object, user, options = {}) + options = { replace: ".watcher_link", class: "watcher_link" }.merge(options) - return "" unless user&.logged? && object.respond_to?(:watched_by?) + return "" unless valid_watcher_conditions?(object, user, options) watched = object.watched_by?(user) - html_options = options - path = send(:"#{(watched ? 'unwatch' : 'watch')}_path", object_type: object.class.to_s.underscore.pluralize, - object_id: object.id, - replace: options.delete("replace")) - html_options[:class] = html_options[:class].to_s + " button" + path = watcher_path(object, watched, options) + + html_options = prepare_html_options(watched, options) + + link_to_watcher_button(watched, path, html_options) + end + + def watcher_button_arguments(object, user) + return nil unless user&.logged? && object.respond_to?(:watched_by?) + + watched = object.watched_by?(user) + + path = send(:"#{(watched ? 'unwatch' : 'watch')}_path", + object_type: object.class.to_s.underscore.pluralize, + object_id: object.id) method = watched ? :delete : :post label = watched ? I18n.t(:button_unwatch) : I18n.t(:button_watch) - link_to(content_tag(:i, "", class: watched ? "button--icon icon-watched" : " button--icon icon-unwatched") + " " + - content_tag(:span, label, class: "button--text"), path, html_options.merge(method:)) + { + tag: :a, + href: path, + scheme: :default, + aria: { label: label }, + data: { + method: + }, + mobile_icon: watched ? "eye-closed" : "eye", + mobile_label: label + } + end + + private + + def valid_watcher_conditions?(object, user, options) + raise ArgumentError, "Missing :replace option in options hash" if options[:replace].blank? + + user&.logged? && object.respond_to?(:watched_by?) + end + + def watcher_path(object, watched, options) + action = watched ? "unwatch" : "watch" + send(:"#{action}_path", object_type: object.class.to_s.underscore.pluralize, object_id: object.id, replace: options[:replace]) + end + + def prepare_html_options(watched, options) + options.merge( + class: "#{options[:class]} button", + method: watched ? :delete : :post + ) + end + + def link_to_watcher_button(watched, path, html_options) + label = watched ? I18n.t(:button_unwatch) : I18n.t(:button_watch) + icon_class = watched ? "icon-watched" : "icon-unwatched" + + link_to( + content_tag(:i, "", class: "button--icon #{icon_class}") + + content_tag(:span, label, class: "button--text"), + path, + html_options + ) end end diff --git a/app/views/account/lost_password.html.erb b/app/views/account/lost_password.html.erb index 5f2859f265c4..1a5fced1d7c6 100644 --- a/app/views/account/lost_password.html.erb +++ b/app/views/account/lost_password.html.erb @@ -27,7 +27,15 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_password_lost) %> -<%= toolbar title: t(:label_password_lost) %> + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_password_lost) } + header.with_breadcrumbs([{ href: home_path, text: organization_name }, + t(:label_password_lost)]) + end +%> +
<%= styled_form_tag({action: "lost_password"}) do %>
diff --git a/app/views/account/password_recovery.html.erb b/app/views/account/password_recovery.html.erb index 47b1f76db29f..3e33e162f621 100644 --- a/app/views/account/password_recovery.html.erb +++ b/app/views/account/password_recovery.html.erb @@ -27,7 +27,15 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_password_lost) %> -<%= toolbar title: t(:label_password_lost) %> + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_password_lost) } + header.with_breadcrumbs([{ href: home_path, text: organization_name }, + t(:label_password_lost)]) + end +%> + <%= error_messages_for 'user' %> <%= styled_form_tag({token: @token.value}, autocomplete: 'off') do %>
diff --git a/app/views/admin/settings/project_custom_fields/edit.html.erb b/app/views/admin/settings/project_custom_fields/edit.html.erb index 9651e2fb7db1..4b28742f4731 100644 --- a/app/views/admin/settings/project_custom_fields/edit.html.erb +++ b/app/views/admin/settings/project_custom_fields/edit.html.erb @@ -28,7 +28,6 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t("settings.project_attributes.heading"), @custom_field.name %> -<% local_assigns[:additional_breadcrumb] = @custom_field.name %> <%= render(Settings::ProjectCustomFields::EditFormHeaderComponent.new( diff --git a/app/views/admin/settings/project_custom_fields/new.html.erb b/app/views/admin/settings/project_custom_fields/new.html.erb index f95642bc2048..0384cb23b787 100644 --- a/app/views/admin/settings/project_custom_fields/new.html.erb +++ b/app/views/admin/settings/project_custom_fields/new.html.erb @@ -28,7 +28,6 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_administration), t("settings.project_attributes.heading"), t('settings.project_attributes.new.heading') %> -<% local_assigns[:additional_breadcrumb] = t('settings.project_attributes.new.heading') %> <%= render(Settings::ProjectCustomFields::NewFormHeaderComponent.new) %> diff --git a/app/views/categories/destroy.html.erb b/app/views/categories/destroy.html.erb index ea75334d6a64..430fd0185378 100644 --- a/app/views/categories/destroy.html.erb +++ b/app/views/categories/destroy.html.erb @@ -26,7 +26,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: "#{Category.model_name.human} #{@category.name}" %> + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @category.name } + header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") }, + { href: project_settings_categories_path(@project.id), text: t(:label_work_package_category_plural) }, + @category.name]) + end %> + <%= form_tag({}, {method: :delete, class: 'form'}) do %>

<%= t(:text_work_package_category_destroy_question, count: @issue_count) %>

diff --git a/app/views/categories/edit.html.erb b/app/views/categories/edit.html.erb index cd0a4711ef27..ea7ef00d6d33 100644 --- a/app/views/categories/edit.html.erb +++ b/app/views/categories/edit.html.erb @@ -26,7 +26,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: Category.model_name.human %> + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @category.name } + header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") }, + { href: project_settings_categories_path(@project.id), text: t(:label_work_package_category_plural) }, + @category.name]) + end +%> + <%= labelled_tabular_form_for @category, as: :category do |f| %> <%= render partial: 'categories/form', locals: { f: f } %> <%= f.button t(:button_save), class: 'button -primary -with-icon icon-checkmark' %> diff --git a/app/views/categories/new.html.erb b/app/views/categories/new.html.erb index f93042e60ecc..bcb04b11371c 100644 --- a/app/views/categories/new.html.erb +++ b/app/views/categories/new.html.erb @@ -26,7 +26,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: t(:label_work_package_category_new) %> + +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_work_package_category_new) } + header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_settings_general_path(@project.id), text: I18n.t("label_project_settings") }, + { href: project_settings_categories_path(@project.id), text: t(:label_work_package_category_plural) }, + t(:label_work_package_category_new) + ]) + end %> + <%= labelled_tabular_form_for [@project, @category], as: :category do |f| %> <%= render partial: 'categories/form', locals: { f: f } %> <%= f.button t(:button_create), class: 'button -primary -with-icon icon-checkmark' %> diff --git a/app/views/colors/confirm_destroy.html.erb b/app/views/colors/confirm_destroy.html.erb index 878cb53b1785..a8bd724e9195 100644 --- a/app/views/colors/confirm_destroy.html.erb +++ b/app/views/colors/confirm_destroy.html.erb @@ -26,7 +26,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: @color.name %> + +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { @color.name } + header.with_breadcrumbs([{ href: admin_index_path, text: t(:label_administration) }, + { href: colors_path, text: t(:label_color_plural) }, + @color.name]) + end +%> + <%= labelled_tabular_form_for @color, url: color_url(@color), html: {method: 'delete'}, diff --git a/app/views/forums/edit.html.erb b/app/views/forums/edit.html.erb index 55eecad24ebf..db71092e464e 100644 --- a/app/views/forums/edit.html.erb +++ b/app/views/forums/edit.html.erb @@ -26,7 +26,13 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: Forum.model_name.human %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @forum.name } + header.with_breadcrumbs( [{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project.id), text: t(:label_forum_plural) }, + @forum.name + ]) end %> <%= labelled_tabular_form_for [@project, @forum] do |f| %> <%= render partial: 'form', locals: { f: f } %> diff --git a/app/views/forums/index.html.erb b/app/views/forums/index.html.erb index 73a2c166a9a7..b228b5921e34 100644 --- a/app/views/forums/index.html.erb +++ b/app/views/forums/index.html.erb @@ -27,20 +27,28 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_forum_plural) %> -<%= toolbar title: t(:label_forum_plural) do %> - <% if User.current.allowed_in_project?(:manage_forums, @project) %> -
  • - <%= link_to(new_project_forum_path(@project), - { aria: { label: t(:label_forum_new) }, - title: t(:label_forum_new), - class: 'button -primary' }) do %> - <%= op_icon('button--icon icon-add') %> - <%= t('activerecord.models.forum') %> - <% end %> -
  • - <% end %> -<% end %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_forum_plural) } + header.with_breadcrumbs( [{ href: project_overview_path(@project.id), text: @project.name }, + t(:label_forum_plural) + ]) end %> + +<% if User.current.allowed_in_project?(:manage_forums, @project) %> + <%= + render(Primer::OpenProject::SubHeader.new) do |subheader| + subheader.with_action_button(scheme: :primary, + aria: { label: t(:label_forum_new) }, + title: t(:label_forum_new), + tag: :a, + href: new_project_forum_path(@project)) do |button| + button.with_leading_visual_icon(icon: :plus) + t('activerecord.models.forum') + end + end + %> +<% end %> <% if @forums.empty? %> <%= no_results_box(action_url: new_project_forum_path(@project)) %> <% else %> diff --git a/app/views/forums/new.html.erb b/app/views/forums/new.html.erb index 47c22c0fd526..97f41c0d1be0 100644 --- a/app/views/forums/new.html.erb +++ b/app/views/forums/new.html.erb @@ -27,8 +27,14 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: t(:label_forum_new) %> - +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_forum_new) } + header.with_breadcrumbs( [{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project.id), text: t(:label_forum_plural) }, + t(:label_forum_new) + ]) + end %> <%= labelled_tabular_form_for [@project, @forum] do |f| %> <%= render partial: 'form', locals: {f: f} %> <%= f.button t(:button_create), class: 'button -primary -with-icon icon-checkmark' %> diff --git a/app/views/forums/show.html.erb b/app/views/forums/show.html.erb index 576da3808a90..0d7e4a48b977 100644 --- a/app/views/forums/show.html.erb +++ b/app/views/forums/show.html.erb @@ -49,24 +49,39 @@ See COPYRIGHT and LICENSE files for more details. <% end %>
    -<%= toolbar title: @forum.name, subtitle: format_text(@forum.description) do %> - <% if authorize_for(:messages, :new) %> -
  • - <%= link_to({ controller: '/messages', action: 'new', forum_id: @forum }, - { class: 'add-message-button button -primary', - aria: { label: t(:label_message_new) }, - title: t(:label_message_new) }) do %> - <%= op_icon('button--icon icon-add') %> - <%= t(:label_message) %> - <% end %> - <% csp_onclick('jQuery("#add-message").show(); jQuery("#message_subject").focus();', '.add-message-button') %> -
  • - <% end %> - <% unless User.current.anonymous? %> -
  • - <%= watcher_link(@forum, User.current) %> -
  • - <% end %> + +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { @forum.name } + header.with_description { @forum.description } + header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project), text: t(:label_forum_plural) }, + @forum.name]) + unless User.current.anonymous? + watcher_button_args = watcher_button_arguments(@forum, User.current) + header.with_action_button(**watcher_button_args) do |button| + button.with_leading_visual_icon(icon: watcher_button_args[:mobile_icon]) + watcher_button_args[:mobile_label] + end + end + end +%> +<% if authorize_for(:messages, :new) %> + <%= + render(Primer::OpenProject::SubHeader.new) do |subheader| + if authorize_for(:messages, :new) + subheader.with_action_button(scheme: :primary, + aria: { label: t(:label_message_new) }, + title: t(:label_message_new), + tag: :a, + class: 'add-message-button', + href: url_for({controller: '/messages', action: 'new', forum_id: @forum})) do |button| + button.with_leading_visual_icon(icon: :plus) + t(:label_message) + end + end + end + %> <% end %> <% if @topics.any? %> diff --git a/app/views/messages/edit.html.erb b/app/views/messages/edit.html.erb index 503d85c27e51..f906ee6ed300 100644 --- a/app/views/messages/edit.html.erb +++ b/app/views/messages/edit.html.erb @@ -27,7 +27,14 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -

    <%= link_to h(@forum.name), controller: '/forums', action: 'show', project_id: @project, id: @forum %> » <%= h @message.subject %>

    +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @message.subject } + header.with_breadcrumbs( [{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project), text: t(:label_forum_plural) }, + { href: project_forum_path(@project, @forum), text: @forum.name }, + @message.subject]) + end %> <%= labelled_tabular_form_for @message, url: topic_path(@message), diff --git a/app/views/messages/new.html.erb b/app/views/messages/new.html.erb index 58fed5b40082..3b6e0879f527 100644 --- a/app/views/messages/new.html.erb +++ b/app/views/messages/new.html.erb @@ -27,8 +27,15 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -

    <%= link_to h(@forum.name), controller: '/forums', action: 'show', project_id: @project, id: @forum %> » <%= t(:label_message_new) %>

    - +<%= + render(Primer::OpenProject::PageHeader.new) do |header| + header.with_title { t(:label_message_new) } + header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_forums_path(@project), text: t(:label_forum_plural) }, + { href: url_for(controller: '/forums', action: 'show', project_id: @project, id: @forum), text: @forum.name }, + t(:label_message_new)]) + end +%> <%= labelled_tabular_form_for @message, url: forum_topics_path(@forum), html: { diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb index f294bd74e145..5ec9cbdda7d5 100644 --- a/app/views/messages/show.html.erb +++ b/app/views/messages/show.html.erb @@ -27,48 +27,12 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<% breadcrumb_paths( - link_to(t(:label_forum_plural), project_forums_path(@project)), - link_to(h(@forum.name), project_forum_path(@project, @forum))) -%> +<%= render Messages::ShowPageHeaderComponent.new(topic: @topic, message: @message, forum: @forum, project:@project) %> <% content_controller 'forum-messages', dynamic: true %> <% title avatar(@topic.author) + h(@topic.subject) %> -<%= toolbar title: title do %> -
  • - <%= watcher_link(@topic, User.current) %> -
  • -
  • - <% if !@topic.locked? && authorize_for('messages', 'reply') %> - <%= link_to( - { action: 'quote', id: @topic }, - data: { 'action': 'forum-messages#quote' }, - class: 'boards--quote-button button' - ) do %> - <%= op_icon('button--icon icon-quote') %> - <%= t(:button_quote) %> - <% end %> - <% end %> -
  • -
  • - <% if @message.editable_by?(User.current) %> - <%= link_to(edit_topic_path(@topic), accesskey: accesskey(:edit), class: 'button') do %> - <%= op_icon('button--icon icon-edit') %> - <%= t(:button_edit) %> - <% end %> - <% end %> -
  • -
  • - <% if @message.destroyable_by?(User.current) %> - <%= link_to(topic_path(@topic), method: :delete, data: { confirm: t(:text_are_you_sure) }, class: 'button') do %> - <%= op_icon('button--icon icon-delete') %> - <%= t(:button_delete) %> - <% end %> - <% end %> -
  • -<% end %>

    <%= authoring @topic.created_at, @topic.author %>

    diff --git a/app/views/news/edit.html.erb b/app/views/news/edit.html.erb index dd8cadc3a921..0509feb45196 100644 --- a/app/views/news/edit.html.erb +++ b/app/views/news/edit.html.erb @@ -28,7 +28,15 @@ See COPYRIGHT and LICENSE files for more details. ++#%> <% html_title t(:label_news_edit) %> -<%= toolbar title: News.model_name.human %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { @news.title } + header.with_breadcrumbs([*([ href: home_path, text: organization_name ] unless @project), + *([ href: project_overview_path(@project.id), text: @project.name ] if @project), + *([ href: project_news_index_path(@project.id), text: t(:label_news_plural) ] if @project), + @news.title]) + end +%> <%= labelled_tabular_form_for @news, html: { id: 'news-form' } do |f| %> <%= render partial: 'form', locals: { f: f } %> diff --git a/app/views/news/new.html.erb b/app/views/news/new.html.erb index f031848d2b34..383750570f35 100644 --- a/app/views/news/new.html.erb +++ b/app/views/news/new.html.erb @@ -26,10 +26,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. See COPYRIGHT and LICENSE files for more details. ++#%> - <% html_title t(:label_news_new) %> -<%= toolbar title: t(:label_news_new) %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { t(:label_news_new) } + header.with_breadcrumbs([{ href: project_overview_path(@project.id), text: @project.name }, + { href: project_news_index_path(@project), text: t(:label_news_plural)}, + t(:label_news_new)]) + end +%> <%= labelled_tabular_form_for [@project, @news], html: { id: 'news-form' } do |f| %> <%= render partial: 'news/form', locals: { f: f } %> diff --git a/app/views/news/show.html.erb b/app/views/news/show.html.erb index 6e6820b3def3..317fc5b8a42e 100644 --- a/app/views/news/show.html.erb +++ b/app/views/news/show.html.erb @@ -27,33 +27,46 @@ See COPYRIGHT and LICENSE files for more details. ++#%> -<%= toolbar title: "#{avatar(@news.author)} #{h @news.title}".html_safe do %> - <% if User.current.allowed_in_project?(:manage_news, @project) %> -
  • - <%= link_to(edit_news_path(@news), - accesskey: accesskey(:edit), - class: 'button edit-news-button') do %> - <%= op_icon('button--icon icon-edit') %> - <%= t(:button_edit) %> - <% end %> - <% csp_onclick('jQuery("#edit-news").show()', '.edit-news-button') %> -
  • - <% end %> -
  • - <%= watcher_link(@news, User.current) %> -
  • - <% if User.current.allowed_in_project?(:manage_news, @project) %> -
  • - <%= link_to(news_path(@news), - data: { confirm: t(:text_are_you_sure) }, - method: :delete, - class: 'button') do %> - <%= op_icon('button--icon icon-delete') %> - <%= t(:button_delete) %> - <% end %> -
  • - <% end %> -<% end %> +<%= + render Primer::OpenProject::PageHeader.new do |header| + header.with_title { "#{avatar(@news.author)} #{h @news.title}".html_safe } + header.with_breadcrumbs([*([ href: home_path, text: organization_name ] unless @project), + *([ href: project_overview_path(@project.id), text: @project.name ] if @project), + *([ href: project_news_index_path(@project.id), text: t(:label_news_plural) ] if @project), + @news.title]) + if User.current.allowed_in_project?(:manage_news, @project) + header.with_action_button(tag: :a, + mobile_icon: :pencil, + mobile_label: t(:button_edit), + size: :medium, + href: edit_news_path(@news), + aria: { label: I18n.t(:button_edit) }, + title: I18n.t(:button_edit)) do |button| + csp_onclick('jQuery("#edit-news").show()', '.edit-news-button') + button.with_leading_visual_icon(icon: :pencil) + t(:button_edit) + end + end + watcher_button_args = watcher_button_arguments(@news, User.current) + header.with_action_button(**watcher_button_args) do |button| + button.with_leading_visual_icon(icon: watcher_button_args[:mobile_icon]) + watcher_button_args[:mobile_label] + end + if User.current.allowed_in_project?(:manage_news, @project) + header.with_action_button(scheme: :danger, + tag: :a, + href: news_path(@news), + mobile_icon: :trash, + mobile_label: I18n.t("button_delete"), + data: { confirm: t(:text_are_you_sure), method: :delete, }, + aria: { label: I18n.t("button_delete") }, + ) do |button| + button.with_leading_visual_icon(icon: :trash) + I18n.t("button_delete") + end + end + end +%> <% if authorize_for('news', 'edit') %>